Skip to content

Commit

Permalink
implemented unary not + unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
miampf committed Jan 19, 2024
1 parent a594f81 commit d948ff7
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 9 deletions.
4 changes: 3 additions & 1 deletion query.pest
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ operation = _{and | or}
and = {"&"}
or = {"|"}

unary_not = {"!"}

expr = {term ~ (operation ~ term)*}
term = _{tag | "(" ~ expr ~ ")"}
term = _{unary_not* ~ tag | "(" ~ expr ~ ")"}

tagsearch = _{SOI ~ expr ~ EOI}

Expand Down
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
}

let ast = construct_query_ast(
QueryParser::parse(Rule::tagsearch, "(#a & #b | (#c & #d)) & #e")
QueryParser::parse(Rule::tagsearch, "!#e")
.unwrap()
.next()
.unwrap()
.into_inner(),
vec!["#a", "#c", "#d", "#e"],
vec!["#a", "#c", "#d"],
);

println!("{:#?}", ast);
Expand Down
19 changes: 13 additions & 6 deletions src/parsers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub mod query {
#[derive(Debug, PartialEq, Clone)]
pub enum Expr {
Bool(bool),
UnaryNot(Box<Expr>),
Operation {
lhs: Box<Expr>,
op: Op,
Expand All @@ -38,6 +39,7 @@ pub mod query {
PrattParser::new()
// & and | are evaluated with the same precedence
.op(Op::infix(and, Left) | Op::infix(or, Left))
.op(Op::prefix(unary_not))
};
}

Expand Down Expand Up @@ -69,6 +71,10 @@ pub mod query {
rhs: Box::new(rhs),
}
})
.map_prefix(|op, rhs| match op.as_rule() {
Rule::unary_not => Expr::UnaryNot(Box::new(rhs)),
rule => unreachable!("Expected unary not, found {:?}", rule),
})
.parse(pairs)
}

Expand All @@ -77,6 +83,7 @@ pub mod query {
pub fn evaluate_ast(ast: Expr) -> bool {
match ast {
Expr::Bool(value) => value,
Expr::UnaryNot(expr) => !evaluate_ast(*expr),
Expr::Operation { lhs, op, rhs } => {
let left = evaluate_ast(*lhs);
let right = evaluate_ast(*rhs);
Expand Down Expand Up @@ -174,7 +181,7 @@ mod tests {
let test_cases = [
TestCase {
name: "success_with_space",
input: "#a & #b",
input: "#a & !#b",
expected_error: false,
},
TestCase {
Expand Down Expand Up @@ -251,7 +258,7 @@ mod tests {
},
TestCase {
name: "success_nested",
input_query: "#a & #b | (#c & #d)",
input_query: "#a & #b | (!#c & #d)",
input_tags: vec!["#c".to_string(), "#d".to_string()],
expected_ast: Expr::Operation {
lhs: Box::new(Expr::Operation {
Expand All @@ -261,7 +268,7 @@ mod tests {
}),
op: Op::Or,
rhs: Box::new(Expr::Operation {
lhs: Box::new(Expr::Bool(true)),
lhs: Box::new(Expr::UnaryNot(Box::new(Expr::Bool(true)))),
op: Op::And,
rhs: Box::new(Expr::Bool(true)),
}),
Expand Down Expand Up @@ -316,11 +323,11 @@ mod tests {
rhs: Box::new(Expr::Bool(false)),
}),
op: Op::Or,
rhs: Box::new(Expr::Operation {
rhs: Box::new(Expr::UnaryNot(Box::new(Expr::Operation {
lhs: Box::new(Expr::Bool(true)),
op: Op::And,
rhs: Box::new(Expr::Bool(false)),
}),
rhs: Box::new(Expr::Bool(true)),
}))),
},
expected_result: false,
},
Expand Down

0 comments on commit d948ff7

Please sign in to comment.