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