1mod control_flow;
2mod expressions;
3mod funcs;
4mod patterns;
5mod statements;
6
7use crate::file::FileId;
8use crate::kind::SyntaxKind;
9use crate::node::SyntaxNode;
10use crate::scanner::Scanner;
11use crate::set::{SyntaxSet, syntax_set};
12use crate::{Lexer, Span, SyntaxError};
13use compose_utils::trace_log;
14use ecow::{EcoString, eco_format};
15use expressions::err_unclosed_delim;
16use std::collections::HashMap;
17use std::ops::{Index, IndexMut, Range};
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24enum ExprContext {
25 Expr,
27
28 AtomicExpr,
32
33 Statement,
37}
38
39impl ExprContext {
40 fn is_expr(&self) -> bool {
45 match self {
46 ExprContext::Expr => true,
47 ExprContext::AtomicExpr => true,
48 ExprContext::Statement => false,
49 }
50 }
51
52 fn is_atomic(&self) -> bool {
57 match self {
58 ExprContext::Expr => false,
59 ExprContext::AtomicExpr => true,
60 ExprContext::Statement => false,
61 }
62 }
63
64 fn to_expr(self) -> ExprContext {
69 match self {
70 ExprContext::Expr => ExprContext::Expr,
71 ExprContext::AtomicExpr => ExprContext::AtomicExpr,
72 ExprContext::Statement => ExprContext::Expr,
73 }
74 }
75}
76
77pub fn parse(text: &str, file_id: FileId) -> Vec<SyntaxNode> {
94 parse_with_offset(text, file_id, 0)
95}
96
97pub fn parse_with_offset(text: &str, file_id: FileId, offset: usize) -> Vec<SyntaxNode> {
115 let mut p = Parser::new(text, offset, file_id);
116
117 statements::code(&mut p, syntax_set!(End));
118
119 p.finish()
120}
121
122impl Index<Marker> for Parser<'_> {
123 type Output = SyntaxNode;
124
125 fn index(&self, index: Marker) -> &Self::Output {
126 &self.nodes[index.0]
127 }
128}
129
130impl IndexMut<Marker> for Parser<'_> {
131 fn index_mut(&mut self, index: Marker) -> &mut Self::Output {
132 &mut self.nodes[index.0]
133 }
134}
135
136#[derive(Debug)]
167pub struct Parser<'s> {
168 text: &'s str,
170
171 lexer: Lexer<'s>,
173
174 pub(crate) token: Token,
176
177 balanced: bool,
179
180 pub(crate) nodes: Vec<SyntaxNode>,
186
187 pub(crate) last_pos: usize,
189
190 memo: MemoArena,
192}
193
194#[derive(Debug, Clone)]
195pub struct CheckPoint {
196 pub(crate) nodes_len: usize,
197 lexer_cursor: usize,
198 token: Token,
199}
200
201pub enum ExpectResult<'a> {
213 Ok,
214 SyntaxError(&'a mut SyntaxError),
215}
216
217impl<'a> ExpectResult<'a> {
218 pub(crate) fn is_ok(&self) -> bool {
219 matches!(self, ExpectResult::Ok)
220 }
221}
222
223impl ExpectResult<'_> {
224 pub fn map(self, f: impl FnOnce(&mut SyntaxError)) -> Self {
228 match self {
229 Self::Ok => self,
230 Self::SyntaxError(err) => {
231 f(err);
232 Self::SyntaxError(err)
233 }
234 }
235 }
236}
237
238impl<'s> Parser<'s> {
240 #[track_caller]
244 pub(crate) fn assert(&mut self, kind: SyntaxKind) {
245 assert_eq!(self.current(), kind, "Expected {:?}", kind);
246 self.eat();
247 }
248
249 pub(crate) fn insert_error_before(
253 &mut self,
254 message: impl Into<EcoString>,
255 ) -> &mut SyntaxError {
256 let (span, text) = match self.last_node() {
257 Some(v) => (v.span().after(), ""),
258 None => (self.token.node.span(), ""),
259 };
260 let error = SyntaxNode::error(SyntaxError::new(message.into(), span), text);
261
262 trace_log!("inserting error: {:?}", error);
263 self.nodes.push(error);
264
265 self.last_err().unwrap()
266 }
267
268 pub(crate) fn insert_error_here(&mut self, message: impl Into<EcoString>) -> &mut SyntaxError {
273 let error = SyntaxNode::error(
274 SyntaxError::new(message.into(), self.token.node.span()),
275 self.token.node.text(),
276 );
277 trace_log!("inserting error: {:?}", error);
278 self.nodes.push(error);
279
280 self.last_err().unwrap()
281 }
282
283 pub(crate) fn insert_error(&mut self, error: SyntaxError) -> &mut SyntaxError {
284 trace_log!("inserting error: {:?}", error);
285 let span = error.span;
286
287 let error = SyntaxNode::error(
288 error,
289 span.range()
290 .and_then(|r| self.get_text(r))
291 .unwrap_or_default(),
292 );
293 self.nodes.push(error);
294
295 self.last_err().unwrap()
296 }
297
298 pub(crate) fn err_at(&mut self, at: Marker) -> Option<&mut SyntaxError> {
300 self.nodes.get_mut(at.0).and_then(|n| n.error_mut())
301 }
302
303 pub fn last_err(&mut self) -> Option<&mut SyntaxError> {
305 self.nodes.iter_mut().rev().find_map(|n| n.error_mut())
306 }
307
308 #[track_caller]
312 pub(crate) fn expected(&mut self, expected: &str) {
313 let kind = self.current();
314 self.insert_error_here(eco_format!("expected {expected}, got {kind:?}"));
315 }
316
317 pub(crate) fn unexpected(
322 &mut self,
323 message: impl Into<EcoString>,
324 recover_set: Option<SyntaxSet>,
325 ) -> &mut SyntaxError {
326 self.balanced &= !self.token.kind.is_grouping();
327 let message = message.into();
328 trace_log!("error_unexpected: {}", message);
329 self.token.node.convert_to_error(match message.as_str() {
330 "" => eco_format!("unexpected token {:?}", self.token.kind),
331 _ => message,
332 });
333
334 let err_marker = self.marker();
335
336 self.eat();
337
338 if let Some(recover_set) = recover_set {
339 self.recover_until(recover_set);
340 }
341
342 self.err_at(err_marker).expect("An error was just inserted")
343 }
344
345 pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool {
349 let at = self.at(kind);
350 if at {
351 self.eat();
352 } else if kind == SyntaxKind::Ident && self.token.kind.is_keyword() {
353 self.token.node.expected(eco_format!("{kind:?}"));
354 } else {
355 self.balanced &= !kind.is_grouping();
356 self.expected(&format!("{kind:?}"));
357 }
358 at
359 }
360
361 pub(crate) fn expect_or_recover(
364 &mut self,
365 expected: SyntaxKind,
366 recover_set: SyntaxSet,
367 ) -> bool {
368 if self.at(expected) {
369 self.eat();
370 return true;
371 }
372
373 self.expected(&format!("{expected:?}"));
374 if self.can_recover_with(recover_set) {
375 self.eat()
376 }
377 false
378 }
379
380 fn can_recover_with(&self, recover_set: SyntaxSet) -> bool {
383 recover_set.contains(self.current())
384 || (recover_set.contains(SyntaxKind::NewLine) && self.had_leading_newline())
385 }
386
387 pub(crate) fn expect_or_recover_until(
392 &mut self,
393 expected: SyntaxKind,
394 message: impl Into<EcoString>,
395 recover_set: SyntaxSet,
396 ) -> ExpectResult {
397 if self.at(expected) {
398 self.eat();
399 return ExpectResult::Ok;
400 }
401
402 self.insert_error_here(message);
403
404 self.recover_until(recover_set);
405 if self.current() == expected {
406 self.eat();
407 }
408 ExpectResult::SyntaxError(self.last_err().expect("An error was just inserted"))
409 }
410
411 pub(crate) fn recover_until(&mut self, recovery_set: SyntaxSet) {
419 while !self.can_recover_with(recovery_set) && !self.end() {
420 self.eat();
421 }
422 }
423
424 pub(crate) fn recover_until_node(&mut self, node: &SyntaxNode) {
426 while !self.end() {
427 if self.token.node.span() == node.span() {
428 break;
429 }
430 self.eat();
431 }
432 }
433
434 #[track_caller]
440 pub(crate) fn expect_closing_delimiter(
441 &mut self,
442 open_marker: Marker,
443 expected_closing: SyntaxKind,
444 ) -> bool {
445 debug_assert!(expected_closing.is_grouping());
446 if self.eat_if(expected_closing) {
447 return true;
448 }
449
450 err_unclosed_delim(self, open_marker, expected_closing);
451
452 false
453 }
454}
455
456#[derive(Debug, Default)]
457struct MemoArena {
458 nodes: Vec<SyntaxNode>,
459 memo_map: HashMap<MemoKey, (Range<usize>, CheckPoint)>,
460}
461
462impl<'s> Parser<'s> {
463 pub(crate) fn new(text: &'s str, offset: usize, file_id: FileId) -> Self {
464 let mut lexer = Lexer::new(text, file_id);
465 lexer.jump(offset);
466
467 let token = Self::lex(&mut lexer);
468
469 Self {
470 text,
471 lexer,
472 token,
473 balanced: true,
474 nodes: vec![],
475 last_pos: 0,
476 memo: Default::default(),
477 }
478 }
479
480 pub fn scanner(&self) -> Scanner<'s> {
481 Scanner::new(self.lexer.clone()).with_offset(self.token.start)
482 }
483
484 pub(crate) fn finish(self) -> Vec<SyntaxNode> {
485 self.nodes
486 }
487
488 fn finish_into(self, kind: SyntaxKind) -> SyntaxNode {
489 assert!(self.end());
490 SyntaxNode::inner(kind, self.finish())
491 }
492
493 #[inline]
494 pub(crate) fn current(&self) -> SyntaxKind {
495 self.token.kind
496 }
497
498 pub(crate) fn last_text(&self) -> &'s str {
499 let Some(last) = self.nodes.last() else {
500 return "";
501 };
502 let Some(range) = last.span().range() else {
503 return "";
504 };
505
506 self.get_text(range).unwrap_or_default()
507 }
508
509 pub(crate) fn last_node(&self) -> Option<&SyntaxNode> {
510 self.nodes.last()
511 }
512
513 pub(crate) fn get_text(&self, range: Range<usize>) -> Option<&'s str> {
514 self.text.get(range)
515 }
516
517 pub(crate) fn current_text(&self) -> &'s str {
518 match self.token.node.span().range() {
519 Some(s) => self.text.get(s).expect("text should exist"),
520 None => &self.text[self.token.start..self.current_end()],
521 }
522 }
523
524 #[inline]
525 pub(crate) fn current_node(&self) -> &SyntaxNode {
526 &self.token.node
527 }
528
529 #[inline]
530 pub(crate) fn current_span(&self) -> Span {
531 self.current_node().span()
532 }
533
534 pub(crate) fn current_end(&self) -> usize {
535 self.lexer.cursor()
536 }
537
538 fn peek(&self) -> SyntaxKind {
540 let (kind, _) = self.lexer.clone().next();
541 kind
542 }
543 pub(crate) fn peeker(&self) -> SyntaxKindIter {
544 SyntaxKindIter::new(self.lexer.clone())
545 }
546
547 pub(crate) fn peek_at(&self, kind: SyntaxKind) -> bool {
548 self.peek() == kind
549 }
550
551 pub(crate) fn peek_at_set(&self, set: SyntaxSet) -> bool {
552 set.contains(self.peek())
553 }
554
555 pub(crate) fn at(&self, kind: SyntaxKind) -> bool {
556 self.current() == kind
557 }
558
559 pub(crate) fn at_set(&self, set: SyntaxSet) -> bool {
560 set.contains(self.current())
561 }
562
563 pub(crate) fn end(&self) -> bool {
564 self.at(SyntaxKind::End)
565 }
566
567 pub(crate) fn marker(&self) -> Marker {
569 Marker(self.nodes.len())
570 }
571
572 fn had_leading_newline(&self) -> bool {
573 self.token.newline
574 }
575
576 pub(crate) fn eat(&mut self) {
577 self.nodes.push(std::mem::take(&mut self.token.node));
578
579 let mut next = Self::lex(&mut self.lexer);
580 while next.kind == SyntaxKind::Error {
581 self.nodes.push(next.node);
582 next = Self::lex(&mut self.lexer)
583 }
584
585 self.token = next;
586 }
587
588 pub(crate) fn eat_if(&mut self, kind: SyntaxKind) -> bool {
589 let at = self.at(kind);
590 if at {
591 self.eat();
592 }
593 at
594 }
595
596 pub(crate) fn skip(&mut self) {
598 self.token = Self::lex(&mut self.lexer);
599 }
600
601 pub(crate) fn skip_if(&mut self, kind: SyntaxKind) -> bool {
604 let at = self.at(kind);
605 if at {
606 self.skip();
607 }
608 at
609 }
610
611 fn convert_and_eat(&mut self, kind: SyntaxKind) {
612 self.token.node.convert_to_kind(kind);
613 self.eat();
614 }
615
616 pub(crate) fn wrap(&mut self, from: Marker, kind: SyntaxKind) {
617 let to = self.marker().0;
618 let from = from.0.min(to);
619
620 let children = self.nodes.drain(from..to).collect();
621 self.nodes.insert(from, SyntaxNode::inner(kind, children))
622 }
623
624 fn lex(lexer: &mut Lexer) -> Token {
625 let prev_end = lexer.cursor();
626 let start = prev_end;
627 let (mut kind, mut node) = lexer.next();
628
629 while kind == SyntaxKind::Comment {
630 (kind, node) = lexer.next();
631 }
632
633 Token {
634 kind,
635 node,
636 newline: lexer.newline(),
637 start,
638 prev_end,
639 }
640 }
641
642 pub(crate) fn checkpoint(&self) -> CheckPoint {
643 trace_log!("Creating checkpoint: {}", self.nodes.len());
644 CheckPoint {
645 nodes_len: self.nodes.len(),
646 lexer_cursor: self.lexer.cursor(),
647 token: self.token.clone(),
648 }
649 }
650
651 pub(crate) fn restore(&mut self, checkpoint: CheckPoint) {
652 trace_log!("Restoring checkpoint: {}", checkpoint.nodes_len);
653 self.nodes.truncate(checkpoint.nodes_len);
654 self.restore_partial(checkpoint);
655 }
656
657 pub(crate) fn restore_partial(&mut self, checkpoint: CheckPoint) {
658 self.lexer.jump(checkpoint.lexer_cursor);
659 self.token = checkpoint.token;
660 }
661
662 pub(crate) fn restore_memo_or_checkpoint(&mut self) -> Option<(MemoKey, CheckPoint)> {
663 let key: MemoKey = self.current_start();
664 match self.memo.memo_map.get(&key).cloned() {
665 Some((range, checkpoint)) => {
666 self.nodes.extend_from_slice(&self.memo.nodes[range]);
668 self.restore_partial(checkpoint);
669 None
670 }
671 None => Some((key, self.checkpoint())),
672 }
673 }
674
675 pub(crate) fn memoize_parsed_nodes(&mut self, key: MemoKey, prev_len: usize) {
676 let prev_memo_len = self.memo.nodes.len();
677
678 self.memo.nodes.extend_from_slice(&self.nodes[prev_len..]);
679 let checkpoint = self.checkpoint();
680 self.memo
681 .memo_map
682 .insert(key, (prev_memo_len..self.memo.nodes.len(), checkpoint));
683 }
684
685 fn current_start(&self) -> MemoKey {
686 self.token.start
687 }
688}
689
690type MemoKey = usize;
691
692#[derive(Debug, Copy, Clone, PartialEq, Eq)]
694pub(crate) struct Marker(pub(crate) usize);
695
696pub(crate) struct SyntaxKindIter<'s> {
697 lexer: Lexer<'s>,
698 yielded_at_end: bool,
699}
700
701impl<'a> SyntaxKindIter<'a> {
702 pub fn new(lexer: Lexer<'a>) -> Self {
703 Self {
704 lexer,
705 yielded_at_end: false,
706 }
707 }
708}
709
710impl<'s> Iterator for SyntaxKindIter<'s> {
711 type Item = SyntaxKind;
712
713 fn next(&mut self) -> Option<Self::Item> {
714 if self.yielded_at_end {
715 return None;
716 }
717 let (kind, _) = self.lexer.next();
718 if kind == SyntaxKind::End {
719 self.yielded_at_end = true;
720 }
721 Some(kind)
722 }
723}
724
725#[derive(Debug, Clone)]
726pub(crate) struct Token {
727 pub(crate) kind: SyntaxKind,
728 pub(crate) node: SyntaxNode,
729 pub(crate) newline: bool,
731
732 pub(crate) start: usize,
733
734 pub(crate) prev_end: usize,
736}