1 //! The "parse-tree" is what is produced by the parser. We use it do
2 //! some pre-expansion and so forth before creating the proper AST.
3
4 use grammar::consts::{INPUT_LIFETIME, LALR, RECURSIVE_ASCENT, TABLE_DRIVEN, TEST_ALL};
5 use grammar::pattern::Pattern;
6 use grammar::repr::{self as r, NominalTypeRepr, TypeRepr};
7 use lexer::dfa::DFA;
8 use message::builder::InlineBuilder;
9 use message::Content;
10 use std::fmt::{Debug, Display, Error, Formatter};
11 use string_cache::DefaultAtom as Atom;
12 use tls::Tls;
13 use util::Sep;
14
15 #[derive(Clone, Debug, PartialEq, Eq)]
16 pub struct Grammar {
17 // see field `prefix` in `grammar::repr::Grammar`
18 pub prefix: String,
19 pub span: Span,
20 pub type_parameters: Vec<TypeParameter>,
21 pub parameters: Vec<Parameter>,
22 pub where_clauses: Vec<WhereClause<TypeRef>>,
23 pub items: Vec<GrammarItem>,
24 pub annotations: Vec<Annotation>,
25 pub module_attributes: Vec<String>,
26 }
27
28 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
29 pub struct Span(pub usize, pub usize);
30
31 impl Into<Box<Content>> for Span {
into(self) -> Box<Content>32 fn into(self) -> Box<Content> {
33 let file_text = Tls::file_text();
34 let string = file_text.span_str(self);
35
36 // Insert an Adjacent block to prevent wrapping inside this
37 // string:
38 InlineBuilder::new()
39 .begin_adjacent()
40 .text(string)
41 .end()
42 .end()
43 }
44 }
45
46 #[derive(Clone, Debug, PartialEq, Eq)]
47 pub enum GrammarItem {
48 MatchToken(MatchToken),
49 ExternToken(ExternToken),
50 InternToken(InternToken),
51 Nonterminal(NonterminalData),
52 Use(String),
53 }
54
55 #[derive(Clone, Debug, PartialEq, Eq)]
56 pub struct MatchToken {
57 pub contents: Vec<MatchContents>,
58 pub span: Span,
59 }
60
61 impl MatchToken {
new(contents: MatchContents, span: Span) -> MatchToken62 pub fn new(contents: MatchContents, span: Span) -> MatchToken {
63 MatchToken {
64 contents: vec![contents],
65 span: span,
66 }
67 }
68
69 // Not really sure if this is the best way to do it
add(self, contents: MatchContents) -> MatchToken70 pub fn add(self, contents: MatchContents) -> MatchToken {
71 let mut new_contents = self.contents.clone();
72 new_contents.push(contents);
73 MatchToken {
74 contents: new_contents,
75 span: self.span,
76 }
77 }
78 }
79
80 #[derive(Clone, Debug, PartialEq, Eq)]
81 pub struct MatchContents {
82 pub items: Vec<MatchItem>,
83 }
84
85 // FIXME: Validate that MatchSymbol is actually a TerminalString::Literal
86 // and that MatchMapping is an Id or String
87 #[derive(Clone, Debug, PartialEq, Eq)]
88 pub enum MatchItem {
89 CatchAll(Span),
90 Unmapped(MatchSymbol, Span),
91 Mapped(MatchSymbol, MatchMapping, Span),
92 }
93
94 impl MatchItem {
is_catch_all(&self) -> bool95 pub fn is_catch_all(&self) -> bool {
96 match *self {
97 MatchItem::CatchAll(_) => true,
98 _ => false,
99 }
100 }
101
span(&self) -> Span102 pub fn span(&self) -> Span {
103 match *self {
104 MatchItem::CatchAll(span) => span,
105 MatchItem::Unmapped(_, span) => span,
106 MatchItem::Mapped(_, _, span) => span,
107 }
108 }
109 }
110
111 pub type MatchSymbol = TerminalLiteral;
112 pub type MatchMapping = TerminalString;
113
114 /// Intern tokens are not typed by the user: they are synthesized in
115 /// the absence of an "extern" declaration with information about the
116 /// string literals etc that appear in the grammar.
117 #[derive(Clone, Debug, PartialEq, Eq)]
118 pub struct InternToken {
119 /// Set of `r"foo"` and `"foo"` literals extracted from the
120 /// grammar. Sorted by order of increasing precedence.
121 pub match_entries: Vec<MatchEntry>,
122 pub dfa: DFA,
123 }
124
125 /// In `token_check`, as we prepare to generate a tokenizer, we
126 /// combine any `match` declaration the user may have given with the
127 /// set of literals (e.g. `"foo"` or `r"[a-z]"`) that appear elsewhere
128 /// in their in the grammar to produce a series of `MatchEntry`. Each
129 /// `MatchEntry` roughly corresponds to one line in a `match` declaration.
130 ///
131 /// So e.g. if you had
132 ///
133 /// ```
134 /// match {
135 /// r"(?i)BEGIN" => "BEGIN",
136 /// "+" => "+",
137 /// } else {
138 /// _
139 /// }
140 ///
141 /// ID = r"[a-zA-Z]+"
142 /// ```
143 ///
144 /// This would correspond to three match entries:
145 /// - `MatchEntry { match_literal: r"(?i)BEGIN", user_name: "BEGIN", precedence: 2 }`
146 /// - `MatchEntry { match_literal: "+", user_name: "+", precedence: 3 }`
147 /// - `MatchEntry { match_literal: "r[a-zA-Z]+"", user_name: r"[a-zA-Z]+", precedence: 0 }`
148 ///
149 /// A couple of things to note:
150 ///
151 /// - Literals appearing in the grammar are converting into an "identity" mapping
152 /// - Each match group G is combined with the implicit priority IP of 1 for literals and 0 for
153 /// regex to yield the final precedence; the formula is `G*2 + IP`.
154 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
155 pub struct MatchEntry {
156 /// The precedence of this match entry.
157 ///
158 /// NB: This field must go first, so that `PartialOrd` sorts by precedence first!
159 pub precedence: usize,
160 pub match_literal: TerminalLiteral,
161 pub user_name: TerminalString,
162 }
163
164 #[derive(Clone, Debug, PartialEq, Eq)]
165 pub struct ExternToken {
166 pub span: Span,
167 pub associated_types: Vec<AssociatedType>,
168 pub enum_token: Option<EnumToken>,
169 }
170
171 #[derive(Clone, Debug, PartialEq, Eq)]
172 pub struct AssociatedType {
173 pub type_span: Span,
174 pub type_name: Atom,
175 pub type_ref: TypeRef,
176 }
177
178 #[derive(Clone, Debug, PartialEq, Eq)]
179 pub struct EnumToken {
180 pub type_name: TypeRef,
181 pub type_span: Span,
182 pub conversions: Vec<Conversion>,
183 }
184
185 #[derive(Clone, Debug, PartialEq, Eq)]
186 pub struct Conversion {
187 pub span: Span,
188 pub from: TerminalString,
189 pub to: Pattern<TypeRef>,
190 }
191
192 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
193 pub struct Path {
194 pub absolute: bool,
195 pub ids: Vec<Atom>,
196 }
197
198 #[derive(Clone, Debug, PartialEq, Eq)]
199 pub enum TypeRef {
200 // (T1, T2)
201 Tuple(Vec<TypeRef>),
202
203 // Foo<'a, 'b, T1, T2>, Foo::Bar, etc
204 Nominal {
205 path: Path,
206 types: Vec<TypeRef>,
207 },
208
209 Ref {
210 lifetime: Option<Lifetime>,
211 mutable: bool,
212 referent: Box<TypeRef>,
213 },
214
215 // 'x ==> only should appear within nominal types, but what do we care
216 Lifetime(Lifetime),
217
218 // Foo or Bar ==> treated specially since macros may care
219 Id(Atom),
220
221 // <N> ==> type of a nonterminal, emitted by macro expansion
222 OfSymbol(SymbolKind),
223 }
224
225 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
226 pub enum WhereClause<T> {
227 // 'a: 'b + 'c
228 Lifetime {
229 lifetime: Lifetime,
230 bounds: Vec<Lifetime>,
231 },
232 // where for<'a> &'a T: Debug + Into<usize>
233 Type {
234 forall: Vec<TypeParameter>,
235 ty: T,
236 bounds: Vec<TypeBound<T>>,
237 },
238 }
239
240 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
241 pub enum TypeBound<T> {
242 // The `'a` in `T: 'a`.
243 Lifetime(Lifetime),
244
245 // `for<'a> FnMut(&'a usize)`
246 Fn {
247 forall: Vec<TypeParameter>,
248 path: Path,
249 parameters: Vec<T>,
250 ret: Option<T>,
251 },
252
253 // `some::Trait` or `some::Trait<Param, ...>` or `some::Trait<Item = Assoc>`
254 // or `for<'a> Trait<'a, T>`
255 Trait {
256 forall: Vec<TypeParameter>,
257 path: Path,
258 parameters: Vec<TypeBoundParameter<T>>,
259 },
260 }
261
262 impl<T> TypeBound<T> {
map<F, U>(&self, mut f: F) -> TypeBound<U> where F: FnMut(&T) -> U,263 pub fn map<F, U>(&self, mut f: F) -> TypeBound<U>
264 where
265 F: FnMut(&T) -> U,
266 {
267 match *self {
268 TypeBound::Lifetime(ref l) => TypeBound::Lifetime(l.clone()),
269 TypeBound::Fn {
270 ref forall,
271 ref path,
272 ref parameters,
273 ref ret,
274 } => TypeBound::Fn {
275 forall: forall.clone(),
276 path: path.clone(),
277 parameters: parameters.iter().map(&mut f).collect(),
278 ret: ret.as_ref().map(f),
279 },
280 TypeBound::Trait {
281 ref forall,
282 ref path,
283 ref parameters,
284 } => TypeBound::Trait {
285 forall: forall.clone(),
286 path: path.clone(),
287 parameters: parameters.iter().map(|p| p.map(&mut f)).collect(),
288 },
289 }
290 }
291 }
292
293 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
294 pub enum TypeBoundParameter<T> {
295 // 'a
296 Lifetime(Lifetime),
297 // `T` or `'a`
298 TypeParameter(T),
299 // `Item = T`
300 Associated(Atom, T),
301 }
302
303 impl<T> TypeBoundParameter<T> {
map<F, U>(&self, mut f: F) -> TypeBoundParameter<U> where F: FnMut(&T) -> U,304 pub fn map<F, U>(&self, mut f: F) -> TypeBoundParameter<U>
305 where
306 F: FnMut(&T) -> U,
307 {
308 match *self {
309 TypeBoundParameter::Lifetime(ref l) => TypeBoundParameter::Lifetime(l.clone()),
310 TypeBoundParameter::TypeParameter(ref t) => TypeBoundParameter::TypeParameter(f(t)),
311 TypeBoundParameter::Associated(ref id, ref t) => {
312 TypeBoundParameter::Associated(id.clone(), f(t))
313 }
314 }
315 }
316 }
317
318 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
319 pub enum TypeParameter {
320 Lifetime(Lifetime),
321 Id(Atom),
322 }
323
324 #[derive(Clone, Debug, PartialEq, Eq)]
325 pub struct Parameter {
326 pub name: Atom,
327 pub ty: TypeRef,
328 }
329
330 #[derive(Clone, Debug, PartialEq, Eq)]
331 pub enum Visibility {
332 Pub(Option<Path>),
333 Priv,
334 }
335
336 impl Visibility {
is_pub(&self) -> bool337 pub fn is_pub(&self) -> bool {
338 match *self {
339 Visibility::Pub(_) => true,
340 Visibility::Priv => false,
341 }
342 }
343 }
344
345 #[derive(Clone, Debug, PartialEq, Eq)]
346 pub struct NonterminalData {
347 pub visibility: Visibility,
348 pub name: NonterminalString,
349 pub annotations: Vec<Annotation>,
350 pub span: Span,
351 pub args: Vec<NonterminalString>, // macro arguments
352 pub type_decl: Option<TypeRef>,
353 pub alternatives: Vec<Alternative>,
354 }
355
356 #[derive(Clone, Debug, PartialEq, Eq)]
357 pub struct Annotation {
358 pub id_span: Span,
359 pub id: Atom,
360 pub arg: Option<(Atom, String)>,
361 }
362
363 #[derive(Clone, Debug, PartialEq, Eq)]
364 pub struct Alternative {
365 pub span: Span,
366
367 pub expr: ExprSymbol,
368
369 // if C, only legal in macros
370 pub condition: Option<Condition>,
371
372 // => { code }
373 pub action: Option<ActionKind>,
374 }
375
376 #[derive(Clone, Debug, PartialEq, Eq)]
377 pub enum ActionKind {
378 User(String),
379 Fallible(String),
380 Lookahead,
381 Lookbehind,
382 }
383
384 #[derive(Clone, Debug, PartialEq, Eq)]
385 pub struct Condition {
386 pub span: Span,
387 pub lhs: NonterminalString, // X
388 pub rhs: Atom, // "Foo"
389 pub op: ConditionOp,
390 }
391
392 #[derive(Clone, Debug, PartialEq, Eq)]
393 pub enum ConditionOp {
394 // X == "Foo", equality
395 Equals,
396
397 // X != "Foo", inequality
398 NotEquals,
399
400 // X ~~ "Foo", regexp match
401 Match,
402
403 // X !~ "Foo", regexp non-match
404 NotMatch,
405 }
406
407 #[derive(Clone, Debug, PartialEq, Eq)]
408 pub struct Symbol {
409 pub span: Span,
410 pub kind: SymbolKind,
411 }
412
413 #[derive(Clone, Debug, PartialEq, Eq)]
414 pub enum SymbolKind {
415 // (X Y)
416 Expr(ExprSymbol),
417
418 // foo, before name resolution
419 AmbiguousId(Atom),
420
421 // "foo" and foo (after name resolution)
422 Terminal(TerminalString),
423
424 // foo, after name resolution
425 Nonterminal(NonterminalString),
426
427 // foo<..>
428 Macro(MacroSymbol),
429
430 // X+, X?, X*
431 Repeat(Box<RepeatSymbol>),
432
433 // <X>
434 Choose(Box<Symbol>),
435
436 // x:X
437 Name(Atom, Box<Symbol>),
438
439 // @L
440 Lookahead,
441
442 // @R
443 Lookbehind,
444
445 Error,
446 }
447
448 #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
449 pub enum TerminalString {
450 Literal(TerminalLiteral),
451 Bare(Atom),
452 Error,
453 }
454
455 impl TerminalString {
as_literal(&self) -> Option<TerminalLiteral>456 pub fn as_literal(&self) -> Option<TerminalLiteral> {
457 match *self {
458 TerminalString::Literal(ref l) => Some(l.clone()),
459 _ => None,
460 }
461 }
462
display_len(&self) -> usize463 pub fn display_len(&self) -> usize {
464 match *self {
465 TerminalString::Literal(ref x) => x.display_len(),
466 TerminalString::Bare(ref x) => x.len(),
467 TerminalString::Error => "error".len(),
468 }
469 }
470 }
471
472 #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
473 pub enum TerminalLiteral {
474 Quoted(Atom),
475 Regex(Atom),
476 }
477
478 impl TerminalLiteral {
479 /// The *base precedence* is the precedence within a `match { }`
480 /// block level. It indicates that quoted things like `"foo"` get
481 /// precedence over regex matches.
base_precedence(&self) -> usize482 pub fn base_precedence(&self) -> usize {
483 match *self {
484 TerminalLiteral::Quoted(_) => 1,
485 TerminalLiteral::Regex(_) => 0,
486 }
487 }
488
display_len(&self) -> usize489 pub fn display_len(&self) -> usize {
490 match *self {
491 TerminalLiteral::Quoted(ref x) => x.len(),
492 TerminalLiteral::Regex(ref x) => x.len() + "####r".len(),
493 }
494 }
495 }
496
497 #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
498 pub struct NonterminalString(pub Atom);
499
500 impl NonterminalString {
len(&self) -> usize501 pub fn len(&self) -> usize {
502 self.0.len()
503 }
504 }
505
506 impl Into<Box<Content>> for NonterminalString {
into(self) -> Box<Content>507 fn into(self) -> Box<Content> {
508 let session = Tls::session();
509
510 InlineBuilder::new()
511 .text(self)
512 .styled(session.nonterminal_symbol)
513 .end()
514 }
515 }
516
517 #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
518 pub struct Lifetime(pub Atom);
519
520 impl Lifetime {
anonymous() -> Self521 pub fn anonymous() -> Self {
522 Lifetime(Atom::from("'_"))
523 }
524
is_anonymous(&self) -> bool525 pub fn is_anonymous(&self) -> bool {
526 *self == Self::anonymous()
527 }
528
statik() -> Self529 pub fn statik() -> Self {
530 Lifetime(Atom::from("'static"))
531 }
532
input() -> Self533 pub fn input() -> Self {
534 Lifetime(Atom::from(INPUT_LIFETIME))
535 }
536
len(&self) -> usize537 pub fn len(&self) -> usize {
538 self.0.len()
539 }
540 }
541
542 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
543 pub enum RepeatOp {
544 Star,
545 Plus,
546 Question,
547 }
548
549 #[derive(Clone, Debug, PartialEq, Eq)]
550 pub struct RepeatSymbol {
551 pub op: RepeatOp,
552 pub symbol: Symbol,
553 }
554
555 #[derive(Clone, Debug, PartialEq, Eq)]
556 pub struct ExprSymbol {
557 pub symbols: Vec<Symbol>,
558 }
559
560 #[derive(Clone, Debug, PartialEq, Eq)]
561 pub struct MacroSymbol {
562 pub name: NonterminalString,
563 pub args: Vec<Symbol>,
564 }
565
566 impl TerminalString {
quoted(i: Atom) -> TerminalString567 pub fn quoted(i: Atom) -> TerminalString {
568 TerminalString::Literal(TerminalLiteral::Quoted(i))
569 }
570
regex(i: Atom) -> TerminalString571 pub fn regex(i: Atom) -> TerminalString {
572 TerminalString::Literal(TerminalLiteral::Regex(i))
573 }
574 }
575
576 impl Into<Box<Content>> for TerminalString {
into(self) -> Box<Content>577 fn into(self) -> Box<Content> {
578 let session = Tls::session();
579 InlineBuilder::new()
580 .text(self)
581 .styled(session.terminal_symbol)
582 .end()
583 }
584 }
585
586 impl Grammar {
extern_token(&self) -> Option<&ExternToken>587 pub fn extern_token(&self) -> Option<&ExternToken> {
588 self.items.iter().flat_map(|i| i.as_extern_token()).next()
589 }
590
enum_token(&self) -> Option<&EnumToken>591 pub fn enum_token(&self) -> Option<&EnumToken> {
592 self.items
593 .iter()
594 .flat_map(|i| i.as_extern_token())
595 .flat_map(|et| et.enum_token.as_ref())
596 .next()
597 }
598
intern_token(&self) -> Option<&InternToken>599 pub fn intern_token(&self) -> Option<&InternToken> {
600 self.items.iter().flat_map(|i| i.as_intern_token()).next()
601 }
602
match_token(&self) -> Option<&MatchToken>603 pub fn match_token(&self) -> Option<&MatchToken> {
604 self.items.iter().flat_map(|i| i.as_match_token()).next()
605 }
606 }
607
608 impl GrammarItem {
is_macro_def(&self) -> bool609 pub fn is_macro_def(&self) -> bool {
610 match *self {
611 GrammarItem::Nonterminal(ref d) => d.is_macro_def(),
612 _ => false,
613 }
614 }
615
as_nonterminal(&self) -> Option<&NonterminalData>616 pub fn as_nonterminal(&self) -> Option<&NonterminalData> {
617 match *self {
618 GrammarItem::Nonterminal(ref d) => Some(d),
619 GrammarItem::Use(..) => None,
620 GrammarItem::MatchToken(..) => None,
621 GrammarItem::ExternToken(..) => None,
622 GrammarItem::InternToken(..) => None,
623 }
624 }
625
as_match_token(&self) -> Option<&MatchToken>626 pub fn as_match_token(&self) -> Option<&MatchToken> {
627 match *self {
628 GrammarItem::Nonterminal(..) => None,
629 GrammarItem::Use(..) => None,
630 GrammarItem::MatchToken(ref d) => Some(d),
631 GrammarItem::ExternToken(..) => None,
632 GrammarItem::InternToken(..) => None,
633 }
634 }
635
as_extern_token(&self) -> Option<&ExternToken>636 pub fn as_extern_token(&self) -> Option<&ExternToken> {
637 match *self {
638 GrammarItem::Nonterminal(..) => None,
639 GrammarItem::Use(..) => None,
640 GrammarItem::MatchToken(..) => None,
641 GrammarItem::ExternToken(ref d) => Some(d),
642 GrammarItem::InternToken(..) => None,
643 }
644 }
645
as_intern_token(&self) -> Option<&InternToken>646 pub fn as_intern_token(&self) -> Option<&InternToken> {
647 match *self {
648 GrammarItem::Nonterminal(..) => None,
649 GrammarItem::Use(..) => None,
650 GrammarItem::MatchToken(..) => None,
651 GrammarItem::ExternToken(..) => None,
652 GrammarItem::InternToken(ref d) => Some(d),
653 }
654 }
655 }
656
657 impl NonterminalData {
is_macro_def(&self) -> bool658 pub fn is_macro_def(&self) -> bool {
659 !self.args.is_empty()
660 }
661 }
662
663 impl Symbol {
new(span: Span, kind: SymbolKind) -> Symbol664 pub fn new(span: Span, kind: SymbolKind) -> Symbol {
665 Symbol {
666 span: span,
667 kind: kind,
668 }
669 }
670
canonical_form(&self) -> String671 pub fn canonical_form(&self) -> String {
672 format!("{}", self)
673 }
674 }
675
676 impl Display for Visibility {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>677 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
678 match *self {
679 Visibility::Pub(Some(ref path)) => write!(fmt, "pub({}) ", path),
680 Visibility::Pub(None) => write!(fmt, "pub "),
681 Visibility::Priv => Ok(()),
682 }
683 }
684 }
685
686 impl<T: Display> Display for WhereClause<T> {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>687 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
688 match *self {
689 WhereClause::Lifetime {
690 ref lifetime,
691 ref bounds,
692 } => {
693 write!(fmt, "{}:", lifetime)?;
694 for (i, b) in bounds.iter().enumerate() {
695 if i != 0 {
696 write!(fmt, " +")?;
697 }
698 write!(fmt, " {}", b)?;
699 }
700 Ok(())
701 }
702 WhereClause::Type {
703 ref forall,
704 ref ty,
705 ref bounds,
706 } => {
707 if !forall.is_empty() {
708 write!(fmt, "for<")?;
709 for (i, l) in forall.iter().enumerate() {
710 if i != 0 {
711 write!(fmt, ", ")?;
712 }
713 write!(fmt, "{}", l)?;
714 }
715 write!(fmt, "> ")?;
716 }
717
718 write!(fmt, "{}: ", ty)?;
719 for (i, b) in bounds.iter().enumerate() {
720 if i != 0 {
721 write!(fmt, " +")?;
722 }
723 write!(fmt, " {}", b)?;
724 }
725 Ok(())
726 }
727 }
728 }
729 }
730
731 impl<T: Display> Display for TypeBound<T> {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>732 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
733 match *self {
734 TypeBound::Lifetime(ref l) => write!(fmt, "{}", l),
735 TypeBound::Fn {
736 ref forall,
737 ref path,
738 ref parameters,
739 ref ret,
740 } => {
741 if !forall.is_empty() {
742 write!(fmt, "for<")?;
743 for (i, l) in forall.iter().enumerate() {
744 if i != 0 {
745 write!(fmt, ", ")?;
746 }
747 write!(fmt, "{}", l)?;
748 }
749 write!(fmt, "> ")?;
750 }
751
752 write!(fmt, "{}(", path)?;
753 for (i, p) in parameters.iter().enumerate() {
754 if i != 0 {
755 write!(fmt, ", ")?;
756 }
757 write!(fmt, "{}", p)?;
758 }
759 write!(fmt, ")")?;
760
761 if let Some(ref ret) = *ret {
762 write!(fmt, " -> {}", ret)?;
763 }
764
765 Ok(())
766 }
767 TypeBound::Trait {
768 ref forall,
769 ref path,
770 ref parameters,
771 } => {
772 if !forall.is_empty() {
773 write!(fmt, "for<")?;
774 for (i, l) in forall.iter().enumerate() {
775 if i != 0 {
776 write!(fmt, ", ")?;
777 }
778 write!(fmt, "{}", l)?;
779 }
780 write!(fmt, "> ")?;
781 }
782
783 write!(fmt, "{}", path)?;
784 if parameters.is_empty() {
785 return Ok(());
786 }
787
788 write!(fmt, "<")?;
789 for (i, p) in parameters.iter().enumerate() {
790 if i != 0 {
791 write!(fmt, ", ")?;
792 }
793 write!(fmt, "{}", p)?;
794 }
795 write!(fmt, ">")
796 }
797 }
798 }
799 }
800
801 impl<T: Display> Display for TypeBoundParameter<T> {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>802 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
803 match *self {
804 TypeBoundParameter::Lifetime(ref l) => write!(fmt, "{}", l),
805 TypeBoundParameter::TypeParameter(ref t) => write!(fmt, "{}", t),
806 TypeBoundParameter::Associated(ref id, ref t) => write!(fmt, "{} = {}", id, t),
807 }
808 }
809 }
810
811 impl Display for TerminalString {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>812 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
813 match *self {
814 TerminalString::Literal(ref s) => write!(fmt, "{}", s),
815 TerminalString::Bare(ref s) => write!(fmt, "{}", s),
816 TerminalString::Error => write!(fmt, "error"),
817 }
818 }
819 }
820
821 impl Debug for TerminalString {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>822 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
823 Display::fmt(self, fmt)
824 }
825 }
826
827 impl Display for Lifetime {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>828 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
829 Display::fmt(&self.0, fmt)
830 }
831 }
832
833 impl Debug for Lifetime {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>834 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
835 Display::fmt(self, fmt)
836 }
837 }
838
839 impl Display for TerminalLiteral {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>840 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
841 match *self {
842 TerminalLiteral::Quoted(ref s) => write!(fmt, "{:?}", s.as_ref()), // the Debug impl adds the `"` and escaping
843 TerminalLiteral::Regex(ref s) => write!(fmt, "r#{:?}#", s.as_ref()), // FIXME -- need to determine proper number of #
844 }
845 }
846 }
847
848 impl Debug for TerminalLiteral {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>849 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
850 write!(fmt, "{}", self)
851 }
852 }
853
854 impl Display for Path {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>855 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
856 write!(
857 fmt,
858 "{}{}",
859 if self.absolute { "::" } else { "" },
860 Sep("::", &self.ids),
861 )
862 }
863 }
864
865 impl Display for NonterminalString {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>866 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
867 write!(fmt, "{}", self.0)
868 }
869 }
870
871 impl Debug for NonterminalString {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>872 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
873 Display::fmt(self, fmt)
874 }
875 }
876
877 impl Display for Symbol {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>878 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
879 Display::fmt(&self.kind, fmt)
880 }
881 }
882
883 impl Display for SymbolKind {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>884 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
885 match *self {
886 SymbolKind::Expr(ref expr) => write!(fmt, "{}", expr),
887 SymbolKind::Terminal(ref s) => write!(fmt, "{}", s),
888 SymbolKind::Nonterminal(ref s) => write!(fmt, "{}", s),
889 SymbolKind::AmbiguousId(ref s) => write!(fmt, "{}", s),
890 SymbolKind::Macro(ref m) => write!(fmt, "{}", m),
891 SymbolKind::Repeat(ref r) => write!(fmt, "{}", r),
892 SymbolKind::Choose(ref s) => write!(fmt, "<{}>", s),
893 SymbolKind::Name(ref n, ref s) => write!(fmt, "{}:{}", n, s),
894 SymbolKind::Lookahead => write!(fmt, "@L"),
895 SymbolKind::Lookbehind => write!(fmt, "@R"),
896 SymbolKind::Error => write!(fmt, "error"),
897 }
898 }
899 }
900
901 impl Display for RepeatSymbol {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>902 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
903 write!(fmt, "{}{}", self.symbol, self.op)
904 }
905 }
906
907 impl Display for RepeatOp {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>908 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
909 match *self {
910 RepeatOp::Plus => write!(fmt, "+"),
911 RepeatOp::Star => write!(fmt, "*"),
912 RepeatOp::Question => write!(fmt, "?"),
913 }
914 }
915 }
916
917 impl Display for ExprSymbol {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>918 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
919 write!(fmt, "({})", Sep(" ", &self.symbols))
920 }
921 }
922
923 impl ExternToken {
associated_type(&self, name: Atom) -> Option<&AssociatedType>924 pub fn associated_type(&self, name: Atom) -> Option<&AssociatedType> {
925 self.associated_types
926 .iter()
927 .filter(|a| a.type_name == name)
928 .next()
929 }
930 }
931
932 impl ExprSymbol {
canonical_form(&self) -> String933 pub fn canonical_form(&self) -> String {
934 format!("{}", self)
935 }
936 }
937
938 impl MacroSymbol {
canonical_form(&self) -> String939 pub fn canonical_form(&self) -> String {
940 format!("{}", self)
941 }
942 }
943
944 impl RepeatSymbol {
canonical_form(&self) -> String945 pub fn canonical_form(&self) -> String {
946 format!("{}", self)
947 }
948 }
949
950 impl Display for MacroSymbol {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>951 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
952 write!(fmt, "{}<{}>", self.name, Sep(", ", &self.args))
953 }
954 }
955
956 impl Display for TypeParameter {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>957 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
958 match *self {
959 TypeParameter::Lifetime(ref s) => write!(fmt, "{}", s),
960 TypeParameter::Id(ref s) => write!(fmt, "{}", s),
961 }
962 }
963 }
964
965 impl Display for TypeRef {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>966 fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
967 match *self {
968 TypeRef::Tuple(ref types) => write!(fmt, "({})", Sep(", ", types)),
969 TypeRef::Nominal {
970 ref path,
971 ref types,
972 }
973 if types.len() == 0 =>
974 {
975 write!(fmt, "{}", path)
976 }
977 TypeRef::Nominal {
978 ref path,
979 ref types,
980 } => write!(fmt, "{}<{}>", path, Sep(", ", types)),
981 TypeRef::Lifetime(ref s) => write!(fmt, "{}", s),
982 TypeRef::Id(ref s) => write!(fmt, "{}", s),
983 TypeRef::OfSymbol(ref s) => write!(fmt, "`{}`", s),
984 TypeRef::Ref {
985 lifetime: None,
986 mutable: false,
987 ref referent,
988 } => write!(fmt, "&{}", referent),
989 TypeRef::Ref {
990 lifetime: Some(ref l),
991 mutable: false,
992 ref referent,
993 } => write!(fmt, "&{} {}", l, referent),
994 TypeRef::Ref {
995 lifetime: None,
996 mutable: true,
997 ref referent,
998 } => write!(fmt, "&mut {}", referent),
999 TypeRef::Ref {
1000 lifetime: Some(ref l),
1001 mutable: true,
1002 ref referent,
1003 } => write!(fmt, "&{} mut {}", l, referent),
1004 }
1005 }
1006 }
1007
1008 impl TypeRef {
1009 // Converts a TypeRef to a TypeRepr, assuming no inference is
1010 // required etc. This is safe for all types a user can directly
1011 // type, but not safe for the result of expanding macros.
type_repr(&self) -> TypeRepr1012 pub fn type_repr(&self) -> TypeRepr {
1013 match *self {
1014 TypeRef::Tuple(ref types) => {
1015 TypeRepr::Tuple(types.iter().map(TypeRef::type_repr).collect())
1016 }
1017 TypeRef::Nominal {
1018 ref path,
1019 ref types,
1020 } => TypeRepr::Nominal(NominalTypeRepr {
1021 path: path.clone(),
1022 types: types.iter().map(TypeRef::type_repr).collect(),
1023 }),
1024 TypeRef::Lifetime(ref id) => TypeRepr::Lifetime(id.clone()),
1025 TypeRef::Id(ref id) => TypeRepr::Nominal(NominalTypeRepr {
1026 path: Path::from_id(id.clone()),
1027 types: vec![],
1028 }),
1029 TypeRef::OfSymbol(_) => unreachable!("OfSymbol produced by parser"),
1030 TypeRef::Ref {
1031 ref lifetime,
1032 mutable,
1033 ref referent,
1034 } => TypeRepr::Ref {
1035 lifetime: lifetime.clone(),
1036 mutable: mutable,
1037 referent: Box::new(referent.type_repr()),
1038 },
1039 }
1040 }
1041 }
1042
1043 impl Path {
from_id(id: Atom) -> Path1044 pub fn from_id(id: Atom) -> Path {
1045 Path {
1046 absolute: false,
1047 ids: vec![id],
1048 }
1049 }
1050
usize() -> Path1051 pub fn usize() -> Path {
1052 Path {
1053 absolute: false,
1054 ids: vec![Atom::from("usize")],
1055 }
1056 }
1057
str() -> Path1058 pub fn str() -> Path {
1059 Path {
1060 absolute: false,
1061 ids: vec![Atom::from("str")],
1062 }
1063 }
1064
vec() -> Path1065 pub fn vec() -> Path {
1066 Path {
1067 absolute: true,
1068 ids: vec![Atom::from("std"), Atom::from("vec"), Atom::from("Vec")],
1069 }
1070 }
1071
option() -> Path1072 pub fn option() -> Path {
1073 Path {
1074 absolute: true,
1075 ids: vec![
1076 Atom::from("std"),
1077 Atom::from("option"),
1078 Atom::from("Option"),
1079 ],
1080 }
1081 }
1082
as_id(&self) -> Option<Atom>1083 pub fn as_id(&self) -> Option<Atom> {
1084 if !self.absolute && self.ids.len() == 1 {
1085 Some(self.ids[0].clone())
1086 } else {
1087 None
1088 }
1089 }
1090 }
1091
read_algorithm(annotations: &[Annotation], algorithm: &mut r::Algorithm)1092 pub fn read_algorithm(annotations: &[Annotation], algorithm: &mut r::Algorithm) {
1093 for annotation in annotations {
1094 if annotation.id == Atom::from(LALR) {
1095 algorithm.lalr = true;
1096 } else if annotation.id == Atom::from(TABLE_DRIVEN) {
1097 algorithm.codegen = r::LrCodeGeneration::TableDriven;
1098 } else if annotation.id == Atom::from(RECURSIVE_ASCENT) {
1099 algorithm.codegen = r::LrCodeGeneration::RecursiveAscent;
1100 } else if annotation.id == Atom::from(TEST_ALL) {
1101 algorithm.codegen = r::LrCodeGeneration::TestAll;
1102 } else {
1103 panic!(
1104 "validation permitted unknown annotation: {:?}",
1105 annotation.id,
1106 );
1107 }
1108 }
1109 }
1110