use pest::Parser;
use pest_derive::Parser;
use pest::iterators::Pairs;
use crate::ast::Expr;
#[derive(Parser)]
#[grammar = "query.pest"]
pub struct QueryParser;
pub fn parse_expr(input: &str) -> Expr {
let pairs = QueryParser::parse(Rule::query, input)
.expect("Failed to parse filter expression");
build_expr(pairs)
}
fn build_expr(pairs: Pairs<Rule>) -> Expr {
use Expr::*;
for pair in pairs {
match pair.as_rule() {
Rule::expr => {
return build_expr(pair.into_inner());
}
Rule::or_expr => {
let mut inner = pair.into_inner();
let mut expr = build_expr(inner.next().unwrap().into_inner());
for next in inner {
expr = Or(Box::new(expr), Box::new(build_expr(next.into_inner())));
}
return expr;
}
Rule::and_expr => {
let mut inner = pair.into_inner();
let mut expr = build_expr(inner.next().unwrap().into_inner());
for next in inner {
expr = And(Box::new(expr), Box::new(build_expr(next.into_inner())));
}
return expr;
}
Rule::cmp_expr => {
let mut inner = pair.into_inner();
let field = inner.next().unwrap().as_str().to_string();
let op = inner.next().unwrap().as_str().to_string();
let val = inner.next().unwrap().as_str().to_string();
return Cmp {
field,
op,
value: val,
};
}
_ => {}
}
}
panic!("Empty expression");
}