File: arithmetic_ast.rs

package info (click to toggle)
rust-peg 0.8.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 756 kB
  • sloc: makefile: 20; sh: 12
file content (63 lines) | stat: -rw-r--r-- 1,936 bytes parent folder | download
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
extern crate peg;
use peg::parser;

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Expression {
    Number(i64),
    Sum(Box<Expression>, Box<Expression>),
    Product(Box<Expression>, Box<Expression>),
}

parser!{
/// Doc comment
grammar arithmetic() for str {
    /// Top level parser rule
    /// This doc comment has multiple lines to test support for that as well
    pub rule expression() -> Expression
        = sum()

    rule _ = [' ' | '\n']*

    rule sum() -> Expression
        = l:product() _ "+" _ r:product() { Expression::Sum(Box::new(l), Box::new(r)) }
        / product()

    rule product() -> Expression
        = l:atom() _ "*" _ r:atom() { Expression::Product(Box::new(l), Box::new(r)) }
        / atom()

    rule atom() -> Expression
        = number()
        / "(" _ v:sum() _ ")" { v }

    rule number() -> Expression
        = n:$(['0'..='9']+) { Expression::Number(n.parse().unwrap()) }
}}

fn main() {
    assert_eq!(arithmetic::expression("1+1"), Ok(Expression::Sum(
        Box::new(Expression::Number(1)),
        Box::new(Expression::Number(1)))
    ));
    assert_eq!(arithmetic::expression("5*5"), Ok(Expression::Product(
        Box::new(Expression::Number(5)),
        Box::new(Expression::Number(5)))
    ));
    assert_eq!(arithmetic::expression("2+3*4"), Ok(Expression::Sum(
        Box::new(Expression::Number(2)),
        Box::new(Expression::Product(
            Box::new(Expression::Number(3)),
            Box::new(Expression::Number(4))
        )),
    )));
    assert_eq!(arithmetic::expression("(2+3) * 4"), Ok(Expression::Product(
        Box::new(Expression::Sum(
            Box::new(Expression::Number(2)),
            Box::new(Expression::Number(3)),
        )),
        Box::new(Expression::Number(4))
    )));
    assert!(arithmetic::expression("(22+)+1").is_err());
    assert!(arithmetic::expression("1++1").is_err());
    assert!(arithmetic::expression("3)+1").is_err());
}