1use 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}