From 11aae6799e81af539fad1c3224a4d6018f2af1a0 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 5 Jul 2020 15:53:02 +0800 Subject: [PATCH] add peg --- peg/Cargo.lock | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ peg/Cargo.toml | 11 +++++++++ peg/src/main.rs | 52 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 peg/Cargo.lock create mode 100644 peg/Cargo.toml create mode 100644 peg/src/main.rs diff --git a/peg/Cargo.lock b/peg/Cargo.lock new file mode 100644 index 0000000..74b1085 --- /dev/null +++ b/peg/Cargo.lock @@ -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" diff --git a/peg/Cargo.toml b/peg/Cargo.toml new file mode 100644 index 0000000..35f1d40 --- /dev/null +++ b/peg/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "peg" +version = "0.1.0" +authors = ["Hatter Jiang "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +peg = "0.6.2" + diff --git a/peg/src/main.rs b/peg/src/main.rs new file mode 100644 index 0000000..8036dcd --- /dev/null +++ b/peg/src/main.rs @@ -0,0 +1,52 @@ +peg::parser!{ + grammar list_parser() for str { + rule number() -> u32 + = n:$(['0'..='9']+) { n.parse().unwrap() } + + pub rule list() -> Vec + = "[" 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, right: Box, } +impl Node for AddNode { + fn eval(&self) -> i64 { self.left.eval() + self.right.eval() } +} + +#[derive(Debug)] +struct SubNode { left: Box, right: Box, } +impl Node for SubNode { + fn eval(&self) -> i64 { self.left.eval() - self.right.eval() } +} + +peg::parser!{ + grammar expression() for str { + rule number() -> Box + = n:$(['0'..='9']+) { Box::new(NumberNode{ val: n.parse().unwrap() }) } + + pub rule calculate() -> Box = 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()); +}