1use std::cell::Cell;
4
5use drop_bomb::DropBomb;
6
7use crate::{
8 Edition,
9 SyntaxKind::{self, EOF, ERROR, TOMBSTONE},
10 T, TokenSet,
11 event::Event,
12 input::Input,
13};
14
15pub(crate) struct Parser<'t> {
25 inp: &'t Input,
26 pos: usize,
27 events: Vec<Event>,
28 steps: Cell<u32>,
29 edition: Edition,
30}
31
32const PARSER_STEP_LIMIT: usize = 15_000_000;
33
34impl<'t> Parser<'t> {
35 pub(super) fn new(inp: &'t Input, edition: Edition) -> Parser<'t> {
36 Parser { inp, pos: 0, events: Vec::new(), steps: Cell::new(0), edition }
37 }
38
39 pub(crate) fn finish(self) -> Vec<Event> {
40 self.events
41 }
42
43 pub(crate) fn current(&self) -> SyntaxKind {
47 self.nth(0)
48 }
49
50 pub(crate) fn nth(&self, n: usize) -> SyntaxKind {
53 assert!(n <= 3);
54
55 let steps = self.steps.get();
56 assert!((steps as usize) < PARSER_STEP_LIMIT, "the parser seems stuck");
57 self.steps.set(steps + 1);
58
59 self.inp.kind(self.pos + n)
60 }
61
62 pub(crate) fn at(&self, kind: SyntaxKind) -> bool {
64 self.nth_at(0, kind)
65 }
66
67 pub(crate) fn nth_at(&self, n: usize, kind: SyntaxKind) -> bool {
68 match kind {
69 T![-=] => self.at_composite2(n, T![-], T![=]),
70 T![->] => self.at_composite2(n, T![-], T![>]),
71 T![::] => self.at_composite2(n, T![:], T![:]),
72 T![!=] => self.at_composite2(n, T![!], T![=]),
73 T![..] => self.at_composite2(n, T![.], T![.]),
74 T![*=] => self.at_composite2(n, T![*], T![=]),
75 T![/=] => self.at_composite2(n, T![/], T![=]),
76 T![&&] => self.at_composite2(n, T![&], T![&]),
77 T![&=] => self.at_composite2(n, T![&], T![=]),
78 T![%=] => self.at_composite2(n, T![%], T![=]),
79 T![^=] => self.at_composite2(n, T![^], T![=]),
80 T![+=] => self.at_composite2(n, T![+], T![=]),
81 T![<<] => self.at_composite2(n, T![<], T![<]),
82 T![<=] => self.at_composite2(n, T![<], T![=]),
83 T![==] => self.at_composite2(n, T![=], T![=]),
84 T![=>] => self.at_composite2(n, T![=], T![>]),
85 T![>=] => self.at_composite2(n, T![>], T![=]),
86 T![>>] => self.at_composite2(n, T![>], T![>]),
87 T![|=] => self.at_composite2(n, T![|], T![=]),
88 T![||] => self.at_composite2(n, T![|], T![|]),
89
90 T![...] => self.at_composite3(n, T![.], T![.], T![.]),
91 T![..=] => self.at_composite3(n, T![.], T![.], T![=]),
92 T![<<=] => self.at_composite3(n, T![<], T![<], T![=]),
93 T![>>=] => self.at_composite3(n, T![>], T![>], T![=]),
94
95 _ => self.inp.kind(self.pos + n) == kind,
96 }
97 }
98
99 pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool {
101 if !self.at(kind) {
102 return false;
103 }
104 let n_raw_tokens = match kind {
105 T![-=]
106 | T![->]
107 | T![::]
108 | T![!=]
109 | T![..]
110 | T![*=]
111 | T![/=]
112 | T![&&]
113 | T![&=]
114 | T![%=]
115 | T![^=]
116 | T![+=]
117 | T![<<]
118 | T![<=]
119 | T![==]
120 | T![=>]
121 | T![>=]
122 | T![>>]
123 | T![|=]
124 | T![||] => 2,
125
126 T![...] | T![..=] | T![<<=] | T![>>=] => 3,
127 _ => 1,
128 };
129 self.do_bump(kind, n_raw_tokens);
130 true
131 }
132
133 pub(crate) fn eat_contextual_kw(&mut self, kind: SyntaxKind) -> bool {
134 if !self.at_contextual_kw(kind) {
135 return false;
136 }
137 self.bump_remap(kind);
138 true
139 }
140
141 fn at_composite2(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind) -> bool {
142 self.inp.kind(self.pos + n) == k1
143 && self.inp.kind(self.pos + n + 1) == k2
144 && self.inp.is_joint(self.pos + n)
145 }
146
147 fn at_composite3(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind, k3: SyntaxKind) -> bool {
148 self.inp.kind(self.pos + n) == k1
149 && self.inp.kind(self.pos + n + 1) == k2
150 && self.inp.kind(self.pos + n + 2) == k3
151 && self.inp.is_joint(self.pos + n)
152 && self.inp.is_joint(self.pos + n + 1)
153 }
154
155 pub(crate) fn at_ts(&self, kinds: TokenSet) -> bool {
157 kinds.contains(self.current())
158 }
159
160 pub(crate) fn at_contextual_kw(&self, kw: SyntaxKind) -> bool {
162 self.inp.contextual_kind(self.pos) == kw
163 }
164
165 pub(crate) fn nth_at_contextual_kw(&self, n: usize, kw: SyntaxKind) -> bool {
167 self.inp.contextual_kind(self.pos + n) == kw
168 }
169
170 pub(crate) fn start(&mut self) -> Marker {
174 let pos = self.events.len() as u32;
175 self.push_event(Event::tombstone());
176 Marker::new(pos)
177 }
178
179 pub(crate) fn bump(&mut self, kind: SyntaxKind) {
181 assert!(self.eat(kind));
182 }
183
184 pub(crate) fn bump_any(&mut self) {
186 let kind = self.nth(0);
187 if kind == EOF {
188 return;
189 }
190 self.do_bump(kind, 1);
191 }
192
193 pub(crate) fn split_float(&mut self, mut marker: Marker) -> (bool, Marker) {
195 assert!(self.at(SyntaxKind::FLOAT_NUMBER));
196 let ends_in_dot = !self.inp.is_joint(self.pos);
204 if !ends_in_dot {
205 let new_marker = self.start();
206 let idx = marker.pos as usize;
207 match &mut self.events[idx] {
208 Event::Start { forward_parent, kind } => {
209 *kind = SyntaxKind::FIELD_EXPR;
210 *forward_parent = Some(new_marker.pos - marker.pos);
211 }
212 _ => unreachable!(),
213 }
214 marker.bomb.defuse();
215 marker = new_marker;
216 };
217 self.pos += 1;
218 self.push_event(Event::FloatSplitHack { ends_in_dot });
219 (ends_in_dot, marker)
220 }
221
222 pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) {
229 if self.nth(0) == EOF {
230 return;
232 }
233 self.do_bump(kind, 1);
234 }
235
236 pub(crate) fn error<T: Into<String>>(&mut self, message: T) {
241 let msg = message.into();
242 self.push_event(Event::Error { msg });
243 }
244
245 pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool {
248 if self.eat(kind) {
249 return true;
250 }
251 self.error(format!("expected {kind:?}"));
252 false
253 }
254
255 pub(crate) fn err_and_bump(&mut self, message: &str) {
257 self.err_recover(message, TokenSet::EMPTY);
258 }
259
260 pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) -> bool {
264 if matches!(self.current(), T!['{'] | T!['}']) {
265 self.error(message);
266 return true;
267 }
268
269 if self.at_ts(recovery) {
270 self.error(message);
271 return true;
272 }
273
274 let m = self.start();
275 self.error(message);
276 self.bump_any();
277 m.complete(self, ERROR);
278 false
279 }
280
281 fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) {
282 self.pos += n_raw_tokens as usize;
283 self.steps.set(0);
284 self.push_event(Event::Token { kind, n_raw_tokens });
285 }
286
287 fn push_event(&mut self, event: Event) {
288 self.events.push(event);
289 }
290
291 pub(crate) fn edition(&self) -> Edition {
292 self.edition
293 }
294}
295
296pub(crate) struct Marker {
298 pos: u32,
299 bomb: DropBomb,
300}
301
302impl Marker {
303 fn new(pos: u32) -> Marker {
304 Marker { pos, bomb: DropBomb::new("Marker must be either completed or abandoned") }
305 }
306
307 pub(crate) fn complete(mut self, p: &mut Parser<'_>, kind: SyntaxKind) -> CompletedMarker {
311 self.bomb.defuse();
312 let idx = self.pos as usize;
313 match &mut p.events[idx] {
314 Event::Start { kind: slot, .. } => {
315 *slot = kind;
316 }
317 _ => unreachable!(),
318 }
319 p.push_event(Event::Finish);
320 let end_pos = p.events.len() as u32;
321 CompletedMarker::new(self.pos, end_pos, kind)
322 }
323
324 pub(crate) fn abandon(mut self, p: &mut Parser<'_>) {
327 self.bomb.defuse();
328 let idx = self.pos as usize;
329 if idx == p.events.len() - 1 {
330 assert!(matches!(
331 p.events.pop(),
332 Some(Event::Start { kind: TOMBSTONE, forward_parent: None })
333 ));
334 }
335 }
336}
337
338pub(crate) struct CompletedMarker {
339 start_pos: u32,
340 end_pos: u32,
341 kind: SyntaxKind,
342}
343
344impl CompletedMarker {
345 fn new(start_pos: u32, end_pos: u32, kind: SyntaxKind) -> Self {
346 CompletedMarker { start_pos, end_pos, kind }
347 }
348
349 pub(crate) fn precede(self, p: &mut Parser<'_>) -> Marker {
363 let new_pos = p.start();
364 let idx = self.start_pos as usize;
365 match &mut p.events[idx] {
366 Event::Start { forward_parent, .. } => {
367 *forward_parent = Some(new_pos.pos - self.start_pos);
368 }
369 _ => unreachable!(),
370 }
371 new_pos
372 }
373
374 pub(crate) fn extend_to(self, p: &mut Parser<'_>, mut m: Marker) -> CompletedMarker {
376 m.bomb.defuse();
377 let idx = m.pos as usize;
378 match &mut p.events[idx] {
379 Event::Start { forward_parent, .. } => {
380 *forward_parent = Some(self.start_pos - m.pos);
381 }
382 _ => unreachable!(),
383 }
384 self
385 }
386
387 pub(crate) fn kind(&self) -> SyntaxKind {
388 self.kind
389 }
390
391 pub(crate) fn last_token(&self, p: &Parser<'_>) -> Option<SyntaxKind> {
392 let end_pos = self.end_pos as usize;
393 debug_assert_eq!(p.events[end_pos - 1], Event::Finish);
394 p.events[..end_pos].iter().rev().find_map(|event| match event {
395 Event::Token { kind, .. } => Some(*kind),
396 _ => None,
397 })
398 }
399}