I need a declarative macro to parse a function.
I wrote one:
macro_rules! parse_fn
{
() => {};
(
$( #[ $Meta : meta ] )*
$( pub )?
fn $Name : ident
$( $Rest : tt )*
)
=>
{
$crate::parse_fn!
{
as DEFINE_FN
as META $( #[ $Meta ] )*
as VIS $( pub )?
as NAME $Name
as INPUT ()
as OUTPUT
as BLOCK {}
as REST
$( #[ $Meta ] )*
$( pub )? fn $Name
$( $Rest )*
}
};
(
as DEFINE_FN
as META $( #[ $Meta : meta ] )*
as VIS $( pub )*
as NAME $Name : ident
as INPUT $Input : tt
as OUTPUT $( -> $Output : ty )?
as BLOCK $Block : block
as REST
$Item : item
$( $Rest : tt )*
)
=>
{
macro_rules! $Name
{
() =>
{
$Item
};
}
$crate::parse_fn!
{
$( $Rest )*
}
};
}
But the problem of my solution is that it does not let pass visibility directive $( pub )?
.
It gives
error: attempted to repeat an expression containing no syntax variables matched as repeating at this depth
There is workaround of duplicating of
(
$( #[ $Meta : meta ] )*
pub
fn $Name : ident
$( $Rest : tt )*
) =>
...
(
$( #[ $Meta : meta ] )*
fn $Name : ident
$( $Rest : tt )*
) =>
...
But that solution is not good enough because visibility prefix is not only optional part, permutation of all combinations is too tedious.
Why am I getting the exception?
Better solution to parse a function?
Problem with visibility directive is solved. Thanks for advice.
Another obstacle is parsing parameters fn f3< T : Clone >()
of a function. Best what I got is here.
It throws error:
error: local ambiguity when calling macro `parse_fn`: multiple parsing options: built-in NTs tt ('Input') or 1 other option.
--> src/bin/problem2.rs:80:8
|
80 | fn f3< T : Clone >( _ : T )
| ^