-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathexpr.rs
26 lines (23 loc) · 838 Bytes
/
expr.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
use untwine::{parser, parser_repl};
fn operate(left: f64, op: char, right: f64) -> f64 {
match op {
'+' => left + right,
'-' => left - right,
'/' => left / right,
'*' => left * right,
_ => unreachable!(),
}
}
parser! {
[recover = true]
sep = #{char::is_ascii_whitespace}*;
num: num=<'0'-'9'+ ("." '0'-'9'+)?> -> f64 { num.parse().unwrap() }
term = (num | negation | "(" sep expr sep ")") -> f64;
negation: "-" value=term -> f64 { -value }
add: first=mul sep ops=(["+-"] sep mul)* -> f64 { ops.into_iter().fold(first, |left, (op, right)| operate(left, op, right)) }
mul: first=term sep ops=(["*/"] sep term)* -> f64 { ops.into_iter().fold(first, |left, (op, right)| operate(left, op, right)) }
pub expr = add -> f64;
}
fn main() {
parser_repl(expr);
}