On Tue, Feb 19, 2013 at 6:43 PM, Paul Stansifer <[email protected]>wrote:
> Alternation already exists, at least at the outer level:
>
> macro_rules! alt_example(
> ( cons($e1:expr, $e2:expr) ) => ( ... )
> ( mt() ) => ( ... )
> )
>
> Of course, making use of it for something other than a whole macro
> invocation requires the use of a helper macro, which can be tricky if the
> helper macro wants to be invoked somewhere that macro invocations can't yet
> go.
>
> There's generally some way around this sort of problem, typically
> involving continuation-passing-style at the macro level. Since you can't
> generate patterns, you'll want to generate a whole match (as you are
> doing), and since you want to process each arm on its own (in order to do
> pattern-matching), you'll want to process one at a time, accumulating your
> work into some sort of accumulator argument.
>
One thing this does is force all the alternatives to follow the same form
so that they can be matched by the same matcher, which isn't always
desirable.
Also, I ran into something I can't explain trying to use this approach.
This works:
macro_rules! make_vec(
($($n:ident),*) => (make_vec_rec!($($n),* :));
)
macro_rules! make_vec_rec(
(a $(,$n1:ident)* : $($n2:expr),*) => (make_vec_rec!($($n1),* : $($n2,)*
1));
(b $(,$n1:ident)* : $($n2:expr),*) => (make_vec_rec!($($n1),* : $($n2,)*
2));
(: $($n2:expr),*) => ([$($n2),*]);
)
But this is ambiguous:
macro_rules! make_vec(
($($n:ident),*) => (make_vec_rec!(($($n),*)()));
)
macro_rules! make_vec_rec(
((a $(,$n1:ident)*)($($n2:expr),*)) =>
(make_vec_rec!(($($n1),*)($($n2,)* 1)));
((b $(,$n1:ident)*)($($n2:expr),*)) =>
(make_vec_rec!(($($n1),*)($($n2,)* 2)));
(()($($n2:expr),*)) => ([$($n2),*]);
)
Documents/test.rs:85:45: 85:46 error: Local ambiguity: multiple parsing
options: built-in NTs expr ('
n2') or 1 other options.
Documents/test.rs:85 ($($n:ident),*) => (make_vec_rec!(($($n),*)()));
(`^` pointing at `()`)
Any idea why? () could be considered an expression, but it's not in an
expression position, and a lot of things could be considered expressions
and don't do this.
Abusing repetition to get around this is probably equally legitimate
>
My only concern would be whether there are cases where this abuse causes
unexpected behaviour rather than a syntax error when given incorrect input,
though I can't think of any off the top of my head.
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev