calc/
calc.rs

1use parse_it::ParseIt;
2
3parse_it::parse_it! {
4    #[parse_it(crate = "parse_it")]
5    mod parse {
6        Digit -> char {
7            @['0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'] => self
8        }
9
10        Num -> i32 {
11            digits:Digit+ => digits.into_iter().collect::<String>().parse::<i32>().unwrap(),
12        }
13
14        pub Expr -> i32 {
15            AddExpr => self,
16        }
17
18        AddExpr -> i32 {
19            lhs:AddExpr '+' rhs:MulExpr => {
20                lhs + rhs
21            }
22            lhs:AddExpr '-' rhs:MulExpr => {
23                lhs - rhs
24            }
25            MulExpr => self,
26        }
27
28        MulExpr -> i32 {
29            lhs:MulExpr '*' rhs:Term => {
30                lhs * rhs
31            }
32            lhs:MulExpr '/' rhs:Term => {
33                lhs / rhs
34            }
35            Term => self,
36        }
37
38        Term -> i32 {
39            Num => self,
40            '(' expr:Expr ')' => expr,
41        }
42    }
43}
44
45fn main() {
46    let parser = parse::Expr::default();
47
48    let input = "11+(6-1-1)*(4/2/2)";
49
50    let result = match parser.parse(input) {
51        Ok(value) => value,
52        Err(err) => {
53            println!("span: {}..{}", err.span.start, err.span.end);
54            return;
55        }
56    };
57
58    println!("parser: {}", result);
59    assert_eq!(result, 15);
60}