A simple binary expression tree, for parsing and preparing expressions which can be executed on dynamic contents.
An expression is built by calling the push_operator
, open_par
, close_par
and push_atom
functions.
It can then be evaluated with the eval
function which takes as parameters
Normal evaluation order is left to right but is modified with parenthesis.
This library is very young. Contact me if you think it might be useful to you. I might then consider some additions (for example to deal with optional operator precedence if somebody needs it).
Here we parse the "(A | B) & !(C | D | E)"
expression
and evaluate it with different values of the A
to E
variables.
Then two other expressions are evaluated to display how parenthesis and evaluation work.
``` use bet::*;
/// The operators in this example are AND, OR, and NOT operating on booleans.
/// And
and Or
are binary while Not
is unary.
/// Note that bet doesn't prevent an operator from being usable in both
/// unary and binary contexts.
enum BoolOperator {
And,
Or,
Not,
}
type BoolErr = &'static str;
impl BoolOperator {
fn eval(self, a: bool, b: Option
fn parse(input: &str) -> BeTree
let expr = parse("(A | B) & !(C | D | E)"); asserteq!( expr.eval( |&c| Ok(c=='A'||c=='C'||c=='E'), |op, a, b| op.eval(a, b), ), Ok(Some(false)), ); asserteq!( expr.eval( |&c| Ok(c=='A'||c=='B'), |op, a, b| op.eval(a, b), ), Ok(Some(true)), );
// Let's show the left to right evaluation order // and importance of parenthesis asserteq!( parse("(A & B) | (C & D)").eval( |&c| Ok(c=='A' || c=='B' || c=='C'), |op, a, b| op.eval(a, b), ), Ok(Some(true)), ); asserteq!( parse("A & B | C & D").eval( |&c| Ok(c=='A' || c=='B' || c=='C'), |op, a, b| op.eval(a, b), ), Ok(Some(false)), );
```