beans 6.6.0

A parser generator library based on the Earley parser
Documentation
#[macro_export]
macro_rules! rules {
    (@rule($grammar:expr) proxy insert $proxy: ident $key: ident bool $value: literal) => {
	$proxy.insert(stringify!($key).into(), $crate::parser::grammarparser::ValueTemplate::Bool($value));
    };
    (@rule($grammar:expr) proxy insert $proxy: ident $key: ident str $value: literal) => {
	$proxy.insert(
	    stringify!($key).into(),
	    $crate::parser::grammarparser::ValueTemplate::Str(
		Rc::from($value)
	    )
	);
    };
    (@rule($grammar:expr) proxy $($key: ident = $type: ident $value: literal)*) => {
	{
	    #[allow(unused_mut)]
	    let mut proxy = Proxy::new();
	    $(
		rules!(@rule($grammar) proxy insert proxy $key $type $value);
	    )*
		proxy
	}
    };
    (@rule($grammar:expr) key) => { None };
    (@rule($grammar:expr) key $key: ident) => { Some(::std::rc::Rc::from(stringify!($key))) };
    (@rule($grammar:expr) attribute) => { Attribute::None };
    (@rule($grammar:expr) attribute str $attribute: ident) => { Attribute::Named(stringify!($attribute).to_string()) };
    (@rule($grammar:expr) attribute idx $attribute: literal) => { Attribute::Indexed($attribute) };
    (@rule($grammar:expr) terminality t) => { TestElementType::Terminal };
    (@rule($grammar:expr) terminality n) => { TestElementType::NonTerminal };
    (@rule($grammar:expr) terminality) => { TestElementType::NonTerminal };
    (@rule($grammar:expr) element $(! $terminality: tt)? $name: ident $(. $type: ident $attribute: tt)? $(@ $key: tt)?) => {
	TestElement {
	    name: stringify!($name).to_string(),
	    attribute: rules!(@rule($grammar) attribute $($type $attribute)?),
	    key: rules!(@rule($grammar) key $($key)?),
	    element_type: rules!(@rule($grammar) terminality $($terminality)?)
	}
    };
    (($grammar:expr)
	$(
	    $name: ident ::= $(
		$(
		    $(! $terminality: tt)?
		    $element: ident
			$(
			    . $attribute_type: ident $attribute: literal
			)?
		    $(
			@ $key: tt
		    )?
		)*
		    < $(
			$proxy_key: ident = $proxy_type: ident $proxy_value: literal
		    )* >
	    )*
	);*
    ) => {
	{
	    let mut result = Vec::new();
	    $({
		let name = stringify!($name);
		$(
		    let elements = vec![$(
			rules!(
			    @rule($grammar)
				element $(! $terminality)? $element
				$(. $attribute_type $attribute)? $(@ $key)?
			)
		    ),*];
		    let proxy = rules!(@rule($grammar) proxy $($proxy_key = $proxy_type $proxy_value)*);
		    result.push(TestRule::new(name, elements, proxy, $grammar));
		)*
	    })*
		result
	}
    };
}