1use std::collections::BTreeMap;
10
11use uqa_core::Value;
12
13use crate::cypher::ast::{
14 BinaryOp, CaseExpr, CreateClause, CypherClause, CypherExpr, CypherQuery, DeleteClause,
15 FunctionCall, InList, IsNotNull, IsNull, ListComprehension, ListIndex, ListLiteral, ListSlice,
16 Literal, MapLiteral, MatchClause, MergeClause, NodePattern, OrderByItem, Parameter,
17 PathElement, PathPattern, PropertyAccess, RelDirection, RelPattern, ReturnClause, ReturnItem,
18 SetClause, SetItem, SetOperator, UnaryOp, UnwindClause, Variable, WithClause,
19};
20use crate::cypher::lexer::{is_keyword, tokenize, LexError, Token, TokenKind};
21
22mod atoms;
23mod clauses;
24mod expressions;
25mod limits;
26mod patterns;
27mod stream;
28
29#[derive(Debug, thiserror::Error, PartialEq)]
30pub enum ParseError {
31 #[error(transparent)]
32 Lex(#[from] LexError),
33 #[error("expected {expected}, got {got:?} ({value:?}) at position {position}")]
34 Expected {
35 expected: &'static str,
36 got: TokenKind,
37 value: String,
38 position: usize,
39 },
40 #[error("expected keyword {keyword:?}, got {got:?} at position {position}")]
41 ExpectedKeyword {
42 keyword: &'static str,
43 got: String,
44 position: usize,
45 },
46 #[error("unexpected token {got:?} at position {position}")]
47 Unexpected { got: String, position: usize },
48 #[error("Cypher expression nesting limit of {limit} exceeded at position {position}")]
49 ExpressionTooDeep { limit: usize, position: usize },
50}
51
52pub fn parse_cypher(source: &str) -> Result<CypherQuery, ParseError> {
54 let tokens = tokenize(source)?;
55 let mut parser = Parser {
56 tokens,
57 pos: 0,
58 expression_recursion: 0,
59 };
60 parser.parse()
61}
62
63struct Parser {
64 tokens: Vec<Token>,
65 pos: usize,
66 expression_recursion: usize,
67}
68
69const RESERVED_KEYWORDS: &[&str] = &[
70 "AND",
71 "AS",
72 "ASC",
73 "BY",
74 "CASE",
75 "CONTAINS",
76 "CREATE",
77 "DELETE",
78 "DESC",
79 "DETACH",
80 "DISTINCT",
81 "ELSE",
82 "END",
83 "ENDS",
84 "EXISTS",
85 "FALSE",
86 "IN",
87 "IS",
88 "LIMIT",
89 "MATCH",
90 "MERGE",
91 "NODE",
92 "NOT",
93 "NULL",
94 "ON",
95 "OPTIONAL",
96 "OR",
97 "ORDER",
98 "RELATIONSHIP",
99 "REMOVE",
100 "RETURN",
101 "SET",
102 "SKIP",
103 "STARTS",
104 "THEN",
105 "TRUE",
106 "UNWIND",
107 "WHEN",
108 "WHERE",
109 "WITH",
110 "XOR",
111];
112
113#[cfg(test)]
114mod tests;