aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/parser.rs')
-rw-r--r--crates/ra_parser/src/parser.rs92
1 files changed, 79 insertions, 13 deletions
diff --git a/crates/ra_parser/src/parser.rs b/crates/ra_parser/src/parser.rs
index 3cb57ed9c..71f1f8b30 100644
--- a/crates/ra_parser/src/parser.rs
+++ b/crates/ra_parser/src/parser.rs
@@ -45,8 +45,9 @@ impl<'t> Parser<'t> {
45 /// 45 ///
46 /// Useful for parsing things like `>>`. 46 /// Useful for parsing things like `>>`.
47 pub(crate) fn current2(&self) -> Option<(SyntaxKind, SyntaxKind)> { 47 pub(crate) fn current2(&self) -> Option<(SyntaxKind, SyntaxKind)> {
48 let c1 = self.token_source.token_kind(self.token_pos); 48 let c1 = self.nth(0);
49 let c2 = self.token_source.token_kind(self.token_pos + 1); 49 let c2 = self.nth(1);
50
50 if self.token_source.is_token_joint_to_next(self.token_pos) { 51 if self.token_source.is_token_joint_to_next(self.token_pos) {
51 Some((c1, c2)) 52 Some((c1, c2))
52 } else { 53 } else {
@@ -59,9 +60,9 @@ impl<'t> Parser<'t> {
59 /// 60 ///
60 /// Useful for parsing things like `=>>`. 61 /// Useful for parsing things like `=>>`.
61 pub(crate) fn current3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> { 62 pub(crate) fn current3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> {
62 let c1 = self.token_source.token_kind(self.token_pos); 63 let c1 = self.nth(0);
63 let c2 = self.token_source.token_kind(self.token_pos + 1); 64 let c2 = self.nth(1);
64 let c3 = self.token_source.token_kind(self.token_pos + 2); 65 let c3 = self.nth(2);
65 if self.token_source.is_token_joint_to_next(self.token_pos) 66 if self.token_source.is_token_joint_to_next(self.token_pos)
66 && self.token_source.is_token_joint_to_next(self.token_pos + 1) 67 && self.token_source.is_token_joint_to_next(self.token_pos + 1)
67 { 68 {
@@ -77,7 +78,23 @@ impl<'t> Parser<'t> {
77 let steps = self.steps.get(); 78 let steps = self.steps.get();
78 assert!(steps <= 10_000_000, "the parser seems stuck"); 79 assert!(steps <= 10_000_000, "the parser seems stuck");
79 self.steps.set(steps + 1); 80 self.steps.set(steps + 1);
80 self.token_source.token_kind(self.token_pos + n) 81
82 // It is beecause the Dollar will appear between nth
83 // Following code skips through it
84 let mut non_dollars_count = 0;
85 let mut i = 0;
86
87 loop {
88 let kind = self.token_source.token_kind(self.token_pos + i);
89 i += 1;
90
91 match kind {
92 EOF => return EOF,
93 SyntaxKind::L_DOLLAR | SyntaxKind::R_DOLLAR => {}
94 _ if non_dollars_count == n => return kind,
95 _ => non_dollars_count += 1,
96 }
97 }
81 } 98 }
82 99
83 /// Checks if the current token is `kind`. 100 /// Checks if the current token is `kind`.
@@ -99,8 +116,6 @@ impl<'t> Parser<'t> {
99 /// consumed between the `start` and the corresponding `Marker::complete` 116 /// consumed between the `start` and the corresponding `Marker::complete`
100 /// belong to the same node. 117 /// belong to the same node.
101 pub(crate) fn start(&mut self) -> Marker { 118 pub(crate) fn start(&mut self) -> Marker {
102 self.eat_dollars();
103
104 let pos = self.events.len() as u32; 119 let pos = self.events.len() as u32;
105 self.push_event(Event::tombstone()); 120 self.push_event(Event::tombstone());
106 Marker::new(pos) 121 Marker::new(pos)
@@ -185,7 +200,6 @@ impl<'t> Parser<'t> {
185 self.eat_dollars(); 200 self.eat_dollars();
186 self.token_pos += usize::from(n_raw_tokens); 201 self.token_pos += usize::from(n_raw_tokens);
187 self.push_event(Event::Token { kind, n_raw_tokens }); 202 self.push_event(Event::Token { kind, n_raw_tokens });
188 self.eat_dollars();
189 } 203 }
190 204
191 fn push_event(&mut self, event: Event) { 205 fn push_event(&mut self, event: Event) {
@@ -193,12 +207,64 @@ impl<'t> Parser<'t> {
193 } 207 }
194 208
195 fn eat_dollars(&mut self) { 209 fn eat_dollars(&mut self) {
196 while self.nth(0) == SyntaxKind::L_DOLLAR || self.nth(0) == SyntaxKind::R_DOLLAR { 210 loop {
197 let kind = self.nth(0); 211 match self.token_source.token_kind(self.token_pos) {
198 self.token_pos += 1; 212 k @ SyntaxKind::L_DOLLAR | k @ SyntaxKind::R_DOLLAR => {
199 self.push_event(Event::Token { kind, n_raw_tokens: 1 }); 213 self.token_pos += 1;
214 self.push_event(Event::Token { kind: k, n_raw_tokens: 1 });
215 }
216 _ => {
217 return;
218 }
219 }
220 }
221 }
222
223 pub(crate) fn eat_l_dollars(&mut self) -> usize {
224 let mut ate_count = 0;
225 loop {
226 match self.token_source.token_kind(self.token_pos) {
227 k @ SyntaxKind::L_DOLLAR => {
228 self.token_pos += 1;
229 self.push_event(Event::Token { kind: k, n_raw_tokens: 1 });
230 ate_count += 1;
231 }
232 _ => {
233 return ate_count;
234 }
235 }
200 } 236 }
201 } 237 }
238
239 pub(crate) fn eat_r_dollars(&mut self, max_count: usize) -> usize {
240 let mut ate_count = 0;
241 loop {
242 match self.token_source.token_kind(self.token_pos) {
243 k @ SyntaxKind::R_DOLLAR => {
244 self.token_pos += 1;
245 self.push_event(Event::Token { kind: k, n_raw_tokens: 1 });
246 ate_count += 1;
247
248 if max_count >= ate_count {
249 return ate_count;
250 }
251 }
252 _ => {
253 return ate_count;
254 }
255 }
256 }
257 }
258
259 pub(crate) fn at_l_dollar(&self) -> bool {
260 let kind = self.token_source.token_kind(self.token_pos);
261 (kind == SyntaxKind::L_DOLLAR)
262 }
263
264 pub(crate) fn at_r_dollar(&self) -> bool {
265 let kind = self.token_source.token_kind(self.token_pos);
266 (kind == SyntaxKind::R_DOLLAR)
267 }
202} 268}
203 269
204/// See `Parser::start`. 270/// See `Parser::start`.