macro_rules! example {
// A
($x:literal) => {
concat!("a", $x)
};
// B
(foo($x:literal)) => {
concat!("b", $x)
};
// C
(foo($x:literal),$($e:expr),*) => {
concat!("c", ".foo(", $x, ")", example!{$($e),*})
};
// D
($x:literal,$($e:expr),*) => {
concat!("d", ".foo(", $x, ")", example!{$($e),*})
};
}
fn main() {
// 进入规则A,正常输出bbar
println!(
"{}",
example! {
foo("bar")
}
);
// 进入规则D,报错 error: no rules expected the token `foo("1")`
println!(
"{}",
example! {
foo("0"),
"a",
foo("1")
}
);
}
为啥第一次可以正确执行,第二次却不行?
1
共 1 条评论, 1 页
评论区
写评论(token stream) foo(0), 1, foo(2)
第一次展开匹配到了
(foo($x:literal),$($e:expr),*)
,递归展开接下来的部分(AST expr) 1, (AST expr) foo(2)
由于 expr 1 是一个 AST literal 项,因此匹配到
($x:literal,$($e:expr),*)
规则,递归展开匹配(AST expr) foo(2)
这里无法继续匹配,不能匹配到
(foo($x:literal))
,这个只能匹配到 token stream,而传来的是一个 AST Expression tree。如果添加一个项
($e:expr) => {concat!("AST expr:", stringify!($e))}
就可以继续匹配了。