1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#[macro_export]
macro_rules! grammar {
    (start $s:ident; $($tail:tt)+) => {
        {
            use $crate::grammar::GrammarBuilder;
            let builder = GrammarBuilder::<&'static str, _>::new()
                .start(stringify!($s));
            let builder = grammar!(with builder builder | $($tail)+);
            builder.build()
        }
    };
    (with builder $builder:ident | rule $left:ident -> $($tail:tt)+) => {
        {
            let builder = $builder.push_rule_left(stringify!($left));
            grammar!(with builder builder in rule | $($tail)+)
        }
    };
    (with builder $builder:ident | ) => {
        {
            $builder
        }
    };
    (with builder $builder:ident in rule | epsilon ; $($tail:tt)*) => {
        {
            grammar! { with builder $builder | $($tail)* }
        }
    };
    (with builder $builder:ident in rule | $n:ident, $($tail:tt)+) => {
        {
            let builder = $builder.push_rule_right_nonterminal(stringify!($n));
            grammar! ( with builder builder in rule | $($tail)+ )
        }
    };
    (with builder $builder:ident in rule | $t:expr, $($tail:tt)+) => {
        {
            let builder = $builder.push_rule_right_terminal($t);
            grammar! { with builder builder in rule | $($tail)+ }
        }
    };
    (with builder $builder:ident in rule | $n:ident; $($tail:tt)*) => {
        {
            let builder = $builder.push_rule_right_nonterminal(stringify!($n));
            grammar! { with builder builder | $($tail)* }
        }
    };
    (with builder $builder:ident in rule | $t:expr; $($tail:tt)*) => {
        {
            let builder = $builder.push_rule_right_terminal($t);
            grammar! { with builder builder | $($tail)* }
        }
    };
}