1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
/*! A simple binary expression tree, for parsing and preparing expressions which can be executed on dynamic contents. # Example of parsing and evaluating a boolean expression In this example bet helps parsing 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 and OR operating on booleans #[derive(Debug, Clone, Copy, PartialEq)] enum BoolOperator { And, Or, } impl Default for BoolOperator { fn default() -> Self { Self::And } } impl BoolOperator { fn eval(self, a: bool, b: bool) -> bool { match self { Self::And => a & b, Self::Or => a | b, } } } fn parse(input: &str) -> BeTree<BoolOperator, char> { let mut expr = BeTree::new(); for c in input.chars() { match c { '&' => expr.push_operator(BoolOperator::And), '|' => expr.push_operator(BoolOperator::Or), ' ' => {}, '(' => expr.open_par(), ')' => expr.close_par(), _ => expr.push_atom(c), } } expr } let expr = parse("(A | B) & (C | D | E)"); assert_eq!( expr.eval( |&c| c=='A'||c=='C'||c=='E', |op, a, b| op.eval(a, b), ), Some(true), ); assert_eq!( expr.eval( |&c| c=='A'||c=='B', |op, a, b| op.eval(a, b), ), Some(false), ); // Let's show the left to right evaluation order // and importance of parenthesis assert_eq!( parse("(A & B) | (C & D)").eval( |&c| c=='A' || c=='B' || c=='C', |op, a, b| op.eval(a, b), ), Some(true), ); assert_eq!( parse("A & B | C & D").eval( |&c| c=='A' || c=='B' || c=='C', |op, a, b| op.eval(a, b), ), Some(false), ); ``` */ mod be_tree; pub use { be_tree::BeTree, };