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