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.rs102
1 files changed, 7 insertions, 95 deletions
diff --git a/crates/ra_macros/src/mbe_parser.rs b/crates/ra_macros/src/mbe_parser.rs
index 93c2d40b4..024d3a040 100644
--- a/crates/ra_macros/src/mbe_parser.rs
+++ b/crates/ra_macros/src/mbe_parser.rs
@@ -1,99 +1,12 @@
1use crate::{tt, mbe}; 1use crate::{tt, mbe};
2use crate::tt_cursor::TtCursor;
2 3
3/// This module parses a raw `tt::TokenStream` into macro-by-example token 4/// This module parses a raw `tt::TokenStream` into macro-by-example token
4/// stream. This is a *mostly* identify function, expect for handling of 5/// stream. This is a *mostly* identify function, expect for handling of
5/// `$var:tt_kind` and `$(repeat),*` constructs. 6/// `$var:tt_kind` and `$(repeat),*` constructs.
6 7
7struct RulesParser<'a> {
8 subtree: &'a tt::Subtree,
9 pos: usize,
10}
11
12impl<'a> RulesParser<'a> {
13 fn new(subtree: &'a tt::Subtree) -> RulesParser<'a> {
14 RulesParser { subtree, pos: 0 }
15 }
16
17 fn is_eof(&self) -> bool {
18 self.pos == self.subtree.token_trees.len()
19 }
20
21 fn current(&self) -> Option<&'a tt::TokenTree> {
22 self.subtree.token_trees.get(self.pos)
23 }
24
25 fn at_punct(&self) -> Option<&'a tt::Punct> {
26 match self.current() {
27 Some(tt::TokenTree::Leaf(tt::Leaf::Punct(it))) => Some(it),
28 _ => None,
29 }
30 }
31
32 fn at_char(&self, char: char) -> bool {
33 match self.at_punct() {
34 Some(tt::Punct { char: c }) if *c == char => true,
35 _ => false,
36 }
37 }
38
39 fn at_ident(&mut self) -> Option<&'a tt::Ident> {
40 match self.current() {
41 Some(tt::TokenTree::Leaf(tt::Leaf::Ident(i))) => Some(i),
42 _ => None,
43 }
44 }
45
46 fn bump(&mut self) {
47 self.pos += 1;
48 }
49
50 fn eat(&mut self) -> Option<&'a tt::TokenTree> {
51 match self.current() {
52 Some(it) => {
53 self.bump();
54 Some(it)
55 }
56 None => None,
57 }
58 }
59
60 fn eat_subtree(&mut self) -> Option<&'a tt::Subtree> {
61 match self.current()? {
62 tt::TokenTree::Subtree(sub) => {
63 self.bump();
64 Some(sub)
65 }
66 _ => return None,
67 }
68 }
69
70 fn eat_punct(&mut self) -> Option<&'a tt::Punct> {
71 if let Some(it) = self.at_punct() {
72 self.bump();
73 return Some(it);
74 }
75 None
76 }
77
78 fn eat_ident(&mut self) -> Option<&'a tt::Ident> {
79 if let Some(i) = self.at_ident() {
80 self.bump();
81 return Some(i);
82 }
83 None
84 }
85
86 fn expect_char(&mut self, char: char) -> Option<()> {
87 if self.at_char(char) {
88 self.bump();
89 return Some(());
90 }
91 None
92 }
93}
94
95pub fn parse(tt: &tt::Subtree) -> Option<mbe::MacroRules> { 8pub fn parse(tt: &tt::Subtree) -> Option<mbe::MacroRules> {
96 let mut parser = RulesParser::new(tt); 9 let mut parser = TtCursor::new(tt);
97 let mut rules = Vec::new(); 10 let mut rules = Vec::new();
98 while !parser.is_eof() { 11 while !parser.is_eof() {
99 rules.push(parse_rule(&mut parser)?) 12 rules.push(parse_rule(&mut parser)?)
@@ -101,7 +14,7 @@ pub fn parse(tt: &tt::Subtree) -> Option<mbe::MacroRules> {
101 Some(mbe::MacroRules { rules }) 14 Some(mbe::MacroRules { rules })
102} 15}
103 16
104fn parse_rule(p: &mut RulesParser) -> Option<mbe::Rule> { 17fn parse_rule(p: &mut TtCursor) -> Option<mbe::Rule> {
105 let lhs = parse_subtree(p.eat_subtree()?)?; 18 let lhs = parse_subtree(p.eat_subtree()?)?;
106 p.expect_char('=')?; 19 p.expect_char('=')?;
107 p.expect_char('>')?; 20 p.expect_char('>')?;
@@ -111,7 +24,7 @@ fn parse_rule(p: &mut RulesParser) -> Option<mbe::Rule> {
111 24
112fn parse_subtree(tt: &tt::Subtree) -> Option<mbe::Subtree> { 25fn parse_subtree(tt: &tt::Subtree) -> Option<mbe::Subtree> {
113 let mut token_trees = Vec::new(); 26 let mut token_trees = Vec::new();
114 let mut p = RulesParser::new(tt); 27 let mut p = TtCursor::new(tt);
115 while let Some(tt) = p.eat() { 28 while let Some(tt) = p.eat() {
116 let child: mbe::TokenTree = match tt { 29 let child: mbe::TokenTree = match tt {
117 tt::TokenTree::Leaf(leaf) => match leaf { 30 tt::TokenTree::Leaf(leaf) => match leaf {
@@ -142,7 +55,7 @@ fn parse_subtree(tt: &tt::Subtree) -> Option<mbe::Subtree> {
142 }) 55 })
143} 56}
144 57
145fn parse_var(p: &mut RulesParser) -> Option<mbe::Var> { 58fn parse_var(p: &mut TtCursor) -> Option<mbe::Var> {
146 let ident = p.eat_ident().unwrap(); 59 let ident = p.eat_ident().unwrap();
147 let text = ident.text.clone(); 60 let text = ident.text.clone();
148 let kind = if p.at_char(':') { 61 let kind = if p.at_char(':') {
@@ -150,8 +63,7 @@ fn parse_var(p: &mut RulesParser) -> Option<mbe::Var> {
150 if let Some(ident) = p.eat_ident() { 63 if let Some(ident) = p.eat_ident() {
151 Some(ident.text.clone()) 64 Some(ident.text.clone())
152 } else { 65 } else {
153 // ugly as hell :( 66 p.rev_bump();
154 p.pos -= 1;
155 None 67 None
156 } 68 }
157 } else { 69 } else {
@@ -160,7 +72,7 @@ fn parse_var(p: &mut RulesParser) -> Option<mbe::Var> {
160 Some(mbe::Var { text, kind }) 72 Some(mbe::Var { text, kind })
161} 73}
162 74
163fn parse_repeat(p: &mut RulesParser) -> Option<mbe::Repeat> { 75fn parse_repeat(p: &mut TtCursor) -> Option<mbe::Repeat> {
164 let subtree = p.eat_subtree().unwrap(); 76 let subtree = p.eat_subtree().unwrap();
165 let subtree = parse_subtree(subtree)?; 77 let subtree = parse_subtree(subtree)?;
166 let sep = p.eat_punct()?; 78 let sep = p.eat_punct()?;