Skip to content

Commit ea5d44c

Browse files
ssmendon39555lu-zero
committed
feat: Add a Pratt parser
Adds a new operator precedence parser. Co-authored-by: Igor <[email protected]> Co-authored-by: Luca Barbato <[email protected]>
1 parent c56d4fb commit ea5d44c

File tree

8 files changed

+1416
-0
lines changed

8 files changed

+1416
-0
lines changed

Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ name = "arithmetic"
161161
test = true
162162
required-features = ["alloc"]
163163

164+
[[example]]
165+
name = "c_expression"
166+
required-features = ["std"]
167+
164168
[[example]]
165169
name = "css"
166170
test = true
@@ -211,6 +215,12 @@ path = "examples/arithmetic/bench.rs"
211215
harness = false
212216
required-features = ["alloc"]
213217

218+
[[bench]]
219+
name = "c_expression"
220+
path = "examples/c_expression/bench.rs"
221+
harness = false
222+
required-features = ["std"]
223+
214224
[[bench]]
215225
name = "contains_token"
216226
harness = false

examples/c_expression/bench.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
mod parser;
2+
3+
use criterion::black_box;
4+
use winnow::prelude::*;
5+
6+
fn pratt(c: &mut criterion::Criterion) {
7+
let i =
8+
"a = 2*-2 / ( &**foo.a->p! -+1) + 3^1 / 4 == 1 * (2 - 7 + 567 *12 /2) + 3*(1+2*( 45 /2))";
9+
parser::pratt_parser.parse(i).expect("should parse");
10+
c.bench_function("pratt_parser", |b| {
11+
b.iter(|| black_box(parser::pratt_parser.parse(i).unwrap()));
12+
});
13+
}
14+
15+
criterion::criterion_group!(benches, pratt);
16+
criterion::criterion_main!(benches);

examples/c_expression/main.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use winnow::prelude::*;
2+
3+
mod parser;
4+
5+
fn main() -> Result<(), lexopt::Error> {
6+
let args = Args::parse()?;
7+
8+
let input = args.input.as_deref().unwrap_or("1 + 1");
9+
match parser::pratt_parser.parse(input) {
10+
Ok(result) => {
11+
println!("{result}");
12+
}
13+
Err(err) => {
14+
println!("FAILED");
15+
println!("{err}");
16+
}
17+
}
18+
19+
Ok(())
20+
}
21+
22+
#[derive(Default)]
23+
struct Args {
24+
input: Option<String>,
25+
}
26+
27+
impl Args {
28+
fn parse() -> Result<Self, lexopt::Error> {
29+
use lexopt::prelude::*;
30+
31+
let mut res = Args::default();
32+
33+
let mut args = lexopt::Parser::from_env();
34+
while let Some(arg) = args.next()? {
35+
match arg {
36+
Value(input) => {
37+
res.input = Some(input.string()?);
38+
}
39+
_ => return Err(arg.unexpected()),
40+
}
41+
}
42+
Ok(res)
43+
}
44+
}

0 commit comments

Comments
 (0)