Skip to content

Commit 961694e

Browse files
39555ssmendon
andcommitted
docs(comb): Add Pratt parsing example
This commit adds a new example `c_expression` for the Pratt parser added to the `expression` module. It also adds this example to the language special topic. This example was primarily authored by @39555 in PR #622. @ssmendon rebased it to the newest release of winnow and added extra documentation. Co-authored-by: Sohum Mendon <[email protected]>
1 parent ce14cc9 commit 961694e

File tree

6 files changed

+739
-1
lines changed

6 files changed

+739
-1
lines changed

Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,17 @@ required-features = ["alloc"]
205205
name = "string"
206206
required-features = ["alloc"]
207207

208+
[[example]]
209+
name = "c_expression"
210+
required-features = ["std"]
211+
212+
213+
[[bench]]
214+
name = "c_expression"
215+
path = "examples/c_expression/bench.rs"
216+
harness = false
217+
required-features = ["std"]
218+
208219
[[bench]]
209220
name = "arithmetic"
210221
path = "examples/arithmetic/bench.rs"

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)