Skip to main content

linkrs_query/parser/parsing/traversal_parser/
go.rs

1use crate::parser::ast::stmt::*;
2use crate::parser::core::error::ParseError;
3use crate::parser::parsing::clause_parser::ClauseParser;
4use crate::parser::parsing::parse_context::ParseContext;
5use crate::parser::TokenKind;
6
7use super::TraversalParser;
8
9impl TraversalParser {
10    /// Analyzing GO statements
11    pub fn parse_go_statement(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
12        let start_span = ctx.current_span();
13        ctx.expect_token(TokenKind::Go)?;
14
15        let steps = self.parse_steps(ctx)?;
16
17        ctx.match_token(TokenKind::Step);
18
19        ctx.expect_token(TokenKind::From)?;
20        let from_span = ctx.current_span();
21        let from_clause = ctx.recover_clause(
22            |c| {
23                Ok(FromClause {
24                    span: c.current_span(),
25                    vertices: Vec::new(),
26                })
27            },
28            |c| {
29                let vertices = self.parse_expression_list(c)?;
30                Ok(FromClause {
31                    span: from_span,
32                    vertices,
33                })
34            },
35        )?;
36
37        let over = if ctx.match_token(TokenKind::Over) {
38            ctx.recover_clause(
39                |_| Ok(None),
40                |c| ClauseParser::new().parse_over_clause(c).map(Some),
41            )?
42        } else {
43            None
44        };
45
46        let where_clause = if ctx.match_token(TokenKind::Where) {
47            Some(ctx.recover_clause(Self::create_true_expression, |c| self.parse_expression(c))?)
48        } else {
49            Some(Self::create_true_expression(ctx)?)
50        };
51
52        let yield_clause = if ctx.match_token(TokenKind::Yield) {
53            ctx.recover_clause(
54                |_| Ok(None),
55                |c| ClauseParser::new().parse_yield_clause(c).map(Some),
56            )?
57        } else {
58            None
59        };
60
61        let span = ctx.span_since(start_span.start);
62
63        Ok(Stmt::Go(GoStmt {
64            span,
65            steps,
66            from: from_clause,
67            over,
68            where_clause,
69            yield_clause,
70        }))
71    }
72}