diff options
Diffstat (limited to 'crates/ra_macros/src/mbe_parser.rs')
-rw-r--r-- | crates/ra_macros/src/mbe_parser.rs | 94 |
1 files changed, 0 insertions, 94 deletions
diff --git a/crates/ra_macros/src/mbe_parser.rs b/crates/ra_macros/src/mbe_parser.rs deleted file mode 100644 index 483594590..000000000 --- a/crates/ra_macros/src/mbe_parser.rs +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | use crate::{tt, mbe}; | ||
2 | use crate::tt_cursor::TtCursor; | ||
3 | |||
4 | /// This module parses a raw `tt::TokenStream` into macro-by-example token | ||
5 | /// stream. This is a *mostly* identify function, expect for handling of | ||
6 | /// `$var:tt_kind` and `$(repeat),*` constructs. | ||
7 | |||
8 | pub fn parse(tt: &tt::Subtree) -> Option<mbe::MacroRules> { | ||
9 | let mut parser = TtCursor::new(tt); | ||
10 | let mut rules = Vec::new(); | ||
11 | while !parser.is_eof() { | ||
12 | rules.push(parse_rule(&mut parser)?) | ||
13 | } | ||
14 | Some(mbe::MacroRules { rules }) | ||
15 | } | ||
16 | |||
17 | fn parse_rule(p: &mut TtCursor) -> Option<mbe::Rule> { | ||
18 | let lhs = parse_subtree(p.eat_subtree()?)?; | ||
19 | p.expect_char('=')?; | ||
20 | p.expect_char('>')?; | ||
21 | let rhs = parse_subtree(p.eat_subtree()?)?; | ||
22 | Some(mbe::Rule { lhs, rhs }) | ||
23 | } | ||
24 | |||
25 | fn parse_subtree(tt: &tt::Subtree) -> Option<mbe::Subtree> { | ||
26 | let mut token_trees = Vec::new(); | ||
27 | let mut p = TtCursor::new(tt); | ||
28 | while let Some(tt) = p.eat() { | ||
29 | let child: mbe::TokenTree = match tt { | ||
30 | tt::TokenTree::Leaf(leaf) => match leaf { | ||
31 | tt::Leaf::Punct(tt::Punct { char: '$', .. }) => { | ||
32 | if p.at_ident().is_some() { | ||
33 | mbe::Leaf::from(parse_var(&mut p)?).into() | ||
34 | } else { | ||
35 | parse_repeat(&mut p)?.into() | ||
36 | } | ||
37 | } | ||
38 | tt::Leaf::Punct(punct) => mbe::Leaf::from(*punct).into(), | ||
39 | tt::Leaf::Ident(tt::Ident { text }) => { | ||
40 | mbe::Leaf::from(mbe::Ident { text: text.clone() }).into() | ||
41 | } | ||
42 | tt::Leaf::Literal(tt::Literal { text }) => { | ||
43 | mbe::Leaf::from(mbe::Literal { text: text.clone() }).into() | ||
44 | } | ||
45 | }, | ||
46 | tt::TokenTree::Subtree(subtree) => parse_subtree(subtree)?.into(), | ||
47 | }; | ||
48 | token_trees.push(child); | ||
49 | } | ||
50 | Some(mbe::Subtree { | ||
51 | token_trees, | ||
52 | delimiter: tt.delimiter, | ||
53 | }) | ||
54 | } | ||
55 | |||
56 | fn parse_var(p: &mut TtCursor) -> Option<mbe::Var> { | ||
57 | let ident = p.eat_ident().unwrap(); | ||
58 | let text = ident.text.clone(); | ||
59 | let kind = if p.at_char(':') { | ||
60 | p.bump(); | ||
61 | if let Some(ident) = p.eat_ident() { | ||
62 | Some(ident.text.clone()) | ||
63 | } else { | ||
64 | p.rev_bump(); | ||
65 | None | ||
66 | } | ||
67 | } else { | ||
68 | None | ||
69 | }; | ||
70 | Some(mbe::Var { text, kind }) | ||
71 | } | ||
72 | |||
73 | fn parse_repeat(p: &mut TtCursor) -> Option<mbe::Repeat> { | ||
74 | let subtree = p.eat_subtree().unwrap(); | ||
75 | let subtree = parse_subtree(subtree)?; | ||
76 | let sep = p.eat_punct()?; | ||
77 | let (separator, rep) = match sep.char { | ||
78 | '*' | '+' | '?' => (None, sep.char), | ||
79 | char => (Some(char), p.eat_punct()?.char), | ||
80 | }; | ||
81 | |||
82 | let kind = match rep { | ||
83 | '*' => mbe::RepeatKind::ZeroOrMore, | ||
84 | '+' => mbe::RepeatKind::OneOrMore, | ||
85 | '?' => mbe::RepeatKind::ZeroOrOne, | ||
86 | _ => return None, | ||
87 | }; | ||
88 | p.bump(); | ||
89 | Some(mbe::Repeat { | ||
90 | subtree, | ||
91 | kind, | ||
92 | separator, | ||
93 | }) | ||
94 | } | ||