add peg
This commit is contained in:
59
peg/Cargo.lock
generated
Normal file
59
peg/Cargo.lock
generated
Normal file
@@ -0,0 +1,59 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "peg"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"peg 0.6.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peg"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9075875c14bb21f25f11cad4b6ad2e4dd443b8fb83900b2fbdd6ebd744b82e97"
|
||||
dependencies = [
|
||||
"peg-macros",
|
||||
"peg-runtime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peg-macros"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c24c165fd39e995246140cc78df55c56c6733ba87e6658cb3e197b8856c62852"
|
||||
dependencies = [
|
||||
"peg-runtime",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peg-runtime"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c1a2897e69d986c7986747ebad425cf03746ec5e3e09bb3b2600f91301ba864"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
11
peg/Cargo.toml
Normal file
11
peg/Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "peg"
|
||||
version = "0.1.0"
|
||||
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
peg = "0.6.2"
|
||||
|
||||
52
peg/src/main.rs
Normal file
52
peg/src/main.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
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());
|
||||
}
|
||||
Reference in New Issue
Block a user