diff options
Diffstat (limited to 'src/parser/event_parser/grammar/mod.rs')
-rw-r--r-- | src/parser/event_parser/grammar/mod.rs | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/src/parser/event_parser/grammar/mod.rs b/src/parser/event_parser/grammar/mod.rs index 274c2cdb4..78309aa83 100644 --- a/src/parser/event_parser/grammar/mod.rs +++ b/src/parser/event_parser/grammar/mod.rs | |||
@@ -18,13 +18,13 @@ pub(crate) fn file(p: &mut Parser) { | |||
18 | fn visibility(_: &mut Parser) { | 18 | fn visibility(_: &mut Parser) { |
19 | } | 19 | } |
20 | 20 | ||
21 | fn node_if<F: FnOnce(&mut Parser)>( | 21 | fn node_if<F: FnOnce(&mut Parser), L: Lookahead>( |
22 | p: &mut Parser, | 22 | p: &mut Parser, |
23 | first: SyntaxKind, | 23 | first: L, |
24 | node_kind: SyntaxKind, | 24 | node_kind: SyntaxKind, |
25 | rest: F | 25 | rest: F |
26 | ) -> bool { | 26 | ) -> bool { |
27 | p.current() == first && { node(p, node_kind, |p| { p.bump(); rest(p); }); true } | 27 | first.is_ahead(p) && { node(p, node_kind, |p| { L::consume(p); rest(p); }); true } |
28 | } | 28 | } |
29 | 29 | ||
30 | fn node<F: FnOnce(&mut Parser)>(p: &mut Parser, node_kind: SyntaxKind, rest: F) { | 30 | fn node<F: FnOnce(&mut Parser)>(p: &mut Parser, node_kind: SyntaxKind, rest: F) { |
@@ -99,13 +99,63 @@ impl<'p> Parser<'p> { | |||
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | fn bump_n(&mut self, n: u8) { | ||
103 | for _ in 0..n { | ||
104 | self.bump(); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | fn eat(&mut self, kind: SyntaxKind) -> bool { | 102 | fn eat(&mut self, kind: SyntaxKind) -> bool { |
109 | self.current() == kind && { self.bump(); true } | 103 | self.current() == kind && { self.bump(); true } |
110 | } | 104 | } |
105 | } | ||
106 | |||
107 | trait Lookahead: Copy { | ||
108 | fn is_ahead(self, p: &Parser) -> bool; | ||
109 | fn consume(p: &mut Parser); | ||
110 | } | ||
111 | |||
112 | impl Lookahead for SyntaxKind { | ||
113 | fn is_ahead(self, p: &Parser) -> bool { | ||
114 | p.current() == self | ||
115 | } | ||
116 | |||
117 | fn consume(p: &mut Parser) { | ||
118 | p.bump(); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | impl Lookahead for [SyntaxKind; 2] { | ||
123 | fn is_ahead(self, p: &Parser) -> bool { | ||
124 | p.current() == self[0] | ||
125 | && p.raw_lookahead(1) == self[1] | ||
126 | } | ||
127 | |||
128 | fn consume(p: &mut Parser) { | ||
129 | p.bump(); | ||
130 | p.bump(); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | impl Lookahead for [SyntaxKind; 3] { | ||
135 | fn is_ahead(self, p: &Parser) -> bool { | ||
136 | p.current() == self[0] | ||
137 | && p.raw_lookahead(1) == self[1] | ||
138 | && p.raw_lookahead(2) == self[2] | ||
139 | } | ||
140 | |||
141 | fn consume(p: &mut Parser) { | ||
142 | p.bump(); | ||
143 | p.bump(); | ||
144 | p.bump(); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | #[derive(Clone, Copy)] | ||
149 | struct AnyOf<'a>(&'a [SyntaxKind]); | ||
150 | |||
151 | impl<'a> Lookahead for AnyOf<'a> { | ||
152 | fn is_ahead(self, p: &Parser) -> bool { | ||
153 | let curr = p.current(); | ||
154 | self.0.iter().any(|&k| k == curr) | ||
155 | } | ||
156 | |||
157 | fn consume(p: &mut Parser) { | ||
158 | p.bump(); | ||
159 | } | ||
160 | |||
111 | } \ No newline at end of file | 161 | } \ No newline at end of file |