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