aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_macros/src/mbe_parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_macros/src/mbe_parser.rs')
-rw-r--r--crates/ra_macros/src/mbe_parser.rs94
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 @@
1use crate::{tt, mbe};
2use 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
8pub 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
17fn 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
25fn 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
56fn 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
73fn 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}