gramma 0.2.24

Generate a scannerless parser by declaring types.
Documentation
#[macro_export]
macro_rules! assert_let {
    ($pat:pat = $value:expr, $msg:literal $(, $($args:tt)+)?) => {
        let $pat = (match $value {
            #[allow(unused)]
            actual if matches!(actual, $pat) => actual,
            actual => panic!(
                "Assertion failed: matches!({}, {});\n{}",
                stringify!($value),
                stringify!($pat),
                format_args!($msg, actual = actual, $($args)*),
            ),
        }) else {
            unreachable!()
        };
    };
    ($pat:pat = $value:expr) => {
        $crate::assert_let!($pat = $value, " Actual: {actual:?}")
    };
}

#[macro_export]
macro_rules! parameterize {
    (@mod attrs = (); $(#$attrs:tt)* $vis:vis mod $Mod:ident ;) => {
        $crate::parameterize! { @mod
            attrs = ();
            $(#$attrs)*
            $vis mod $Mod {}
        }
    };
    (@mod attrs = $attrs0:tt; #[params = $Macro:ident $params:tt] $(#$attrs1:tt)* $vis:vis mod $Mod:ident { $($body:tt)* }) => {
        $crate::parameterize! { @mod
            attrs = $attrs0;
            $(#$attrs1)*
            $vis mod $Mod {
                $Macro! $params;
                $($body)*
            }
        }
    };
    (@mod attrs = ($($attrs0:tt)*); #$attr:tt $(#$attrs1:tt)* $vis:vis mod $Mod:ident $body:tt) => {
        $crate::parameterize! { @mod
            attrs = ($($attrs0)* #$attr);
            $(#$attrs1)*
            $vis mod $Mod $body
        }
    };
    (@mod attrs = ($($attrs0:tt)*); $vis:vis mod $Mod:ident { $($body:tt)* }) => {
        $(#$attrs0)*
        $vis mod $Mod {
            #[allow(unused_imports)]
            use super::*;
            $crate::parameterize! { $($body)* }
        }
    };
    () => {};
    ($(macro $Macro:ident ($($arg:tt)*) { $($body:tt)* })+ $($rest:tt)*) => {
        $(macro_rules! $Macro {
            ($($arg)*) => { $crate::parameterize! { $($body)* } };
        })+
        $crate::parameterize! { $($rest)* }
    };
    ($($(#$attrs:tt)* pub mod $Mod:ident $body:tt)+ $($rest:tt)*) => {
        $($crate::parameterize! { @mod
            attrs = ();
            $(#$attrs)*
            pub mod $Mod $body
        })+
        $crate::parameterize! { $($rest)* }
    };
    ($(#$attrs:tt)* $vis:vis mod $Mod:ident $body:tt $($rest:tt)*) => {
        $crate::parameterize! { @mod
            attrs = ();
            $(#$attrs)*
            $vis mod $Mod $body
        }
        $crate::parameterize! { $($rest)* }
    };
    ($item:item $($rest:tt)*) => {
        $item
        $crate::parameterize! { $($rest)* }
    };
    ($item:stmt; $($rest:tt)*) => {
        $item;
        $crate::parameterize! { $($rest)* }
    };
}