macro_rules! string { ($x:ident) => { stringify!($x).to_owned() }; } macro_rules! make_grammar { ( // comma-separated grammar rules $( $lhs:ident -> $( $($arg:ident)* )|* $(|)? ),* $(,)? // backslash for terminals $( % $( $lhs_:ident -> $re:expr ),* $(,)? )? ) => { crate::grammar::Grammar { start: hashset!{ $(string!($lhs),)* }, productions: hashmap!{ $(string!($lhs) => vec![ $(vec![ $(string!($arg),)* ],)* ],)* }, terminals: hashmap!{ $( $(string!($lhs_) => regex::Regex::new($re).unwrap(),)* )? }, first_sets: crate::utils::MapOfSet::default(), } }; }