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<dyn Content>> for Span {
into(self) -> Box<dyn Content>32     fn into(self) -> Box<dyn 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,
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     // `dyn Trait`
216     TraitObject {
217         path: Path,
218         types: Vec<TypeRef>,
219     },
220 
221     // 'x ==> only should appear within nominal types, but what do we care
222     Lifetime(Lifetime),
223 
224     // Foo or Bar ==> treated specially since macros may care
225     Id(Atom),
226 
227     // <N> ==> type of a nonterminal, emitted by macro expansion
228     OfSymbol(SymbolKind),
229 
230     Fn {
231         forall: Vec<TypeParameter>,
232         path: Path,
233         parameters: Vec<TypeRef>,
234         ret: Option<Box<TypeRef>>,
235     },
236 }
237 
238 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
239 pub enum WhereClause<T> {
240     // 'a: 'b + 'c
241     Lifetime {
242         lifetime: Lifetime,
243         bounds: Vec<Lifetime>,
244     },
245     // where for<'a> &'a T: Debug + Into<usize>
246     Type {
247         forall: Vec<TypeParameter>,
248         ty: T,
249         bounds: Vec<TypeBound<T>>,
250     },
251 }
252 
253 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
254 pub enum TypeBound<T> {
255     // The `'a` in `T: 'a`.
256     Lifetime(Lifetime),
257 
258     // `for<'a> FnMut(&'a usize)`
259     Fn {
260         forall: Vec<TypeParameter>,
261         path: Path,
262         parameters: Vec<T>,
263         ret: Option<T>,
264     },
265 
266     // `some::Trait` or `some::Trait<Param, ...>` or `some::Trait<Item = Assoc>`
267     // or `for<'a> Trait<'a, T>`
268     Trait {
269         forall: Vec<TypeParameter>,
270         path: Path,
271         parameters: Vec<TypeBoundParameter<T>>,
272     },
273 }
274 
275 impl<T> TypeBound<T> {
map<F, U>(&self, mut f: F) -> TypeBound<U> where F: FnMut(&T) -> U,276     pub fn map<F, U>(&self, mut f: F) -> TypeBound<U>
277     where
278         F: FnMut(&T) -> U,
279     {
280         match *self {
281             TypeBound::Lifetime(ref l) => TypeBound::Lifetime(l.clone()),
282             TypeBound::Fn {
283                 ref forall,
284                 ref path,
285                 ref parameters,
286                 ref ret,
287             } => TypeBound::Fn {
288                 forall: forall.clone(),
289                 path: path.clone(),
290                 parameters: parameters.iter().map(&mut f).collect(),
291                 ret: ret.as_ref().map(f),
292             },
293             TypeBound::Trait {
294                 ref forall,
295                 ref path,
296                 ref parameters,
297             } => TypeBound::Trait {
298                 forall: forall.clone(),
299                 path: path.clone(),
300                 parameters: parameters.iter().map(|p| p.map(&mut f)).collect(),
301             },
302         }
303     }
304 }
305 
306 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
307 pub enum TypeBoundParameter<T> {
308     // 'a
309     Lifetime(Lifetime),
310     // `T` or `'a`
311     TypeParameter(T),
312     // `Item = T`
313     Associated(Atom, T),
314 }
315 
316 impl<T> TypeBoundParameter<T> {
map<F, U>(&self, mut f: F) -> TypeBoundParameter<U> where F: FnMut(&T) -> U,317     pub fn map<F, U>(&self, mut f: F) -> TypeBoundParameter<U>
318     where
319         F: FnMut(&T) -> U,
320     {
321         match *self {
322             TypeBoundParameter::Lifetime(ref l) => TypeBoundParameter::Lifetime(l.clone()),
323             TypeBoundParameter::TypeParameter(ref t) => TypeBoundParameter::TypeParameter(f(t)),
324             TypeBoundParameter::Associated(ref id, ref t) => {
325                 TypeBoundParameter::Associated(id.clone(), f(t))
326             }
327         }
328     }
329 }
330 
331 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
332 pub enum TypeParameter {
333     Lifetime(Lifetime),
334     Id(Atom),
335 }
336 
337 #[derive(Clone, Debug, PartialEq, Eq)]
338 pub struct Parameter {
339     pub name: Atom,
340     pub ty: TypeRef,
341 }
342 
343 #[derive(Clone, Debug, PartialEq, Eq)]
344 pub enum Visibility {
345     Pub(Option<Path>),
346     Priv,
347 }
348 
349 impl Visibility {
is_pub(&self) -> bool350     pub fn is_pub(&self) -> bool {
351         match *self {
352             Visibility::Pub(_) => true,
353             Visibility::Priv => false,
354         }
355     }
356 }
357 
358 #[derive(Clone, Debug, PartialEq, Eq)]
359 pub struct NonterminalData {
360     pub visibility: Visibility,
361     pub name: NonterminalString,
362     pub annotations: Vec<Annotation>,
363     pub span: Span,
364     pub args: Vec<NonterminalString>, // macro arguments
365     pub type_decl: Option<TypeRef>,
366     pub alternatives: Vec<Alternative>,
367 }
368 
369 #[derive(Clone, Debug, PartialEq, Eq)]
370 pub struct Annotation {
371     pub id_span: Span,
372     pub id: Atom,
373     pub arg: Option<(Atom, String)>,
374 }
375 
376 #[derive(Clone, Debug, PartialEq, Eq)]
377 pub struct Alternative {
378     pub span: Span,
379 
380     pub expr: ExprSymbol,
381 
382     // if C, only legal in macros
383     pub condition: Option<Condition>,
384 
385     // => { code }
386     pub action: Option<ActionKind>,
387 }
388 
389 #[derive(Clone, Debug, PartialEq, Eq)]
390 pub enum ActionKind {
391     User(String),
392     Fallible(String),
393     Lookahead,
394     Lookbehind,
395 }
396 
397 #[derive(Clone, Debug, PartialEq, Eq)]
398 pub struct Condition {
399     pub span: Span,
400     pub lhs: NonterminalString, // X
401     pub rhs: Atom,              // "Foo"
402     pub op: ConditionOp,
403 }
404 
405 #[derive(Clone, Debug, PartialEq, Eq)]
406 pub enum ConditionOp {
407     // X == "Foo", equality
408     Equals,
409 
410     // X != "Foo", inequality
411     NotEquals,
412 
413     // X ~~ "Foo", regexp match
414     Match,
415 
416     // X !~ "Foo", regexp non-match
417     NotMatch,
418 }
419 
420 #[derive(Clone, Debug, PartialEq, Eq)]
421 pub struct Symbol {
422     pub span: Span,
423     pub kind: SymbolKind,
424 }
425 
426 #[derive(Clone, Debug, PartialEq, Eq)]
427 pub enum SymbolKind {
428     // (X Y)
429     Expr(ExprSymbol),
430 
431     // foo, before name resolution
432     AmbiguousId(Atom),
433 
434     // "foo" and foo (after name resolution)
435     Terminal(TerminalString),
436 
437     // foo, after name resolution
438     Nonterminal(NonterminalString),
439 
440     // foo<..>
441     Macro(MacroSymbol),
442 
443     // X+, X?, X*
444     Repeat(Box<RepeatSymbol>),
445 
446     // <X>
447     Choose(Box<Symbol>),
448 
449     // <x:X> or <mut x:X>
450     Name(Name, Box<Symbol>),
451 
452     // @L
453     Lookahead,
454 
455     // @R
456     Lookbehind,
457 
458     Error,
459 }
460 
461 #[derive(Clone, Debug, PartialEq, Eq)]
462 pub struct Name {
463     pub mutable: bool,
464     pub name: Atom,
465 }
466 
467 #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
468 pub enum TerminalString {
469     Literal(TerminalLiteral),
470     Bare(Atom),
471     Error,
472 }
473 
474 impl TerminalString {
as_literal(&self) -> Option<TerminalLiteral>475     pub fn as_literal(&self) -> Option<TerminalLiteral> {
476         match *self {
477             TerminalString::Literal(ref l) => Some(l.clone()),
478             _ => None,
479         }
480     }
481 
display_len(&self) -> usize482     pub fn display_len(&self) -> usize {
483         match *self {
484             TerminalString::Literal(ref x) => x.display_len(),
485             TerminalString::Bare(ref x) => x.len(),
486             TerminalString::Error => "error".len(),
487         }
488     }
489 }
490 
491 #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
492 pub enum TerminalLiteral {
493     Quoted(Atom),
494     Regex(Atom),
495 }
496 
497 impl TerminalLiteral {
498     /// The *base precedence* is the precedence within a `match { }`
499     /// block level. It indicates that quoted things like `"foo"` get
500     /// precedence over regex matches.
base_precedence(&self) -> usize501     pub fn base_precedence(&self) -> usize {
502         match *self {
503             TerminalLiteral::Quoted(_) => 1,
504             TerminalLiteral::Regex(_) => 0,
505         }
506     }
507 
display_len(&self) -> usize508     pub fn display_len(&self) -> usize {
509         match *self {
510             TerminalLiteral::Quoted(ref x) => x.len(),
511             TerminalLiteral::Regex(ref x) => x.len() + "####r".len(),
512         }
513     }
514 }
515 
516 #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
517 pub struct NonterminalString(pub Atom);
518 
519 impl NonterminalString {
len(&self) -> usize520     pub fn len(&self) -> usize {
521         self.0.len()
522     }
523 }
524 
525 impl Into<Box<dyn Content>> for NonterminalString {
into(self) -> Box<dyn Content>526     fn into(self) -> Box<dyn Content> {
527         let session = Tls::session();
528 
529         InlineBuilder::new()
530             .text(self)
531             .styled(session.nonterminal_symbol)
532             .end()
533     }
534 }
535 
536 #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
537 pub struct Lifetime(pub Atom);
538 
539 impl Lifetime {
anonymous() -> Self540     pub fn anonymous() -> Self {
541         Lifetime(Atom::from("'_"))
542     }
543 
is_anonymous(&self) -> bool544     pub fn is_anonymous(&self) -> bool {
545         *self == Self::anonymous()
546     }
547 
statik() -> Self548     pub fn statik() -> Self {
549         Lifetime(Atom::from("'static"))
550     }
551 
input() -> Self552     pub fn input() -> Self {
553         Lifetime(Atom::from(INPUT_LIFETIME))
554     }
555 
len(&self) -> usize556     pub fn len(&self) -> usize {
557         self.0.len()
558     }
559 }
560 
561 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
562 pub enum RepeatOp {
563     Star,
564     Plus,
565     Question,
566 }
567 
568 #[derive(Clone, Debug, PartialEq, Eq)]
569 pub struct RepeatSymbol {
570     pub op: RepeatOp,
571     pub symbol: Symbol,
572 }
573 
574 #[derive(Clone, Debug, PartialEq, Eq)]
575 pub struct ExprSymbol {
576     pub symbols: Vec<Symbol>,
577 }
578 
579 #[derive(Clone, Debug, PartialEq, Eq)]
580 pub struct MacroSymbol {
581     pub name: NonterminalString,
582     pub args: Vec<Symbol>,
583 }
584 
585 impl TerminalString {
quoted(i: Atom) -> TerminalString586     pub fn quoted(i: Atom) -> TerminalString {
587         TerminalString::Literal(TerminalLiteral::Quoted(i))
588     }
589 
regex(i: Atom) -> TerminalString590     pub fn regex(i: Atom) -> TerminalString {
591         TerminalString::Literal(TerminalLiteral::Regex(i))
592     }
593 }
594 
595 impl Into<Box<dyn Content>> for TerminalString {
into(self) -> Box<dyn Content>596     fn into(self) -> Box<dyn Content> {
597         let session = Tls::session();
598         InlineBuilder::new()
599             .text(self)
600             .styled(session.terminal_symbol)
601             .end()
602     }
603 }
604 
605 impl Grammar {
extern_token(&self) -> Option<&ExternToken>606     pub fn extern_token(&self) -> Option<&ExternToken> {
607         self.items
608             .iter()
609             .flat_map(GrammarItem::as_extern_token)
610             .next()
611     }
612 
enum_token(&self) -> Option<&EnumToken>613     pub fn enum_token(&self) -> Option<&EnumToken> {
614         self.items
615             .iter()
616             .flat_map(GrammarItem::as_extern_token)
617             .flat_map(|et| et.enum_token.as_ref())
618             .next()
619     }
620 
intern_token(&self) -> Option<&InternToken>621     pub fn intern_token(&self) -> Option<&InternToken> {
622         self.items
623             .iter()
624             .flat_map(GrammarItem::as_intern_token)
625             .next()
626     }
627 
match_token(&self) -> Option<&MatchToken>628     pub fn match_token(&self) -> Option<&MatchToken> {
629         self.items
630             .iter()
631             .flat_map(GrammarItem::as_match_token)
632             .next()
633     }
634 }
635 
636 impl GrammarItem {
is_macro_def(&self) -> bool637     pub fn is_macro_def(&self) -> bool {
638         match *self {
639             GrammarItem::Nonterminal(ref d) => d.is_macro_def(),
640             _ => false,
641         }
642     }
643 
as_nonterminal(&self) -> Option<&NonterminalData>644     pub fn as_nonterminal(&self) -> Option<&NonterminalData> {
645         match *self {
646             GrammarItem::Nonterminal(ref d) => Some(d),
647             GrammarItem::Use(..) => None,
648             GrammarItem::MatchToken(..) => None,
649             GrammarItem::ExternToken(..) => None,
650             GrammarItem::InternToken(..) => None,
651         }
652     }
653 
as_match_token(&self) -> Option<&MatchToken>654     pub fn as_match_token(&self) -> Option<&MatchToken> {
655         match *self {
656             GrammarItem::Nonterminal(..) => None,
657             GrammarItem::Use(..) => None,
658             GrammarItem::MatchToken(ref d) => Some(d),
659             GrammarItem::ExternToken(..) => None,
660             GrammarItem::InternToken(..) => None,
661         }
662     }
663 
as_extern_token(&self) -> Option<&ExternToken>664     pub fn as_extern_token(&self) -> Option<&ExternToken> {
665         match *self {
666             GrammarItem::Nonterminal(..) => None,
667             GrammarItem::Use(..) => None,
668             GrammarItem::MatchToken(..) => None,
669             GrammarItem::ExternToken(ref d) => Some(d),
670             GrammarItem::InternToken(..) => None,
671         }
672     }
673 
as_intern_token(&self) -> Option<&InternToken>674     pub fn as_intern_token(&self) -> Option<&InternToken> {
675         match *self {
676             GrammarItem::Nonterminal(..) => None,
677             GrammarItem::Use(..) => None,
678             GrammarItem::MatchToken(..) => None,
679             GrammarItem::ExternToken(..) => None,
680             GrammarItem::InternToken(ref d) => Some(d),
681         }
682     }
683 }
684 
685 impl NonterminalData {
is_macro_def(&self) -> bool686     pub fn is_macro_def(&self) -> bool {
687         !self.args.is_empty()
688     }
689 }
690 
691 impl Symbol {
new(span: Span, kind: SymbolKind) -> Symbol692     pub fn new(span: Span, kind: SymbolKind) -> Symbol {
693         Symbol { span, kind }
694     }
695 
canonical_form(&self) -> String696     pub fn canonical_form(&self) -> String {
697         format!("{}", self)
698     }
699 }
700 
701 impl Name {
new(mutable: bool, name: Atom) -> Self702     pub fn new(mutable: bool, name: Atom) -> Self {
703         Name { mutable, name }
704     }
705 
immut(name: Atom) -> Self706     pub fn immut(name: Atom) -> Self {
707         Name::new(false, name)
708     }
709 }
710 
711 impl Display for Visibility {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>712     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
713         match *self {
714             Visibility::Pub(Some(ref path)) => write!(fmt, "pub({}) ", path),
715             Visibility::Pub(None) => write!(fmt, "pub "),
716             Visibility::Priv => Ok(()),
717         }
718     }
719 }
720 
721 impl<T: Display> Display for WhereClause<T> {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>722     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
723         match *self {
724             WhereClause::Lifetime {
725                 ref lifetime,
726                 ref bounds,
727             } => {
728                 write!(fmt, "{}:", lifetime)?;
729                 for (i, b) in bounds.iter().enumerate() {
730                     if i != 0 {
731                         write!(fmt, " +")?;
732                     }
733                     write!(fmt, " {}", b)?;
734                 }
735                 Ok(())
736             }
737             WhereClause::Type {
738                 ref forall,
739                 ref ty,
740                 ref bounds,
741             } => {
742                 if !forall.is_empty() {
743                     write!(fmt, "for<")?;
744                     for (i, l) in forall.iter().enumerate() {
745                         if i != 0 {
746                             write!(fmt, ", ")?;
747                         }
748                         write!(fmt, "{}", l)?;
749                     }
750                     write!(fmt, "> ")?;
751                 }
752 
753                 write!(fmt, "{}: ", ty)?;
754                 for (i, b) in bounds.iter().enumerate() {
755                     if i != 0 {
756                         write!(fmt, " +")?;
757                     }
758                     write!(fmt, " {}", b)?;
759                 }
760                 Ok(())
761             }
762         }
763     }
764 }
765 
766 impl<T: Display> Display for TypeBound<T> {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>767     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
768         match *self {
769             TypeBound::Lifetime(ref l) => write!(fmt, "{}", l),
770             TypeBound::Fn {
771                 ref forall,
772                 ref path,
773                 ref parameters,
774                 ref ret,
775             } => {
776                 if !forall.is_empty() {
777                     write!(fmt, "for<")?;
778                     for (i, l) in forall.iter().enumerate() {
779                         if i != 0 {
780                             write!(fmt, ", ")?;
781                         }
782                         write!(fmt, "{}", l)?;
783                     }
784                     write!(fmt, "> ")?;
785                 }
786 
787                 write!(fmt, "{}(", path)?;
788                 for (i, p) in parameters.iter().enumerate() {
789                     if i != 0 {
790                         write!(fmt, ", ")?;
791                     }
792                     write!(fmt, "{}", p)?;
793                 }
794                 write!(fmt, ")")?;
795 
796                 if let Some(ref ret) = *ret {
797                     write!(fmt, " -> {}", ret)?;
798                 }
799 
800                 Ok(())
801             }
802             TypeBound::Trait {
803                 ref forall,
804                 ref path,
805                 ref parameters,
806             } => {
807                 if !forall.is_empty() {
808                     write!(fmt, "for<")?;
809                     for (i, l) in forall.iter().enumerate() {
810                         if i != 0 {
811                             write!(fmt, ", ")?;
812                         }
813                         write!(fmt, "{}", l)?;
814                     }
815                     write!(fmt, "> ")?;
816                 }
817 
818                 write!(fmt, "{}", path)?;
819                 if parameters.is_empty() {
820                     return Ok(());
821                 }
822 
823                 write!(fmt, "<")?;
824                 for (i, p) in parameters.iter().enumerate() {
825                     if i != 0 {
826                         write!(fmt, ", ")?;
827                     }
828                     write!(fmt, "{}", p)?;
829                 }
830                 write!(fmt, ">")
831             }
832         }
833     }
834 }
835 
836 impl<T: Display> Display for TypeBoundParameter<T> {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>837     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
838         match *self {
839             TypeBoundParameter::Lifetime(ref l) => write!(fmt, "{}", l),
840             TypeBoundParameter::TypeParameter(ref t) => write!(fmt, "{}", t),
841             TypeBoundParameter::Associated(ref id, ref t) => write!(fmt, "{} = {}", id, t),
842         }
843     }
844 }
845 
846 impl Display for TerminalString {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>847     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
848         match *self {
849             TerminalString::Literal(ref s) => write!(fmt, "{}", s),
850             TerminalString::Bare(ref s) => write!(fmt, "{}", s),
851             TerminalString::Error => write!(fmt, "error"),
852         }
853     }
854 }
855 
856 impl Debug for TerminalString {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>857     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
858         Display::fmt(self, fmt)
859     }
860 }
861 
862 impl Display for Lifetime {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>863     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
864         Display::fmt(&self.0, fmt)
865     }
866 }
867 
868 impl Debug for Lifetime {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>869     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
870         Display::fmt(self, fmt)
871     }
872 }
873 
874 impl Display for TerminalLiteral {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>875     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
876         match *self {
877             TerminalLiteral::Quoted(ref s) => write!(fmt, "{:?}", s.as_ref()), // the Debug impl adds the `"` and escaping
878             TerminalLiteral::Regex(ref s) => write!(fmt, "r#{:?}#", s.as_ref()), // FIXME -- need to determine proper number of #
879         }
880     }
881 }
882 
883 impl Debug for TerminalLiteral {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>884     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
885         write!(fmt, "{}", self)
886     }
887 }
888 
889 impl Display for Path {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>890     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
891         write!(
892             fmt,
893             "{}{}",
894             if self.absolute { "::" } else { "" },
895             Sep("::", &self.ids),
896         )
897     }
898 }
899 
900 impl Display for NonterminalString {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>901     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
902         write!(fmt, "{}", self.0)
903     }
904 }
905 
906 impl Debug for NonterminalString {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>907     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
908         Display::fmt(self, fmt)
909     }
910 }
911 
912 impl Display for Symbol {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>913     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
914         Display::fmt(&self.kind, fmt)
915     }
916 }
917 
918 impl Display for SymbolKind {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>919     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
920         match *self {
921             SymbolKind::Expr(ref expr) => write!(fmt, "{}", expr),
922             SymbolKind::Terminal(ref s) => write!(fmt, "{}", s),
923             SymbolKind::Nonterminal(ref s) => write!(fmt, "{}", s),
924             SymbolKind::AmbiguousId(ref s) => write!(fmt, "{}", s),
925             SymbolKind::Macro(ref m) => write!(fmt, "{}", m),
926             SymbolKind::Repeat(ref r) => write!(fmt, "{}", r),
927             SymbolKind::Choose(ref s) => write!(fmt, "<{}>", s),
928             SymbolKind::Name(ref n, ref s) => write!(fmt, "{}:{}", n, s),
929             SymbolKind::Lookahead => write!(fmt, "@L"),
930             SymbolKind::Lookbehind => write!(fmt, "@R"),
931             SymbolKind::Error => write!(fmt, "error"),
932         }
933     }
934 }
935 
936 impl Display for Name {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>937     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
938         if self.mutable {
939             write!(fmt, "mut {}", self.name)
940         } else {
941             Display::fmt(&self.name, fmt)
942         }
943     }
944 }
945 
946 impl Display for RepeatSymbol {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>947     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
948         write!(fmt, "{}{}", self.symbol, self.op)
949     }
950 }
951 
952 impl Display for RepeatOp {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>953     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
954         match *self {
955             RepeatOp::Plus => write!(fmt, "+"),
956             RepeatOp::Star => write!(fmt, "*"),
957             RepeatOp::Question => write!(fmt, "?"),
958         }
959     }
960 }
961 
962 impl Display for ExprSymbol {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>963     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
964         write!(fmt, "({})", Sep(" ", &self.symbols))
965     }
966 }
967 
968 impl ExternToken {
associated_type(&self, name: Atom) -> Option<&AssociatedType>969     pub fn associated_type(&self, name: Atom) -> Option<&AssociatedType> {
970         self.associated_types.iter().find(|a| a.type_name == name)
971     }
972 }
973 
974 impl ExprSymbol {
canonical_form(&self) -> String975     pub fn canonical_form(&self) -> String {
976         format!("{}", self)
977     }
978 }
979 
980 impl MacroSymbol {
canonical_form(&self) -> String981     pub fn canonical_form(&self) -> String {
982         format!("{}", self)
983     }
984 }
985 
986 impl RepeatSymbol {
canonical_form(&self) -> String987     pub fn canonical_form(&self) -> String {
988         format!("{}", self)
989     }
990 }
991 
992 impl Display for MacroSymbol {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>993     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
994         write!(fmt, "{}<{}>", self.name, Sep(", ", &self.args))
995     }
996 }
997 
998 impl Display for TypeParameter {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>999     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
1000         match *self {
1001             TypeParameter::Lifetime(ref s) => write!(fmt, "{}", s),
1002             TypeParameter::Id(ref s) => write!(fmt, "{}", s),
1003         }
1004     }
1005 }
1006 
1007 impl Display for TypeRef {
fmt(&self, fmt: &mut Formatter) -> Result<(), Error>1008     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
1009         match *self {
1010             TypeRef::Tuple(ref types) => write!(fmt, "({})", Sep(", ", types)),
1011             TypeRef::Nominal {
1012                 ref path,
1013                 ref types,
1014             } if types.is_empty() => write!(fmt, "{}", path),
1015             TypeRef::Nominal {
1016                 ref path,
1017                 ref types,
1018             } => write!(fmt, "{}<{}>", path, Sep(", ", types)),
1019             TypeRef::TraitObject {
1020                 ref path,
1021                 ref types,
1022             } if types.is_empty() => write!(fmt, "dyn {}", path),
1023             TypeRef::TraitObject {
1024                 ref path,
1025                 ref types,
1026             } => write!(fmt, "dyn {}<{}>", path, Sep(", ", types)),
1027             TypeRef::Lifetime(ref s) => write!(fmt, "{}", s),
1028             TypeRef::Id(ref s) => write!(fmt, "{}", s),
1029             TypeRef::OfSymbol(ref s) => write!(fmt, "`{}`", s),
1030             TypeRef::Ref {
1031                 lifetime: None,
1032                 mutable: false,
1033                 ref referent,
1034             } => write!(fmt, "&{}", referent),
1035             TypeRef::Ref {
1036                 lifetime: Some(ref l),
1037                 mutable: false,
1038                 ref referent,
1039             } => write!(fmt, "&{} {}", l, referent),
1040             TypeRef::Ref {
1041                 lifetime: None,
1042                 mutable: true,
1043                 ref referent,
1044             } => write!(fmt, "&mut {}", referent),
1045             TypeRef::Ref {
1046                 lifetime: Some(ref l),
1047                 mutable: true,
1048                 ref referent,
1049             } => write!(fmt, "&{} mut {}", l, referent),
1050             TypeRef::Fn {
1051                 ref forall,
1052                 ref path,
1053                 ref parameters,
1054                 ref ret,
1055             } => {
1056                 write!(fmt, "dyn ")?;
1057                 if !forall.is_empty() {
1058                     write!(fmt, "for<{}> ", Sep(", ", forall),)?;
1059                 }
1060                 write!(fmt, "{}({})", path, Sep(", ", parameters))?;
1061                 if let Some(ret) = ret {
1062                     write!(fmt, " -> {}", ret)?;
1063                 }
1064                 Ok(())
1065             }
1066         }
1067     }
1068 }
1069 
1070 impl TypeRef {
1071     // Converts a TypeRef to a TypeRepr, assuming no inference is
1072     // required etc. This is safe for all types a user can directly
1073     // type, but not safe for the result of expanding macros.
type_repr(&self) -> TypeRepr1074     pub fn type_repr(&self) -> TypeRepr {
1075         match *self {
1076             TypeRef::Tuple(ref types) => {
1077                 TypeRepr::Tuple(types.iter().map(TypeRef::type_repr).collect())
1078             }
1079             TypeRef::Nominal {
1080                 ref path,
1081                 ref types,
1082             } => TypeRepr::Nominal(NominalTypeRepr {
1083                 path: path.clone(),
1084                 types: types.iter().map(TypeRef::type_repr).collect(),
1085             }),
1086             TypeRef::Lifetime(ref id) => TypeRepr::Lifetime(id.clone()),
1087             TypeRef::Id(ref id) => TypeRepr::Nominal(NominalTypeRepr {
1088                 path: Path::from_id(id.clone()),
1089                 types: vec![],
1090             }),
1091             TypeRef::OfSymbol(_) => unreachable!("OfSymbol produced by parser"),
1092             TypeRef::Ref {
1093                 ref lifetime,
1094                 mutable,
1095                 ref referent,
1096             } => TypeRepr::Ref {
1097                 lifetime: lifetime.clone(),
1098                 mutable,
1099                 referent: Box::new(referent.type_repr()),
1100             },
1101             TypeRef::TraitObject {
1102                 ref path,
1103                 ref types,
1104             } => TypeRepr::TraitObject(NominalTypeRepr {
1105                 path: path.clone(),
1106                 types: types.iter().map(TypeRef::type_repr).collect(),
1107             }),
1108             TypeRef::Fn {
1109                 ref forall,
1110                 ref path,
1111                 ref parameters,
1112                 ref ret,
1113             } => TypeRepr::Fn {
1114                 forall: forall.clone(),
1115                 path: path.clone(),
1116                 parameters: parameters.iter().map(TypeRef::type_repr).collect(),
1117                 ret: ret.as_ref().map(|t| Box::new(TypeRef::type_repr(t))),
1118             },
1119         }
1120     }
1121 }
1122 
1123 impl Path {
from_id(id: Atom) -> Path1124     pub fn from_id(id: Atom) -> Path {
1125         Path {
1126             absolute: false,
1127             ids: vec![id],
1128         }
1129     }
1130 
usize() -> Path1131     pub fn usize() -> Path {
1132         Path {
1133             absolute: false,
1134             ids: vec![Atom::from("usize")],
1135         }
1136     }
1137 
str() -> Path1138     pub fn str() -> Path {
1139         Path {
1140             absolute: false,
1141             ids: vec![Atom::from("str")],
1142         }
1143     }
1144 
vec() -> Path1145     pub fn vec() -> Path {
1146         Path {
1147             absolute: true,
1148             ids: vec![Atom::from("std"), Atom::from("vec"), Atom::from("Vec")],
1149         }
1150     }
1151 
option() -> Path1152     pub fn option() -> Path {
1153         Path {
1154             absolute: true,
1155             ids: vec![
1156                 Atom::from("std"),
1157                 Atom::from("option"),
1158                 Atom::from("Option"),
1159             ],
1160         }
1161     }
1162 
as_id(&self) -> Option<Atom>1163     pub fn as_id(&self) -> Option<Atom> {
1164         if !self.absolute && self.ids.len() == 1 {
1165             Some(self.ids[0].clone())
1166         } else {
1167             None
1168         }
1169     }
1170 }
1171 
read_algorithm(annotations: &[Annotation], algorithm: &mut r::Algorithm)1172 pub fn read_algorithm(annotations: &[Annotation], algorithm: &mut r::Algorithm) {
1173     for annotation in annotations {
1174         if annotation.id == Atom::from(LALR) {
1175             algorithm.lalr = true;
1176         } else if annotation.id == Atom::from(TABLE_DRIVEN) {
1177             algorithm.codegen = r::LrCodeGeneration::TableDriven;
1178         } else if annotation.id == Atom::from(RECURSIVE_ASCENT) {
1179             algorithm.codegen = r::LrCodeGeneration::RecursiveAscent;
1180         } else if annotation.id == Atom::from(TEST_ALL) {
1181             algorithm.codegen = r::LrCodeGeneration::TestAll;
1182         } else {
1183             panic!(
1184                 "validation permitted unknown annotation: {:?}",
1185                 annotation.id,
1186             );
1187         }
1188     }
1189 }
1190