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.rs90
1 files changed, 84 insertions, 6 deletions
diff --git a/crates/ra_parser/src/parser.rs b/crates/ra_parser/src/parser.rs
index 56f8b7126..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`.
@@ -180,6 +197,7 @@ impl<'t> Parser<'t> {
180 } 197 }
181 198
182 fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) { 199 fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) {
200 self.eat_dollars();
183 self.token_pos += usize::from(n_raw_tokens); 201 self.token_pos += usize::from(n_raw_tokens);
184 self.push_event(Event::Token { kind, n_raw_tokens }); 202 self.push_event(Event::Token { kind, n_raw_tokens });
185 } 203 }
@@ -187,6 +205,66 @@ impl<'t> Parser<'t> {
187 fn push_event(&mut self, event: Event) { 205 fn push_event(&mut self, event: Event) {
188 self.events.push(event) 206 self.events.push(event)
189 } 207 }
208
209 fn eat_dollars(&mut self) {
210 loop {
211 match self.token_source.token_kind(self.token_pos) {
212 k @ SyntaxKind::L_DOLLAR | k @ SyntaxKind::R_DOLLAR => {
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 }
236 }
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 }
190} 268}
191 269
192/// See `Parser::start`. 270/// See `Parser::start`.