forked from kevinmehall/rust-peg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
arithmetic_infix.rs
31 lines (27 loc) · 931 Bytes
/
arithmetic_infix.rs
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
extern crate peg;
peg::parser!( grammar arithmetic() for str {
rule number() -> i64
= n:$(['0'..='9']+) { n.parse().unwrap() }
pub(crate) rule calculate() -> i64 = precedence!{
x:(@) "+" y:@ { x + y }
x:(@) "-" y:@ { x - y }
"-" v:@ { - v }
--
x:(@) "*" y:@ { x * y }
x:(@) "/" y:@ { x / y }
--
x:@ "^" y:(@) { x.pow(y as u32) }
v:@ "!" { (1..v+1).product() }
--
"(" v:calculate() ")" { v }
n:number() {n}
}
});
fn main() {
assert_eq!(arithmetic::calculate("3+3*3+3"), Ok(15));
assert_eq!(arithmetic::calculate("2+2^2^2^2/2+2"), Ok(32772));
assert_eq!(arithmetic::calculate("1024/2/2/2+1"), Ok(129));
assert_eq!(arithmetic::calculate("1024/(1+1)/2/2+1"), Ok(129));
assert_eq!(arithmetic::calculate("-1-2*-2"), Ok(3));
assert_eq!(arithmetic::calculate("1+3!+1"), Ok(8));
}