Skip to main content

hawdb_sql_syntax/
parser.rs

1// Copyright 2026 Nowledge
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::{
16    tokenize, ExpressionSyntax, GraphEdgeDirection, GraphEdgePatternSyntax,
17    GraphElementPatternSyntax, GraphPathFactorSyntax, GraphPathPrimarySyntax, GraphPathSyntax,
18    GraphPatternQuantifier, GraphPatternSyntax, GraphTable, GraphTableColumn, Identifier,
19    LabeledExpressionSyntax, PgqStatement, PostgresSelectSyntax, PostgresStatementSyntax,
20    QualifiedName, Span, SyntaxError, SyntaxErrorCode, TableAlias, Token, TokenKind,
21};
22
23mod expression;
24mod property_graph;
25mod select;
26
27pub fn parse_postgres_statement(input: &str) -> Result<PostgresStatementSyntax, SyntaxError> {
28    let tokens = tokenize(input)?;
29    let mut parser = Parser::new(input, &tokens);
30    let statement = if parser.at_keyword("CREATE") {
31        PostgresStatementSyntax::CreatePropertyGraph(parser.parse_create_property_graph()?)
32    } else if parser.at_keyword("SELECT") {
33        PostgresStatementSyntax::Select(Box::new(parser.parse_postgres_select()?))
34    } else {
35        return Err(parser.unexpected("CREATE PROPERTY GRAPH or SELECT"));
36    };
37    parser.consume_kind(TokenKind::Semicolon);
38    parser.expect_kind(TokenKind::End, "end of statement")?;
39    Ok(statement)
40}
41
42pub fn parse_postgres_select(input: &str) -> Result<PostgresSelectSyntax, SyntaxError> {
43    let tokens = tokenize(input)?;
44    let mut parser = Parser::new(input, &tokens);
45    let select = parser.parse_postgres_select()?;
46    parser.consume_kind(TokenKind::Semicolon);
47    parser.expect_kind(TokenKind::End, "end of SELECT")?;
48    Ok(select)
49}
50
51pub fn parse_pgq_statement(input: &str) -> Result<PgqStatement, SyntaxError> {
52    let tokens = tokenize(input)?;
53    let mut parser = Parser::new(input, &tokens);
54    let statement = if parser.at_keyword("CREATE") {
55        PgqStatement::CreatePropertyGraph(parser.parse_create_property_graph()?)
56    } else {
57        return Err(parser.unexpected("CREATE PROPERTY GRAPH"));
58    };
59    parser.consume_kind(TokenKind::Semicolon);
60    parser.expect_kind(TokenKind::End, "end of statement")?;
61    Ok(statement)
62}
63
64pub fn parse_graph_table(input: &str) -> Result<GraphTable, SyntaxError> {
65    let tokens = tokenize(input)?;
66    let mut parser = Parser::new(input, &tokens);
67    let table = parser.parse_graph_table()?;
68    parser.consume_kind(TokenKind::Semicolon);
69    parser.expect_kind(TokenKind::End, "end of GRAPH_TABLE clause")?;
70    Ok(table)
71}
72
73const MAX_GRAPH_PATTERN_NESTING: usize = 128;
74const MAX_EXPRESSION_NESTING: usize = 128;
75
76struct Parser<'a> {
77    input: &'a str,
78    tokens: &'a [Token],
79    position: usize,
80    graph_pattern_nesting: usize,
81}
82
83struct ParsedGraphElementFields {
84    variable: Option<Identifier>,
85    labels: Vec<Identifier>,
86    predicate: Option<ExpressionSyntax>,
87}
88
89impl<'a> Parser<'a> {
90    fn new(input: &'a str, tokens: &'a [Token]) -> Self {
91        Self {
92            input,
93            tokens,
94            position: 0,
95            graph_pattern_nesting: 0,
96        }
97    }
98
99    fn parse_identifier_list(&mut self) -> Result<Vec<Identifier>, SyntaxError> {
100        self.expect_kind(TokenKind::LeftParen, "(")?;
101        let identifiers = self.parse_nonempty_comma_separated(
102            TokenKind::RightParen,
103            Self::parse_identifier,
104            "at least one identifier",
105        )?;
106        self.expect_kind(TokenKind::RightParen, ")")?;
107        Ok(identifiers)
108    }
109
110    fn parse_labeled_expressions(
111        &mut self,
112        expected: &'static str,
113    ) -> Result<Vec<LabeledExpressionSyntax>, SyntaxError> {
114        if self.current().kind == TokenKind::RightParen {
115            return Err(self.unexpected(expected));
116        }
117        let mut expressions = Vec::new();
118        loop {
119            let start_position = self.position;
120            let end_position = self.scan_to_top_level_delimiter()?;
121            expressions.push(self.labeled_expression_from_range(start_position, end_position)?);
122            if !self.consume_kind(TokenKind::Comma) {
123                break;
124            }
125        }
126        Ok(expressions)
127    }
128
129    fn parse_graph_table(&mut self) -> Result<GraphTable, SyntaxError> {
130        let start = self.expect_keyword("GRAPH_TABLE")?.span.start;
131        self.expect_kind(TokenKind::LeftParen, "(")?;
132        let graph = self.parse_qualified_name()?;
133        self.expect_keyword("MATCH")?;
134        let pattern = self.parse_graph_pattern()?;
135        self.expect_keyword("COLUMNS")?;
136
137        self.expect_kind(TokenKind::LeftParen, "(")?;
138        let columns = self.parse_graph_table_columns()?;
139        self.expect_kind(TokenKind::RightParen, ")")?;
140        self.expect_kind(TokenKind::RightParen, ")")?;
141        let alias = self.parse_optional_table_alias()?;
142
143        Ok(GraphTable {
144            graph,
145            pattern,
146            columns,
147            alias,
148            span: Span::new(start, self.previous_end()),
149        })
150    }
151
152    fn parse_graph_pattern(&mut self) -> Result<GraphPatternSyntax, SyntaxError> {
153        let start = self.current().span.start;
154        let mut paths = vec![self.parse_graph_path()?];
155        while self.consume_kind(TokenKind::Comma) {
156            paths.push(self.parse_graph_path()?);
157        }
158        let predicate = if self.consume_keyword("WHERE") {
159            Some(self.parse_expression_until_keyword("COLUMNS", "an expression after WHERE")?)
160        } else {
161            None
162        };
163        let end = predicate.as_ref().map_or_else(
164            || paths.last().expect("graph path exists").span.end,
165            |value| value.span.end,
166        );
167        Ok(GraphPatternSyntax {
168            paths,
169            predicate,
170            span: Span::new(start, end),
171        })
172    }
173
174    fn parse_graph_path(&mut self) -> Result<GraphPathSyntax, SyntaxError> {
175        let start = self.current().span.start;
176        let mut factors = Vec::new();
177        while self.can_start_graph_primary() {
178            factors.push(self.parse_graph_path_factor()?);
179        }
180        if factors.is_empty() {
181            return Err(self.unexpected("a graph path pattern"));
182        }
183        Ok(GraphPathSyntax {
184            span: Span::new(start, self.previous_end()),
185            factors,
186        })
187    }
188
189    fn parse_graph_path_factor(&mut self) -> Result<GraphPathFactorSyntax, SyntaxError> {
190        let start = self.current().span.start;
191        let primary = self.parse_graph_path_primary()?;
192        let quantifier = self.parse_optional_graph_quantifier()?;
193        Ok(GraphPathFactorSyntax {
194            primary,
195            quantifier,
196            span: Span::new(start, self.previous_end()),
197        })
198    }
199
200    fn parse_graph_path_primary(&mut self) -> Result<GraphPathPrimarySyntax, SyntaxError> {
201        if self.current().kind == TokenKind::LeftParen {
202            return self.parse_parenthesized_or_vertex_pattern();
203        }
204        self.parse_graph_edge_pattern()
205            .map(GraphPathPrimarySyntax::Edge)
206    }
207
208    fn parse_parenthesized_or_vertex_pattern(
209        &mut self,
210    ) -> Result<GraphPathPrimarySyntax, SyntaxError> {
211        let start = self.expect_kind(TokenKind::LeftParen, "(")?.span.start;
212        if self.can_start_graph_primary() {
213            if self.graph_pattern_nesting >= MAX_GRAPH_PATTERN_NESTING {
214                return Err(SyntaxError::new(
215                    SyntaxErrorCode::GraphPatternNestingLimitExceeded,
216                    Span::new(start, self.current().span.end),
217                ));
218            }
219            self.graph_pattern_nesting += 1;
220            let nested = self.parse_nested_graph_path(start);
221            self.graph_pattern_nesting -= 1;
222            return nested;
223        }
224
225        let fields = self.parse_graph_element_fields(TokenKind::RightParen)?;
226        self.expect_kind(TokenKind::RightParen, ")")?;
227        Ok(GraphPathPrimarySyntax::Vertex(GraphElementPatternSyntax {
228            variable: fields.variable,
229            labels: fields.labels,
230            predicate: fields.predicate,
231            span: Span::new(start, self.previous_end()),
232        }))
233    }
234
235    fn parse_nested_graph_path(
236        &mut self,
237        start: usize,
238    ) -> Result<GraphPathPrimarySyntax, SyntaxError> {
239        let path = Box::new(self.parse_graph_path()?);
240        let predicate =
241            if self.consume_keyword("WHERE") {
242                Some(self.parse_expression_until_kind(
243                    TokenKind::RightParen,
244                    "an expression after WHERE",
245                )?)
246            } else {
247                None
248            };
249        self.expect_kind(TokenKind::RightParen, ")")?;
250        Ok(GraphPathPrimarySyntax::Parenthesized {
251            path,
252            predicate,
253            span: Span::new(start, self.previous_end()),
254        })
255    }
256
257    fn parse_graph_edge_pattern(&mut self) -> Result<GraphEdgePatternSyntax, SyntaxError> {
258        let start = self.current().span.start;
259        match self.current().kind {
260            TokenKind::ArrowLeft => {
261                self.advance();
262                self.parse_left_edge_tail(start)
263            }
264            TokenKind::Less => {
265                self.advance();
266                self.expect_kind(TokenKind::Minus, "- after <")?;
267                self.parse_left_edge_tail(start)
268            }
269            TokenKind::ArrowRight => {
270                self.advance();
271                Ok(self.abbreviated_edge(start, GraphEdgeDirection::Right))
272            }
273            TokenKind::Minus => {
274                self.advance();
275                if self.consume_kind(TokenKind::LeftBracket) {
276                    let fields = self.parse_graph_element_fields(TokenKind::RightBracket)?;
277                    self.expect_kind(TokenKind::RightBracket, "]")?;
278                    let direction = if self.consume_kind(TokenKind::ArrowRight) {
279                        GraphEdgeDirection::Right
280                    } else {
281                        self.expect_kind(TokenKind::Minus, "- or -> after edge pattern")?;
282                        if self.consume_kind(TokenKind::Greater) {
283                            GraphEdgeDirection::Right
284                        } else {
285                            GraphEdgeDirection::Any
286                        }
287                    };
288                    Ok(GraphEdgePatternSyntax {
289                        direction,
290                        variable: fields.variable,
291                        labels: fields.labels,
292                        predicate: fields.predicate,
293                        abbreviated: false,
294                        span: Span::new(start, self.previous_end()),
295                    })
296                } else {
297                    let direction = if self.consume_kind(TokenKind::Greater) {
298                        GraphEdgeDirection::Right
299                    } else {
300                        GraphEdgeDirection::Any
301                    };
302                    Ok(self.abbreviated_edge(start, direction))
303                }
304            }
305            _ => Err(self.unexpected("a graph vertex or edge pattern")),
306        }
307    }
308
309    fn parse_left_edge_tail(
310        &mut self,
311        start: usize,
312    ) -> Result<GraphEdgePatternSyntax, SyntaxError> {
313        if !self.consume_kind(TokenKind::LeftBracket) {
314            return Ok(self.abbreviated_edge(start, GraphEdgeDirection::Left));
315        }
316        let fields = self.parse_graph_element_fields(TokenKind::RightBracket)?;
317        self.expect_kind(TokenKind::RightBracket, "]")?;
318        self.expect_kind(TokenKind::Minus, "- after left edge pattern")?;
319        Ok(GraphEdgePatternSyntax {
320            direction: GraphEdgeDirection::Left,
321            variable: fields.variable,
322            labels: fields.labels,
323            predicate: fields.predicate,
324            abbreviated: false,
325            span: Span::new(start, self.previous_end()),
326        })
327    }
328
329    fn abbreviated_edge(
330        &self,
331        start: usize,
332        direction: GraphEdgeDirection,
333    ) -> GraphEdgePatternSyntax {
334        GraphEdgePatternSyntax {
335            direction,
336            variable: None,
337            labels: Vec::new(),
338            predicate: None,
339            abbreviated: true,
340            span: Span::new(start, self.previous_end()),
341        }
342    }
343
344    fn parse_graph_element_fields(
345        &mut self,
346        terminator: TokenKind,
347    ) -> Result<ParsedGraphElementFields, SyntaxError> {
348        let variable = if is_identifier_kind(self.current().kind)
349            && !self.at_keyword("IS")
350            && !self.at_keyword("WHERE")
351        {
352            Some(self.parse_identifier()?)
353        } else {
354            None
355        };
356        let labels = if self.consume_keyword("IS") {
357            let mut labels = vec![self.parse_identifier()?];
358            while self.consume_kind(TokenKind::Pipe) {
359                labels.push(self.parse_identifier()?);
360            }
361            labels
362        } else {
363            Vec::new()
364        };
365        let predicate = if self.consume_keyword("WHERE") {
366            Some(self.parse_expression_until_kind(terminator, "an expression after WHERE")?)
367        } else {
368            None
369        };
370        Ok(ParsedGraphElementFields {
371            variable,
372            labels,
373            predicate,
374        })
375    }
376
377    fn parse_optional_graph_quantifier(
378        &mut self,
379    ) -> Result<Option<GraphPatternQuantifier>, SyntaxError> {
380        if !self.consume_kind(TokenKind::LeftBrace) {
381            return Ok(None);
382        }
383        let start = self.tokens[self.position - 1].span.start;
384        let (min, max) = if self.consume_kind(TokenKind::Comma) {
385            (0, self.parse_nonnegative_integer()?)
386        } else {
387            let min = self.parse_nonnegative_integer()?;
388            if self.consume_kind(TokenKind::RightBrace) {
389                return Ok(Some(GraphPatternQuantifier {
390                    min,
391                    max: min,
392                    span: Span::new(start, self.previous_end()),
393                }));
394            }
395            self.expect_kind(TokenKind::Comma, ", or } in graph pattern quantifier")?;
396            (min, self.parse_nonnegative_integer()?)
397        };
398        self.expect_kind(TokenKind::RightBrace, "}")?;
399        Ok(Some(GraphPatternQuantifier {
400            min,
401            max,
402            span: Span::new(start, self.previous_end()),
403        }))
404    }
405
406    fn parse_nonnegative_integer(&mut self) -> Result<u32, SyntaxError> {
407        let token = self.current();
408        if token.kind != TokenKind::Number {
409            return Err(self.unexpected("a non-negative integer"));
410        }
411        let value = token
412            .text(self.input)
413            .parse::<u32>()
414            .map_err(|_| self.unexpected("a non-negative integer"))?;
415        self.advance();
416        Ok(value)
417    }
418
419    fn can_start_graph_primary(&self) -> bool {
420        matches!(
421            self.current().kind,
422            TokenKind::LeftParen
423                | TokenKind::ArrowLeft
424                | TokenKind::ArrowRight
425                | TokenKind::Less
426                | TokenKind::Minus
427        )
428    }
429
430    fn parse_graph_table_columns(&mut self) -> Result<Vec<GraphTableColumn>, SyntaxError> {
431        if self.current().kind == TokenKind::RightParen {
432            return Err(self.unexpected("at least one GRAPH_TABLE column"));
433        }
434        let mut columns = Vec::new();
435        loop {
436            let start_position = self.position;
437            let end_position = self.scan_to_top_level_delimiter()?;
438            columns.push(self.graph_table_column_from_range(start_position, end_position)?);
439            if !self.consume_kind(TokenKind::Comma) {
440                break;
441            }
442        }
443        Ok(columns)
444    }
445
446    fn graph_table_column_from_range(
447        &self,
448        start_position: usize,
449        end_position: usize,
450    ) -> Result<GraphTableColumn, SyntaxError> {
451        let expression = self.labeled_expression_from_range(start_position, end_position)?;
452        Ok(GraphTableColumn {
453            expression: expression.expression,
454            alias: expression.alias,
455            span: expression.span,
456        })
457    }
458
459    fn labeled_expression_from_range(
460        &self,
461        start_position: usize,
462        end_position: usize,
463    ) -> Result<LabeledExpressionSyntax, SyntaxError> {
464        if start_position == end_position {
465            return Err(self.unexpected("an expression"));
466        }
467        let mut alias_position = None;
468        let mut depths = Depths::default();
469        for position in start_position..end_position {
470            let token = self.tokens[position];
471            self.update_expression_depths(&mut depths, token)?;
472            if depths.is_zero() && token.is_keyword(self.input, "AS") {
473                alias_position = Some(position);
474            }
475        }
476        let (expression_end_position, alias) = if let Some(as_position) = alias_position {
477            let alias_token = self.tokens.get(as_position + 1).copied().ok_or_else(|| {
478                SyntaxError::new(SyntaxErrorCode::UnexpectedEnd, self.current().span)
479                    .expected("a GRAPH_TABLE column alias")
480            })?;
481            if as_position + 2 != end_position || !is_identifier_kind(alias_token.kind) {
482                return Err(
483                    SyntaxError::new(SyntaxErrorCode::UnexpectedToken, alias_token.span)
484                        .expected("one column alias after AS")
485                        .found(alias_token.text(self.input)),
486                );
487            }
488            (as_position, Some(identifier_from_token(alias_token)))
489        } else {
490            (end_position, None)
491        };
492        let start = self.tokens[start_position].span.start;
493        let end = self.tokens[end_position - 1].span.end;
494        if start_position == expression_end_position {
495            return Err(
496                SyntaxError::new(SyntaxErrorCode::UnexpectedToken, Span::new(start, end))
497                    .expected("an expression before AS"),
498            );
499        }
500        Ok(LabeledExpressionSyntax {
501            expression: self.parse_expression_range(start_position, expression_end_position)?,
502            alias,
503            span: Span::new(start, end),
504        })
505    }
506
507    fn parse_optional_table_alias(&mut self) -> Result<Option<TableAlias>, SyntaxError> {
508        let has_as = self.consume_keyword("AS");
509        if !has_as && (!is_identifier_kind(self.current().kind) || self.at_table_alias_boundary()) {
510            return Ok(None);
511        }
512        if has_as && self.at_table_alias_boundary() {
513            return Err(self.unexpected("a table alias"));
514        }
515        let start = self.current().span.start;
516        let name = self.parse_identifier()?;
517        let columns = if self.current().kind == TokenKind::LeftParen {
518            self.parse_identifier_list()?
519        } else {
520            Vec::new()
521        };
522        Ok(Some(TableAlias {
523            name,
524            columns,
525            span: Span::new(start, self.previous_end()),
526        }))
527    }
528
529    fn at_table_alias_boundary(&self) -> bool {
530        matches!(
531            self.current().kind,
532            TokenKind::Comma | TokenKind::RightParen | TokenKind::Semicolon | TokenKind::End
533        ) || [
534            "WHERE",
535            "GROUP",
536            "HAVING",
537            "ORDER",
538            "LIMIT",
539            "OFFSET",
540            "FETCH",
541            "FOR",
542            "JOIN",
543            "INNER",
544            "LEFT",
545            "RIGHT",
546            "FULL",
547            "CROSS",
548            "ON",
549            "USING",
550            "NATURAL",
551            "UNION",
552            "EXCEPT",
553            "INTERSECT",
554            "LATERAL",
555            "TABLESAMPLE",
556            "WINDOW",
557        ]
558        .into_iter()
559        .any(|keyword| self.at_keyword(keyword))
560    }
561
562    fn parse_expression_until_keyword(
563        &mut self,
564        keyword: &'static str,
565        expected: &'static str,
566    ) -> Result<ExpressionSyntax, SyntaxError> {
567        let start_position = self.position;
568        let mut depths = Depths::default();
569        while self.current().kind != TokenKind::End {
570            if depths.is_zero() && self.at_keyword(keyword) {
571                if start_position == self.position {
572                    return Err(self.unexpected(expected));
573                }
574                return self.parse_expression_range(start_position, self.position);
575            }
576            self.update_expression_depths(&mut depths, self.current())?;
577            self.advance();
578        }
579        if !depths.is_zero() {
580            return Err(self.unclosed_expression_error(&depths));
581        }
582        Err(SyntaxError::new(SyntaxErrorCode::UnexpectedEnd, self.current().span).expected(keyword))
583    }
584
585    fn parse_expression_until_kind(
586        &mut self,
587        terminator: TokenKind,
588        expected: &'static str,
589    ) -> Result<ExpressionSyntax, SyntaxError> {
590        let start_position = self.position;
591        let mut depths = Depths::default();
592        while self.current().kind != TokenKind::End {
593            if depths.is_zero() && self.current().kind == terminator {
594                if start_position == self.position {
595                    return Err(self.unexpected(expected));
596                }
597                return self.parse_expression_range(start_position, self.position);
598            }
599            self.update_expression_depths(&mut depths, self.current())?;
600            self.advance();
601        }
602        if !depths.is_zero() {
603            return Err(self.unclosed_expression_error(&depths));
604        }
605        Err(
606            SyntaxError::new(SyntaxErrorCode::UnexpectedEnd, self.current().span)
607                .expected("a closing graph element delimiter"),
608        )
609    }
610
611    fn scan_to_top_level_delimiter(&mut self) -> Result<usize, SyntaxError> {
612        let mut depths = Depths::default();
613        while self.current().kind != TokenKind::End {
614            if depths.is_zero()
615                && matches!(
616                    self.current().kind,
617                    TokenKind::Comma | TokenKind::RightParen
618                )
619            {
620                return Ok(self.position);
621            }
622            self.update_expression_depths(&mut depths, self.current())?;
623            self.advance();
624        }
625        if !depths.is_zero() {
626            return Err(self.unclosed_expression_error(&depths));
627        }
628        Err(
629            SyntaxError::new(SyntaxErrorCode::UnexpectedEnd, self.current().span)
630                .expected("a comma or closing parenthesis"),
631        )
632    }
633
634    fn parse_qualified_name(&mut self) -> Result<QualifiedName, SyntaxError> {
635        let first = self.parse_identifier()?;
636        let start = first.span.start;
637        let mut end = first.span.end;
638        let mut parts = vec![first];
639        while self.consume_kind(TokenKind::Dot) {
640            let part = self.parse_identifier()?;
641            end = part.span.end;
642            parts.push(part);
643        }
644        Ok(QualifiedName {
645            parts,
646            span: Span::new(start, end),
647        })
648    }
649
650    fn parse_identifier(&mut self) -> Result<Identifier, SyntaxError> {
651        let token = self.current();
652        if !is_identifier_kind(token.kind) {
653            return Err(self.unexpected("an identifier"));
654        }
655        self.advance();
656        Ok(identifier_from_token(token))
657    }
658
659    fn parse_comma_separated<T>(
660        &mut self,
661        terminator: TokenKind,
662        parse_item: fn(&mut Self) -> Result<T, SyntaxError>,
663    ) -> Result<Vec<T>, SyntaxError> {
664        if self.current().kind == terminator {
665            return Ok(Vec::new());
666        }
667        let mut items = Vec::new();
668        loop {
669            items.push(parse_item(self)?);
670            if !self.consume_kind(TokenKind::Comma) {
671                break;
672            }
673        }
674        Ok(items)
675    }
676
677    fn parse_nonempty_comma_separated<T>(
678        &mut self,
679        terminator: TokenKind,
680        parse_item: fn(&mut Self) -> Result<T, SyntaxError>,
681        expected: &'static str,
682    ) -> Result<Vec<T>, SyntaxError> {
683        if self.current().kind == terminator {
684            return Err(self.unexpected(expected));
685        }
686        self.parse_comma_separated(terminator, parse_item)
687    }
688
689    fn current(&self) -> Token {
690        self.tokens
691            .get(self.position)
692            .copied()
693            .unwrap_or(Token::new(
694                TokenKind::End,
695                Span::new(self.input.len(), self.input.len()),
696            ))
697    }
698
699    fn previous_end(&self) -> usize {
700        self.position
701            .checked_sub(1)
702            .and_then(|position| self.tokens.get(position))
703            .map_or(0, |token| token.span.end)
704    }
705
706    fn advance(&mut self) -> Token {
707        let token = self.current();
708        if token.kind != TokenKind::End {
709            self.position += 1;
710        }
711        token
712    }
713
714    fn at_keyword(&self, keyword: &str) -> bool {
715        self.current().is_keyword(self.input, keyword)
716    }
717
718    fn consume_keyword(&mut self, keyword: &str) -> bool {
719        if self.at_keyword(keyword) {
720            self.advance();
721            true
722        } else {
723            false
724        }
725    }
726
727    fn expect_keyword(&mut self, keyword: &'static str) -> Result<Token, SyntaxError> {
728        if self.at_keyword(keyword) {
729            Ok(self.advance())
730        } else {
731            Err(self.unexpected(keyword))
732        }
733    }
734
735    fn consume_kind(&mut self, kind: TokenKind) -> bool {
736        if self.current().kind == kind {
737            self.advance();
738            true
739        } else {
740            false
741        }
742    }
743
744    fn expect_kind(
745        &mut self,
746        kind: TokenKind,
747        expected: &'static str,
748    ) -> Result<Token, SyntaxError> {
749        if self.current().kind == kind {
750            Ok(self.advance())
751        } else {
752            Err(self.unexpected(expected))
753        }
754    }
755
756    fn unexpected(&self, expected: &'static str) -> SyntaxError {
757        let token = self.current();
758        let code = if token.kind == TokenKind::End {
759            SyntaxErrorCode::UnexpectedEnd
760        } else {
761            SyntaxErrorCode::UnexpectedToken
762        };
763        SyntaxError::new(code, token.span)
764            .expected(expected)
765            .found(token.text(self.input))
766    }
767
768    fn update_expression_depths(
769        &self,
770        depths: &mut Depths,
771        token: Token,
772    ) -> Result<(), SyntaxError> {
773        depths.update(token.kind).map_err(|error| match error {
774            DepthError::MismatchedDelimiter(expected) => {
775                SyntaxError::new(SyntaxErrorCode::UnexpectedToken, token.span)
776                    .expected(expected)
777                    .found(token.text(self.input))
778            }
779            DepthError::NestingLimitExceeded => {
780                SyntaxError::new(SyntaxErrorCode::ExpressionNestingLimitExceeded, token.span)
781                    .expected("expression nesting within the configured parser limit")
782            }
783        })
784    }
785
786    fn unclosed_expression_error(&self, depths: &Depths) -> SyntaxError {
787        SyntaxError::new(SyntaxErrorCode::UnexpectedEnd, self.current().span)
788            .expected(depths.expected_closing().unwrap_or("a closing delimiter"))
789    }
790}
791
792#[derive(Debug)]
793struct Depths {
794    closing_delimiters: [TokenKind; MAX_EXPRESSION_NESTING],
795    len: usize,
796}
797
798impl Default for Depths {
799    fn default() -> Self {
800        Self {
801            closing_delimiters: [TokenKind::End; MAX_EXPRESSION_NESTING],
802            len: 0,
803        }
804    }
805}
806
807enum DepthError {
808    MismatchedDelimiter(&'static str),
809    NestingLimitExceeded,
810}
811
812impl Depths {
813    fn update(&mut self, kind: TokenKind) -> Result<(), DepthError> {
814        match kind {
815            TokenKind::LeftParen => self.push(TokenKind::RightParen)?,
816            TokenKind::LeftBracket => self.push(TokenKind::RightBracket)?,
817            TokenKind::LeftBrace => self.push(TokenKind::RightBrace)?,
818            TokenKind::RightParen | TokenKind::RightBracket | TokenKind::RightBrace => {
819                if self.last() != Some(kind) {
820                    return Err(DepthError::MismatchedDelimiter(
821                        self.expected_closing().unwrap_or("an opening delimiter"),
822                    ));
823                }
824                self.len -= 1;
825            }
826            _ => return Ok(()),
827        }
828        Ok(())
829    }
830
831    fn is_zero(&self) -> bool {
832        self.len == 0
833    }
834
835    fn expected_closing(&self) -> Option<&'static str> {
836        match self.last() {
837            Some(TokenKind::RightParen) => Some(")"),
838            Some(TokenKind::RightBracket) => Some("]"),
839            Some(TokenKind::RightBrace) => Some("}"),
840            _ => None,
841        }
842    }
843
844    fn last(&self) -> Option<TokenKind> {
845        self.len
846            .checked_sub(1)
847            .map(|position| self.closing_delimiters[position])
848    }
849
850    fn push(&mut self, kind: TokenKind) -> Result<(), DepthError> {
851        if self.len == MAX_EXPRESSION_NESTING {
852            return Err(DepthError::NestingLimitExceeded);
853        }
854        self.closing_delimiters[self.len] = kind;
855        self.len += 1;
856        Ok(())
857    }
858}
859
860fn is_identifier_kind(kind: TokenKind) -> bool {
861    matches!(kind, TokenKind::Word | TokenKind::QuotedIdentifier)
862}
863
864fn identifier_from_token(token: Token) -> Identifier {
865    Identifier {
866        span: token.span,
867        quoted: token.kind == TokenKind::QuotedIdentifier,
868    }
869}