После вызова higher!
, x(7)
был проанализирован как полное выражение , содержащееся в макропеременной $xstuff
:
($xstuff:expr, $a:expr) => { /* ... */ }
// ^~~~
Однако ни одно из правил макроса для lower!
не принимает произвольное выражение в качестве первого аргумента, они принимают только маркер x
:
(x, $a:expr) => { /* ... */ }
// ^
(x($b:expr), $a:expr) => { /* ... */ }
// ^
Самое простое решение - поместить те же ограничения, что и x
, в более высокий макрос:
macro_rules! higher {
(x($xstuff:expr), $a:expr) => {
lower!(x($xstuff), $a)
};
}
Альтернативное решение (которое изменяет синтаксис вызова) состоит в том, чтобы не сразу анализировать x(7)
как выражение, а вместо этого - коллекцию деревьев токенов. Вам нужно добавить дополнительную группировку на сайте вызовов, чтобы парсер знал, когда остановиться, хотя:
macro_rules! higher {
(($($xstuff:tt)*), $a:expr) => {
lower!($($xstuff)*, $a)
};
}
fn main() {
higher!((x(7)), '9');
}
Смотри также: