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