53 lines
1.4 KiB
Rust
53 lines
1.4 KiB
Rust
peg::parser!{
|
|
grammar list_parser() for str {
|
|
rule number() -> u32
|
|
= n:$(['0'..='9']+) { n.parse().unwrap() }
|
|
|
|
pub rule list() -> Vec<u32>
|
|
= "[" l:number() ** "," "]" { l }
|
|
}
|
|
}
|
|
|
|
pub trait Node : std::fmt::Debug { fn eval(&self) -> i64; }
|
|
|
|
#[derive(Debug)]
|
|
struct NumberNode { val: i64, }
|
|
impl Node for NumberNode {
|
|
fn eval(&self) -> i64 { self.val }
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct AddNode { left: Box<dyn Node>, right: Box<dyn Node>, }
|
|
impl Node for AddNode {
|
|
fn eval(&self) -> i64 { self.left.eval() + self.right.eval() }
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct SubNode { left: Box<dyn Node>, right: Box<dyn Node>, }
|
|
impl Node for SubNode {
|
|
fn eval(&self) -> i64 { self.left.eval() - self.right.eval() }
|
|
}
|
|
|
|
peg::parser!{
|
|
grammar expression() for str {
|
|
rule number() -> Box<dyn Node>
|
|
= n:$(['0'..='9']+) { Box::new(NumberNode{ val: n.parse().unwrap() }) }
|
|
|
|
pub rule calculate() -> Box<dyn Node> = precedence!{
|
|
x:(@) "+" y:@ { Box::new(AddNode{ left: x, right: y, }) }
|
|
x:(@) "-" y:@ { Box::new(SubNode{ left: x, right: y, }) }
|
|
--
|
|
"(" v:calculate() ")" { v }
|
|
n:number() {n}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
println!("{:?}", list_parser::list("[1,1,2,3,5,8]"));
|
|
|
|
let a = expression::calculate("111+444-333");
|
|
println!("{:?}", a);
|
|
println!("{}", a.unwrap().eval());
|
|
}
|