]> git.proxmox.com Git - rustc.git/blob - src/vendor/pest/examples/calculator.rs
New upstream version 1.17.0+dfsg1
[rustc.git] / src / vendor / pest / examples / calculator.rs
1 #[macro_use]
2 extern crate pest;
3
4 use pest::prelude::*;
5
6 impl_rdp! {
7 grammar! {
8 // precedence climbing
9 expression = _{ // rule is silent because it's the rule we're matching
10 { ["("] ~ expression ~ [")"] | number } // primary
11 addition = { plus | minus } // precedence 0
12 multiplication = { times | slash } // precedence 1
13 }
14 number = @{ ["-"]? ~ (["0"] | ['1'..'9'] ~ ['0'..'9']*) } // atomic because it cannot
15 plus = { ["+"] } // accept white-space
16 minus = { ["-"] }
17 times = { ["*"] }
18 slash = { ["/"] }
19
20 whitespace = _{ [" "] } // whitespce gets run between all rules
21 }
22
23 process! {
24 compute(&self) -> i32 { // return an i32 in the end
25 (&number: number) => number.parse::<i32>().unwrap(), // capture number as &str
26 (_: addition, left: compute(), sign, right: compute()) => { // get left & right by
27 match sign.rule { // calling compute
28 Rule::plus => left + right,
29 Rule::minus => left - right,
30 _ => unreachable!()
31 }
32 },
33 (_: multiplication, left: compute(), sign, right: compute()) => {
34 match sign.rule {
35 Rule::times => left * right,
36 Rule::slash => left / right,
37 _ => unreachable!()
38 }
39 }
40 }
41 }
42 }
43
44 fn main() {
45 let mut parser = Rdp::new(StringInput::new("(3 + (9 + 3 * 4 + (3 + 1) / 2 - 4)) * 2"));
46
47 parser.expression();
48
49 println!("{}", parser.compute()); // prints 44
50 }