calc/
calc.rs

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