arrow_parser/
parse.rs

1use super::error::SyntaxError;
2use super::error::SyntaxErrorType;
3use super::error::SyntaxResult;
4use super::lex::lex_next;
5use super::lex::Lexer;
6use super::lex::LexerCheckpoint;
7use super::source::SourceRange;
8use super::token::Token;
9use super::token::TokenType;
10use crate::ast::Expression;
11use crate::ast::ModuleItem;
12use crate::ast::Node;
13use crate::ast::Statement;
14use crate::symbol::Scope;
15use crate::symbol::ScopeType;
16
17#[must_use]
18pub struct MaybeToken {
19  typ: TokenType,
20  range: SourceRange,
21  matched: bool,
22}
23
24impl MaybeToken {
25  pub fn is_match(&self) -> bool {
26    self.matched
27  }
28
29  pub fn match_loc(&self) -> Option<SourceRange> {
30    if self.matched {
31      Some(self.range)
32    } else {
33      None
34    }
35  }
36
37  pub fn error(&self, err: SyntaxErrorType) -> SyntaxError {
38    debug_assert!(!self.matched);
39    SyntaxError::from_loc(self.range, err, Some(self.typ))
40  }
41
42  pub fn and_then<R, F: FnOnce() -> SyntaxResult<R>>(self, f: F) -> SyntaxResult<Option<R>> {
43    Ok(if self.matched { Some(f()?) } else { None })
44  }
45}
46
47pub struct ParserCheckpoint {
48  checkpoint: LexerCheckpoint,
49}
50
51pub struct Parser<'a> {
52  lexer: Lexer<'a>,
53  pub(crate) scope: Scope, // The current scope, which will be changed while parsing. It's a field instead of passed via method args to avoid having to propagate that to every method.
54}
55
56impl<'a> Parser<'a> {
57  pub fn new(lexer: Lexer<'a>, root_scope: Scope) -> Parser<'a> {
58    Parser {
59      lexer,
60      scope: root_scope,
61    }
62  }
63
64  // Creates a new scope as a child of the current one and updates the current scope reference to it, returning the old scope.
65  pub fn enter_new_scope(&mut self, typ: ScopeType) -> Scope {
66    let old = self.scope.clone();
67    let new = old.new_child(typ);
68    self.scope = new;
69    old
70  }
71
72  pub fn return_to_scope(&mut self, old: Scope) {
73    self.scope = old;
74  }
75
76  pub fn new_expression(&self, loc: SourceRange, expr: Expression) -> Node<Expression> {
77    Node {
78      loc,
79      stx: Box::new(expr),
80      scope: self.scope.clone(),
81    }
82  }
83
84  pub fn new_statement(&self, loc: SourceRange, stmt: Statement) -> Node<Statement> {
85    Node {
86      loc,
87      stx: Box::new(stmt),
88      scope: self.scope.clone(),
89    }
90  }
91
92  pub fn new_module_item(&self, loc: SourceRange, item: ModuleItem) -> Node<ModuleItem> {
93    Node {
94      loc,
95      stx: Box::new(item),
96      scope: self.scope.clone(),
97    }
98  }
99
100  pub fn lexer_mut(&mut self) -> &mut Lexer<'a> {
101    &mut self.lexer
102  }
103
104  pub fn source(&self, range: SourceRange) -> &[u8] {
105    &self.lexer[range]
106  }
107
108  pub fn source_as_string(&self, range: SourceRange) -> String {
109    unsafe { String::from_utf8_unchecked(self.source(range).to_vec()) }
110  }
111
112  pub fn source_range(&self) -> SourceRange {
113    self.lexer.source_range()
114  }
115
116  pub fn checkpoint(&self) -> ParserCheckpoint {
117    ParserCheckpoint {
118      checkpoint: self.lexer.checkpoint(),
119    }
120  }
121
122  pub fn since_checkpoint(&self, checkpoint: ParserCheckpoint) -> SourceRange {
123    self.lexer.since_checkpoint(checkpoint.checkpoint)
124  }
125
126  pub fn restore_checkpoint(&mut self, checkpoint: ParserCheckpoint) -> () {
127    self.lexer.apply_checkpoint(checkpoint.checkpoint);
128  }
129
130  fn forward<K: FnOnce(&Token) -> bool>(&mut self, keep: K) -> SyntaxResult<(bool, Token)> {
131    let cp = self.checkpoint();
132    let t = lex_next(&mut self.lexer)?;
133    let k = keep(&t);
134    if !k {
135      self.restore_checkpoint(cp);
136    };
137    Ok((k, t))
138  }
139
140  pub fn peek(&mut self) -> SyntaxResult<Token> {
141    self.forward(|_| false).map(|r| r.1)
142  }
143
144  pub fn consume(&mut self) -> SyntaxResult<Token> {
145    self.forward(|_| true).map(|r| r.1)
146  }
147
148  pub fn consume_if_pred<F: FnOnce(&Token) -> bool>(
149    &mut self,
150    pred: F,
151  ) -> SyntaxResult<MaybeToken> {
152    let (matched, t) = self.forward(pred)?;
153    Ok(MaybeToken {
154      typ: t.typ,
155      matched,
156      range: t.loc,
157    })
158  }
159
160  pub fn consume_if(&mut self, typ: TokenType) -> SyntaxResult<MaybeToken> {
161    self.consume_if_pred(|t| t.typ == typ)
162  }
163
164  pub fn require_predicate<P: FnOnce(TokenType) -> bool>(
165    &mut self,
166    pred: P,
167    expected: &'static str,
168  ) -> SyntaxResult<Token> {
169    let t = self.consume()?;
170    if !pred(t.typ) {
171      Err(t.error(SyntaxErrorType::ExpectedSyntax(expected)))
172    } else {
173      Ok(t)
174    }
175  }
176
177  pub fn require(&mut self, typ: TokenType) -> SyntaxResult<Token> {
178    let t = self.consume()?;
179    if t.typ != typ {
180      Err(t.error(SyntaxErrorType::RequiredTokenNotFound(typ)))
181    } else {
182      Ok(t)
183    }
184  }
185
186  pub fn require_identifier_as_string(&mut self) -> SyntaxResult<(SourceRange, String)> {
187    let loc = self.require(TokenType::Identifier)?.loc;
188    Ok((loc, self.source_as_string(loc)))
189  }
190}