Skip to main content

graphos_adapters/query/gql/
parser.rs

1//! GQL Parser.
2
3use super::ast::*;
4use super::lexer::{Lexer, Token, TokenKind};
5use graphos_common::utils::error::{Error, QueryError, QueryErrorKind, Result, SourceSpan};
6
7/// GQL Parser.
8pub struct Parser<'a> {
9    lexer: Lexer<'a>,
10    current: Token,
11    source: &'a str,
12}
13
14impl<'a> Parser<'a> {
15    /// Creates a new parser for the given input.
16    pub fn new(input: &'a str) -> Self {
17        let mut lexer = Lexer::new(input);
18        let current = lexer.next_token();
19        Self {
20            lexer,
21            current,
22            source: input,
23        }
24    }
25
26    /// Parses the input into a statement.
27    pub fn parse(&mut self) -> Result<Statement> {
28        match self.current.kind {
29            TokenKind::Match => self.parse_query().map(Statement::Query),
30            TokenKind::Insert => self.parse_insert().map(|s| Statement::DataModification(DataModificationStatement::Insert(s))),
31            TokenKind::Delete => self.parse_delete().map(|s| Statement::DataModification(DataModificationStatement::Delete(s))),
32            TokenKind::Create => self.parse_create_schema().map(Statement::Schema),
33            _ => Err(self.error("Expected MATCH, INSERT, DELETE, or CREATE")),
34        }
35    }
36
37    fn parse_query(&mut self) -> Result<QueryStatement> {
38        let span_start = self.current.span.start;
39
40        // Parse MATCH clause
41        let match_clause = if self.current.kind == TokenKind::Match {
42            Some(self.parse_match_clause()?)
43        } else {
44            None
45        };
46
47        // Parse WHERE clause
48        let where_clause = if self.current.kind == TokenKind::Where {
49            Some(self.parse_where_clause()?)
50        } else {
51            None
52        };
53
54        // Parse RETURN clause
55        if self.current.kind != TokenKind::Return {
56            return Err(self.error("Expected RETURN"));
57        }
58        let return_clause = self.parse_return_clause()?;
59
60        Ok(QueryStatement {
61            match_clause,
62            where_clause,
63            return_clause,
64            span: Some(SourceSpan::new(span_start, self.current.span.end, 1, 1)),
65        })
66    }
67
68    fn parse_match_clause(&mut self) -> Result<MatchClause> {
69        let span_start = self.current.span.start;
70        self.expect(TokenKind::Match)?;
71
72        let mut patterns = Vec::new();
73        patterns.push(self.parse_pattern()?);
74
75        while self.current.kind == TokenKind::Comma {
76            self.advance();
77            patterns.push(self.parse_pattern()?);
78        }
79
80        Ok(MatchClause {
81            patterns,
82            span: Some(SourceSpan::new(span_start, self.current.span.end, 1, 1)),
83        })
84    }
85
86    fn parse_pattern(&mut self) -> Result<Pattern> {
87        let node = self.parse_node_pattern()?;
88
89        // Check for path continuation
90        // Handle both `-[...]->`/`<-[...]-` style and `->` style
91        if matches!(self.current.kind, TokenKind::Arrow | TokenKind::LeftArrow | TokenKind::DoubleDash | TokenKind::Minus) {
92            let mut edges = Vec::new();
93
94            while matches!(self.current.kind, TokenKind::Arrow | TokenKind::LeftArrow | TokenKind::DoubleDash | TokenKind::Minus) {
95                edges.push(self.parse_edge_pattern()?);
96            }
97
98            Ok(Pattern::Path(PathPattern {
99                source: node,
100                edges,
101                span: None,
102            }))
103        } else {
104            Ok(Pattern::Node(node))
105        }
106    }
107
108    fn parse_node_pattern(&mut self) -> Result<NodePattern> {
109        self.expect(TokenKind::LParen)?;
110
111        let variable = if self.current.kind == TokenKind::Identifier {
112            let name = self.current.text.clone();
113            self.advance();
114            Some(name)
115        } else {
116            None
117        };
118
119        let mut labels = Vec::new();
120        while self.current.kind == TokenKind::Colon {
121            self.advance();
122            if self.current.kind != TokenKind::Identifier {
123                return Err(self.error("Expected label name"));
124            }
125            labels.push(self.current.text.clone());
126            self.advance();
127        }
128
129        // Parse properties { key: value, ... }
130        let properties = if self.current.kind == TokenKind::LBrace {
131            self.parse_property_map()?
132        } else {
133            Vec::new()
134        };
135
136        self.expect(TokenKind::RParen)?;
137
138        Ok(NodePattern {
139            variable,
140            labels,
141            properties,
142            span: None,
143        })
144    }
145
146    fn parse_edge_pattern(&mut self) -> Result<EdgePattern> {
147        // Handle both styles:
148        // 1. `-[...]->` or `-[:TYPE]->` (direction determined by trailing arrow)
149        // 2. `->` or `<-` or `--` (direction determined by leading arrow)
150
151        let (variable, types, direction) = if self.current.kind == TokenKind::Minus {
152            // Pattern: -[...]->(target) or -[...]-(target)
153            self.advance();
154
155            // Parse [variable:TYPE]
156            let (var, edge_types) = if self.current.kind == TokenKind::LBracket {
157                self.advance();
158
159                let v = if self.current.kind == TokenKind::Identifier && self.peek_kind() != TokenKind::Colon {
160                    let name = self.current.text.clone();
161                    self.advance();
162                    Some(name)
163                } else {
164                    None
165                };
166
167                let mut tps = Vec::new();
168                while self.current.kind == TokenKind::Colon {
169                    self.advance();
170                    if self.current.kind != TokenKind::Identifier {
171                        return Err(self.error("Expected edge type"));
172                    }
173                    tps.push(self.current.text.clone());
174                    self.advance();
175                }
176
177                self.expect(TokenKind::RBracket)?;
178                (v, tps)
179            } else {
180                (None, Vec::new())
181            };
182
183            // Now determine direction from trailing symbol
184            let dir = if self.current.kind == TokenKind::Arrow {
185                self.advance();
186                EdgeDirection::Outgoing
187            } else if self.current.kind == TokenKind::Minus {
188                self.advance();
189                EdgeDirection::Undirected
190            } else {
191                return Err(self.error("Expected -> or - after edge pattern"));
192            };
193
194            (var, edge_types, dir)
195        } else if self.current.kind == TokenKind::LeftArrow {
196            // Pattern: <-[...]-(target)
197            self.advance();
198
199            let (var, edge_types) = if self.current.kind == TokenKind::LBracket {
200                self.advance();
201
202                let v = if self.current.kind == TokenKind::Identifier && self.peek_kind() != TokenKind::Colon {
203                    let name = self.current.text.clone();
204                    self.advance();
205                    Some(name)
206                } else {
207                    None
208                };
209
210                let mut tps = Vec::new();
211                while self.current.kind == TokenKind::Colon {
212                    self.advance();
213                    if self.current.kind != TokenKind::Identifier {
214                        return Err(self.error("Expected edge type"));
215                    }
216                    tps.push(self.current.text.clone());
217                    self.advance();
218                }
219
220                self.expect(TokenKind::RBracket)?;
221                (v, tps)
222            } else {
223                (None, Vec::new())
224            };
225
226            // Consume trailing -
227            if self.current.kind == TokenKind::Minus {
228                self.advance();
229            }
230
231            (var, edge_types, EdgeDirection::Incoming)
232        } else if self.current.kind == TokenKind::Arrow {
233            // Simple ->
234            self.advance();
235            (None, Vec::new(), EdgeDirection::Outgoing)
236        } else if self.current.kind == TokenKind::DoubleDash {
237            // Simple --
238            self.advance();
239            (None, Vec::new(), EdgeDirection::Undirected)
240        } else {
241            return Err(self.error("Expected edge pattern"));
242        };
243
244        let target = self.parse_node_pattern()?;
245
246        Ok(EdgePattern {
247            variable,
248            types,
249            direction,
250            target,
251            span: None,
252        })
253    }
254
255    fn parse_where_clause(&mut self) -> Result<WhereClause> {
256        self.expect(TokenKind::Where)?;
257        let expression = self.parse_expression()?;
258
259        Ok(WhereClause {
260            expression,
261            span: None,
262        })
263    }
264
265    fn parse_return_clause(&mut self) -> Result<ReturnClause> {
266        self.expect(TokenKind::Return)?;
267
268        let distinct = if self.current.kind == TokenKind::Distinct {
269            self.advance();
270            true
271        } else {
272            false
273        };
274
275        let mut items = Vec::new();
276        items.push(self.parse_return_item()?);
277
278        while self.current.kind == TokenKind::Comma {
279            self.advance();
280            items.push(self.parse_return_item()?);
281        }
282
283        let order_by = if self.current.kind == TokenKind::Order {
284            Some(self.parse_order_by()?)
285        } else {
286            None
287        };
288
289        let skip = if self.current.kind == TokenKind::Skip {
290            self.advance();
291            Some(self.parse_expression()?)
292        } else {
293            None
294        };
295
296        let limit = if self.current.kind == TokenKind::Limit {
297            self.advance();
298            Some(self.parse_expression()?)
299        } else {
300            None
301        };
302
303        Ok(ReturnClause {
304            distinct,
305            items,
306            order_by,
307            skip,
308            limit,
309            span: None,
310        })
311    }
312
313    fn parse_return_item(&mut self) -> Result<ReturnItem> {
314        let expression = self.parse_expression()?;
315
316        let alias = if self.current.kind == TokenKind::As {
317            self.advance();
318            if self.current.kind != TokenKind::Identifier {
319                return Err(self.error("Expected alias name"));
320            }
321            let name = self.current.text.clone();
322            self.advance();
323            Some(name)
324        } else {
325            None
326        };
327
328        Ok(ReturnItem {
329            expression,
330            alias,
331            span: None,
332        })
333    }
334
335    fn parse_order_by(&mut self) -> Result<OrderByClause> {
336        self.expect(TokenKind::Order)?;
337        self.expect(TokenKind::By)?;
338
339        let mut items = Vec::new();
340        items.push(self.parse_order_item()?);
341
342        while self.current.kind == TokenKind::Comma {
343            self.advance();
344            items.push(self.parse_order_item()?);
345        }
346
347        Ok(OrderByClause { items, span: None })
348    }
349
350    fn parse_order_item(&mut self) -> Result<OrderByItem> {
351        let expression = self.parse_expression()?;
352
353        let order = match self.current.kind {
354            TokenKind::Asc => {
355                self.advance();
356                SortOrder::Asc
357            }
358            TokenKind::Desc => {
359                self.advance();
360                SortOrder::Desc
361            }
362            _ => SortOrder::Asc,
363        };
364
365        Ok(OrderByItem { expression, order })
366    }
367
368    fn parse_expression(&mut self) -> Result<Expression> {
369        self.parse_or_expression()
370    }
371
372    fn parse_or_expression(&mut self) -> Result<Expression> {
373        let mut left = self.parse_and_expression()?;
374
375        while self.current.kind == TokenKind::Or {
376            self.advance();
377            let right = self.parse_and_expression()?;
378            left = Expression::Binary {
379                left: Box::new(left),
380                op: BinaryOp::Or,
381                right: Box::new(right),
382            };
383        }
384
385        Ok(left)
386    }
387
388    fn parse_and_expression(&mut self) -> Result<Expression> {
389        let mut left = self.parse_comparison_expression()?;
390
391        while self.current.kind == TokenKind::And {
392            self.advance();
393            let right = self.parse_comparison_expression()?;
394            left = Expression::Binary {
395                left: Box::new(left),
396                op: BinaryOp::And,
397                right: Box::new(right),
398            };
399        }
400
401        Ok(left)
402    }
403
404    fn parse_comparison_expression(&mut self) -> Result<Expression> {
405        let left = self.parse_additive_expression()?;
406
407        let op = match self.current.kind {
408            TokenKind::Eq => Some(BinaryOp::Eq),
409            TokenKind::Ne => Some(BinaryOp::Ne),
410            TokenKind::Lt => Some(BinaryOp::Lt),
411            TokenKind::Le => Some(BinaryOp::Le),
412            TokenKind::Gt => Some(BinaryOp::Gt),
413            TokenKind::Ge => Some(BinaryOp::Ge),
414            _ => None,
415        };
416
417        if let Some(op) = op {
418            self.advance();
419            let right = self.parse_additive_expression()?;
420            Ok(Expression::Binary {
421                left: Box::new(left),
422                op,
423                right: Box::new(right),
424            })
425        } else {
426            Ok(left)
427        }
428    }
429
430    fn parse_additive_expression(&mut self) -> Result<Expression> {
431        let mut left = self.parse_multiplicative_expression()?;
432
433        loop {
434            let op = match self.current.kind {
435                TokenKind::Plus => BinaryOp::Add,
436                TokenKind::Minus => BinaryOp::Sub,
437                _ => break,
438            };
439            self.advance();
440            let right = self.parse_multiplicative_expression()?;
441            left = Expression::Binary {
442                left: Box::new(left),
443                op,
444                right: Box::new(right),
445            };
446        }
447
448        Ok(left)
449    }
450
451    fn parse_multiplicative_expression(&mut self) -> Result<Expression> {
452        let mut left = self.parse_unary_expression()?;
453
454        loop {
455            let op = match self.current.kind {
456                TokenKind::Star => BinaryOp::Mul,
457                TokenKind::Slash => BinaryOp::Div,
458                TokenKind::Percent => BinaryOp::Mod,
459                _ => break,
460            };
461            self.advance();
462            let right = self.parse_unary_expression()?;
463            left = Expression::Binary {
464                left: Box::new(left),
465                op,
466                right: Box::new(right),
467            };
468        }
469
470        Ok(left)
471    }
472
473    fn parse_unary_expression(&mut self) -> Result<Expression> {
474        match self.current.kind {
475            TokenKind::Not => {
476                self.advance();
477                let operand = self.parse_unary_expression()?;
478                Ok(Expression::Unary {
479                    op: UnaryOp::Not,
480                    operand: Box::new(operand),
481                })
482            }
483            TokenKind::Minus => {
484                self.advance();
485                let operand = self.parse_unary_expression()?;
486                Ok(Expression::Unary {
487                    op: UnaryOp::Neg,
488                    operand: Box::new(operand),
489                })
490            }
491            _ => self.parse_primary_expression(),
492        }
493    }
494
495    fn parse_primary_expression(&mut self) -> Result<Expression> {
496        match self.current.kind {
497            TokenKind::Null => {
498                self.advance();
499                Ok(Expression::Literal(Literal::Null))
500            }
501            TokenKind::True => {
502                self.advance();
503                Ok(Expression::Literal(Literal::Bool(true)))
504            }
505            TokenKind::False => {
506                self.advance();
507                Ok(Expression::Literal(Literal::Bool(false)))
508            }
509            TokenKind::Integer => {
510                let value = self.current.text.parse().map_err(|_| self.error("Invalid integer"))?;
511                self.advance();
512                Ok(Expression::Literal(Literal::Integer(value)))
513            }
514            TokenKind::Float => {
515                let value = self.current.text.parse().map_err(|_| self.error("Invalid float"))?;
516                self.advance();
517                Ok(Expression::Literal(Literal::Float(value)))
518            }
519            TokenKind::String => {
520                let text = &self.current.text;
521                let value = text[1..text.len() - 1].to_string(); // Remove quotes
522                self.advance();
523                Ok(Expression::Literal(Literal::String(value)))
524            }
525            TokenKind::Identifier => {
526                let name = self.current.text.clone();
527                self.advance();
528
529                if self.current.kind == TokenKind::Dot {
530                    self.advance();
531                    if self.current.kind != TokenKind::Identifier {
532                        return Err(self.error("Expected property name"));
533                    }
534                    let property = self.current.text.clone();
535                    self.advance();
536                    Ok(Expression::PropertyAccess {
537                        variable: name,
538                        property,
539                    })
540                } else if self.current.kind == TokenKind::LParen {
541                    // Function call
542                    self.advance();
543                    let mut args = Vec::new();
544                    if self.current.kind != TokenKind::RParen {
545                        args.push(self.parse_expression()?);
546                        while self.current.kind == TokenKind::Comma {
547                            self.advance();
548                            args.push(self.parse_expression()?);
549                        }
550                    }
551                    self.expect(TokenKind::RParen)?;
552                    Ok(Expression::FunctionCall { name, args })
553                } else {
554                    Ok(Expression::Variable(name))
555                }
556            }
557            TokenKind::LParen => {
558                self.advance();
559                let expr = self.parse_expression()?;
560                self.expect(TokenKind::RParen)?;
561                Ok(expr)
562            }
563            TokenKind::LBracket => {
564                self.advance();
565                let mut elements = Vec::new();
566                if self.current.kind != TokenKind::RBracket {
567                    elements.push(self.parse_expression()?);
568                    while self.current.kind == TokenKind::Comma {
569                        self.advance();
570                        elements.push(self.parse_expression()?);
571                    }
572                }
573                self.expect(TokenKind::RBracket)?;
574                Ok(Expression::List(elements))
575            }
576            _ => Err(self.error("Expected expression")),
577        }
578    }
579
580    fn parse_property_map(&mut self) -> Result<Vec<(String, Expression)>> {
581        self.expect(TokenKind::LBrace)?;
582
583        let mut properties = Vec::new();
584
585        if self.current.kind != TokenKind::RBrace {
586            loop {
587                if self.current.kind != TokenKind::Identifier {
588                    return Err(self.error("Expected property name"));
589                }
590                let key = self.current.text.clone();
591                self.advance();
592
593                self.expect(TokenKind::Colon)?;
594
595                let value = self.parse_expression()?;
596                properties.push((key, value));
597
598                if self.current.kind != TokenKind::Comma {
599                    break;
600                }
601                self.advance();
602            }
603        }
604
605        self.expect(TokenKind::RBrace)?;
606        Ok(properties)
607    }
608
609    fn parse_insert(&mut self) -> Result<InsertStatement> {
610        self.expect(TokenKind::Insert)?;
611
612        let mut patterns = Vec::new();
613        patterns.push(self.parse_pattern()?);
614
615        while self.current.kind == TokenKind::Comma {
616            self.advance();
617            patterns.push(self.parse_pattern()?);
618        }
619
620        Ok(InsertStatement {
621            patterns,
622            span: None,
623        })
624    }
625
626    fn parse_delete(&mut self) -> Result<DeleteStatement> {
627        let detach = if self.current.kind == TokenKind::Detach {
628            self.advance();
629            true
630        } else {
631            false
632        };
633
634        self.expect(TokenKind::Delete)?;
635
636        let mut variables = Vec::new();
637        if self.current.kind != TokenKind::Identifier {
638            return Err(self.error("Expected variable name"));
639        }
640        variables.push(self.current.text.clone());
641        self.advance();
642
643        while self.current.kind == TokenKind::Comma {
644            self.advance();
645            if self.current.kind != TokenKind::Identifier {
646                return Err(self.error("Expected variable name"));
647            }
648            variables.push(self.current.text.clone());
649            self.advance();
650        }
651
652        Ok(DeleteStatement {
653            variables,
654            detach,
655            span: None,
656        })
657    }
658
659    fn parse_create_schema(&mut self) -> Result<SchemaStatement> {
660        self.expect(TokenKind::Create)?;
661
662        match self.current.kind {
663            TokenKind::Node => {
664                self.advance();
665                self.expect(TokenKind::Type)?;
666
667                if self.current.kind != TokenKind::Identifier {
668                    return Err(self.error("Expected type name"));
669                }
670                let name = self.current.text.clone();
671                self.advance();
672
673                // Parse property definitions
674                let properties = if self.current.kind == TokenKind::LParen {
675                    self.parse_property_definitions()?
676                } else {
677                    Vec::new()
678                };
679
680                Ok(SchemaStatement::CreateNodeType(CreateNodeTypeStatement {
681                    name,
682                    properties,
683                    span: None,
684                }))
685            }
686            TokenKind::Edge => {
687                self.advance();
688                self.expect(TokenKind::Type)?;
689
690                if self.current.kind != TokenKind::Identifier {
691                    return Err(self.error("Expected type name"));
692                }
693                let name = self.current.text.clone();
694                self.advance();
695
696                let properties = if self.current.kind == TokenKind::LParen {
697                    self.parse_property_definitions()?
698                } else {
699                    Vec::new()
700                };
701
702                Ok(SchemaStatement::CreateEdgeType(CreateEdgeTypeStatement {
703                    name,
704                    properties,
705                    span: None,
706                }))
707            }
708            _ => Err(self.error("Expected NODE or EDGE")),
709        }
710    }
711
712    fn parse_property_definitions(&mut self) -> Result<Vec<PropertyDefinition>> {
713        self.expect(TokenKind::LParen)?;
714
715        let mut defs = Vec::new();
716
717        if self.current.kind != TokenKind::RParen {
718            loop {
719                if self.current.kind != TokenKind::Identifier {
720                    return Err(self.error("Expected property name"));
721                }
722                let name = self.current.text.clone();
723                self.advance();
724
725                if self.current.kind != TokenKind::Identifier {
726                    return Err(self.error("Expected type name"));
727                }
728                let data_type = self.current.text.clone();
729                self.advance();
730
731                let nullable = if self.current.kind == TokenKind::Not {
732                    self.advance();
733                    if self.current.kind != TokenKind::Null {
734                        return Err(self.error("Expected NULL after NOT"));
735                    }
736                    self.advance();
737                    false
738                } else {
739                    true
740                };
741
742                defs.push(PropertyDefinition {
743                    name,
744                    data_type,
745                    nullable,
746                });
747
748                if self.current.kind != TokenKind::Comma {
749                    break;
750                }
751                self.advance();
752            }
753        }
754
755        self.expect(TokenKind::RParen)?;
756        Ok(defs)
757    }
758
759    fn advance(&mut self) {
760        self.current = self.lexer.next_token();
761    }
762
763    fn expect(&mut self, kind: TokenKind) -> Result<()> {
764        if self.current.kind == kind {
765            self.advance();
766            Ok(())
767        } else {
768            Err(self.error(&format!("Expected {:?}", kind)))
769        }
770    }
771
772    fn peek_kind(&mut self) -> TokenKind {
773        // Simple lookahead by creating a temporary lexer
774        // In a production implementation, we'd buffer tokens
775        self.current.kind
776    }
777
778    fn error(&self, message: &str) -> Error {
779        Error::Query(
780            QueryError::new(QueryErrorKind::Syntax, message)
781                .with_span(self.current.span)
782                .with_source(self.source.to_string()),
783        )
784    }
785}
786
787#[cfg(test)]
788mod tests {
789    use super::*;
790
791    #[test]
792    fn test_parse_simple_match() {
793        let mut parser = Parser::new("MATCH (n) RETURN n");
794        let result = parser.parse();
795        assert!(result.is_ok());
796
797        let stmt = result.unwrap();
798        assert!(matches!(stmt, Statement::Query(_)));
799    }
800
801    #[test]
802    fn test_parse_match_with_label() {
803        let mut parser = Parser::new("MATCH (n:Person) RETURN n");
804        let result = parser.parse();
805        assert!(result.is_ok());
806    }
807
808    #[test]
809    fn test_parse_match_with_where() {
810        let mut parser = Parser::new("MATCH (n:Person) WHERE n.age > 30 RETURN n");
811        let result = parser.parse();
812        assert!(result.is_ok());
813    }
814
815    #[test]
816    fn test_parse_path_pattern() {
817        let mut parser = Parser::new("MATCH (a)-[:KNOWS]->(b) RETURN a, b");
818        let result = parser.parse();
819        assert!(result.is_ok());
820    }
821
822    #[test]
823    fn test_parse_insert() {
824        let mut parser = Parser::new("INSERT (n:Person {name: 'Alice'})");
825        let result = parser.parse();
826        assert!(result.is_ok());
827    }
828}