Skip to content

Commit

Permalink
Added calculator example and improved documentation. Fixes pest-parse…
Browse files Browse the repository at this point in the history
  • Loading branch information
dragostis committed Jun 5, 2016
1 parent ba1da63 commit e51144f
Show file tree
Hide file tree
Showing 6 changed files with 628 additions and 10 deletions.
55 changes: 55 additions & 0 deletions examples/calculator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#[macro_use]
extern crate pest;

use pest::Parser;
use pest::Token;
use pest::Input;
use pest::StringInput;

impl_rdp! {
grammar! {
// precedence climbing
expression = _{ // rule is silent because it's the rule we're matching
{ ["("] ~ expression ~ [")"] | number } // primary
addition = { plus | minus } // precedence 0
multiplication = { times | slash } // precedence 1
}
number = @{ ["-"]? ~ (["0"] | ['1'..'9'] ~ ['0'..'9']*) } // atomic because it cannot
plus = { ["+"] } // accept white-space
minus = { ["-"] }
times = { ["*"] }
slash = { ["/"] }

whitespace = _{ [" "] } // whitespce gets run between all rules
}

process! {
(&self) -> i32 { // return an i32 in the end
(&number: number) => { // capture number as &str
number.parse::<i32>().unwrap()
},
(_: addition, @left, sign, @right) => { // get left & right by calling process
match sign.rule { // recursively with @
Rule::plus => left + right,
Rule::minus => left - right,
_ => unreachable!()
}
},
(_: multiplication, @left, sign, @right) => {
match sign.rule {
Rule::times => left * right,
Rule::slash => left / right,
_ => unreachable!()
}
}
}
}
}

fn main() {
let mut parser = Rdp::new(StringInput::new("(3 + (9 + 3 * 4 + (3 + 1) / 2 - 4)) * 2"));

parser.expression();

println!("{}", parser.process()); // prints 44
}
9 changes: 5 additions & 4 deletions src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
///
/// Silent rules work like normal rules without appearing in
/// [`Parser::queue`](trait.Parser#tymethod.queue) or
/// [`Parser::expected`]((trait.Parser#tymethod.expected).
/// [`Parser::expected`](trait.Parser#tymethod.expected).
///
/// ```ignore
/// whitespace = _{ [" "] }
Expand Down Expand Up @@ -85,14 +85,15 @@
/// ```ignore
/// expression = _{
/// { ["("] ~ expression ~ [")"] | number }
/// addition = { plus | minus }
/// multiplication = { times | slash }
/// addition = { plus | minus }
/// multiplication = { times | slash }
/// power = {< pow } // < for right-associativity
/// }
/// ```
///
/// The first part of the precedence climbing rule is the primary expression that comes between
/// braces. It's followed by any number of rules, each rule having a precedence higher than the
/// previous one.
/// previous one. The `<` denote right-associativity, the default being left-associativity.
///
/// # Examples
///
Expand Down

0 comments on commit e51144f

Please sign in to comment.