Skip to main content

quantifiers/
quantifiers.rs

1//! # Quantifiers
2//!
3//! Demonstrates every quantifier form — greedy and lazy — and how to read them
4//! from the AST.
5//!
6//! Run with:
7//!   cargo run -p re-parser --example quantifiers
8
9use re_parser::ast::{QuantKind, Regex};
10use re_parser::parse;
11
12fn describe_quant(kind: &QuantKind, greedy: bool) -> String {
13    let mode = if greedy { "greedy" } else { "lazy" };
14    let desc = match kind {
15        QuantKind::ZeroOrMore => "zero-or-more (*)".to_owned(),
16        QuantKind::OneOrMore => "one-or-more (+)".to_owned(),
17        QuantKind::ZeroOrOne => "zero-or-one (?)".to_owned(),
18        QuantKind::Exactly(n) => format!("exactly {n} ({{{n}}})"),
19        QuantKind::AtLeast(n) => format!("at-least {n} ({{{n},}})"),
20        QuantKind::Between(n, m) => format!("between {n} and {m} ({{{n},{m}}})"),
21    };
22    format!("{desc}, {mode}")
23}
24
25fn print_quantifier(pattern: &str) {
26    let ast = parse(pattern).unwrap();
27    match &ast {
28        Regex::Quantifier(inner, kind, greedy) => {
29            println!(
30                "  {pattern:10}  =>  applied to {:?},  {}",
31                inner,
32                describe_quant(kind, *greedy)
33            );
34        }
35        other => println!("  {pattern:10}  =>  {other:?}"),
36    }
37}
38
39fn main() {
40    println!("=== Greedy quantifiers ===");
41    print_quantifier("a*");
42    print_quantifier("a+");
43    print_quantifier("a?");
44    print_quantifier("a{3}");
45    print_quantifier("a{2,}");
46    print_quantifier("a{1,5}");
47
48    println!("\n=== Lazy (non-greedy) quantifiers ===");
49    print_quantifier("a*?");
50    print_quantifier("a+?");
51    print_quantifier("a??");
52    print_quantifier("a{2,6}?");
53
54    println!("\n=== Quantifier applied to a group ===");
55    let pattern = r"(\d+)?";
56    let ast = parse(pattern).unwrap();
57    println!("  {pattern}  =>  {ast:#?}");
58}