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 patterns;
26mod stream;
27
28#[derive(Debug, thiserror::Error, PartialEq)]
29pub enum ParseError {
30 #[error(transparent)]
31 Lex(#[from] LexError),
32 #[error("expected {expected}, got {got:?} ({value:?}) at position {position}")]
33 Expected {
34 expected: &'static str,
35 got: TokenKind,
36 value: String,
37 position: usize,
38 },
39 #[error("expected keyword {keyword:?}, got {got:?} at position {position}")]
40 ExpectedKeyword {
41 keyword: &'static str,
42 got: String,
43 position: usize,
44 },
45 #[error("unexpected token {got:?} at position {position}")]
46 Unexpected { got: String, position: usize },
47}
48
49pub fn parse_cypher(source: &str) -> Result<CypherQuery, ParseError> {
51 let tokens = tokenize(source)?;
52 let mut parser = Parser { tokens, pos: 0 };
53 parser.parse()
54}
55
56struct Parser {
57 tokens: Vec<Token>,
58 pos: usize,
59}
60
61const RESERVED_KEYWORDS: &[&str] = &[
62 "AND",
63 "AS",
64 "ASC",
65 "BY",
66 "CASE",
67 "CONTAINS",
68 "CREATE",
69 "DELETE",
70 "DESC",
71 "DETACH",
72 "DISTINCT",
73 "ELSE",
74 "END",
75 "ENDS",
76 "EXISTS",
77 "FALSE",
78 "IN",
79 "IS",
80 "LIMIT",
81 "MATCH",
82 "MERGE",
83 "NODE",
84 "NOT",
85 "NULL",
86 "ON",
87 "OPTIONAL",
88 "OR",
89 "ORDER",
90 "RELATIONSHIP",
91 "REMOVE",
92 "RETURN",
93 "SET",
94 "SKIP",
95 "STARTS",
96 "THEN",
97 "TRUE",
98 "UNWIND",
99 "WHEN",
100 "WHERE",
101 "WITH",
102 "XOR",
103];
104
105#[cfg(test)]
106mod tests;