use pest::Parser;
use pest_derive::Parser;
use crate::ast::Expr;
use pest::iterators::Pairs;
#[derive(Parser)]
#[grammar = "query.pest"]
pub struct QueryParser;
pub fn parse_expr(input: &str) -> Expr {
println!("\nDEBUG: parsing: {:?}", input);
match QueryParser::parse(Rule::query, input) {
Ok(pairs) => {
println!("DEBUG: PARSED PAIRS:");
for p in pairs.clone() {
println!(" {:?}", p.as_rule());
}
println!("{:#?}", pairs);
build_expr(pairs)
}
Err(e) => {
println!("DEBUG: PARSE ERROR: {:?}", e);
panic!("Parse failed");
}
}
}
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");
}