lora_parser/parser/
mod.rs1use crate::errors::ParseError;
24use lora_ast::*;
25use pest::iterators::Pair;
26use pest::Parser;
27
28mod clauses;
29mod expressions;
30mod limits;
31mod literals;
32mod patterns;
33mod query;
34mod schema;
35mod util;
36
37#[cfg(test)]
38mod tests;
39
40use clauses::lower_standalone_call;
41use query::lower_regular_query;
42use schema::lower_schema_command;
43use util::{pair_span, unexpected_rule};
44
45#[derive(pest_derive::Parser)]
46#[grammar = "cypher.pest"]
47pub(super) struct LoraParser;
48
49pub fn parse_query(input: &str) -> Result<Document, ParseError> {
50 limits::reset_budgets();
51 let nesting = limits::check_nesting(input)?;
52 lora_ast::stack::guard_with(limits::parse_stack(nesting), || {
55 let mut pairs = LoraParser::parse(Rule::query, input)
56 .map_err(|e| ParseError::new(e.to_string(), 0, input.len()))?;
57
58 let pair = pairs
59 .next()
60 .ok_or_else(|| ParseError::new("expected query", 0, input.len()))?;
61
62 lower_query(pair)
63 })
64}
65
66fn lower_query(pair: Pair<Rule>) -> Result<Document, ParseError> {
67 let span = pair_span(&pair);
68 let mut inner = pair.into_inner();
69
70 let stmt = inner
71 .find(|p| p.as_rule() == Rule::statement)
72 .ok_or_else(|| ParseError::new("expected statement", span.start, span.end))?;
73
74 Ok(Document {
75 statement: lower_statement(stmt)?,
76 span,
77 })
78}
79
80fn lower_statement(pair: Pair<Rule>) -> Result<Statement, ParseError> {
81 let inner = util::single_inner(pair)?;
82 match inner.as_rule() {
83 Rule::regular_query => Ok(Statement::Query(Query::Regular(lower_regular_query(
84 inner,
85 )?))),
86 Rule::standalone_call => Ok(Statement::Query(Query::StandaloneCall(
87 lower_standalone_call(inner)?,
88 ))),
89 Rule::schema_command => Ok(Statement::Schema(lower_schema_command(inner)?)),
90 _ => Err(unexpected_rule("statement", inner)),
91 }
92}