gpt4 book ai didi

rust - 为什么在尝试使用外部宏的参数调用内部宏时得到 "unexpected token"?

转载 作者:行者123 更新时间:2023-11-29 08:28:48 24 4
gpt4 key购买 nike

在尝试将 higher! 宏接收到的表达式传递给 lower! 宏时,我不明白这个失败:

// A low-level macro using only Rust primitives.
macro_rules! lower {
(x, $a:expr) => {
println!("x is {}", $a);
};
(x($b:expr), $a:expr) => {
println!("x({}) is rather {}", $b, $a);
};
}

// A higher-level macro using my own previous macro.
macro_rules! higher {
($xstuff:expr, $a:expr) => {
// Here, I expect transferring the expression $xstuff to lower!.. but it fails.
lower!($xstuff, $a)
};
}

fn main() {
lower!(x, '5'); // x is 5
lower!(x(8), '6'); // x(8) is rather 6

higher!(x(7), '9');
}
error: no rules expected the token `x(7)`
--> src/main.rs:15:16
|
2 | macro_rules! lower {
| ------------------ when calling this macro
...
15 | lower!($xstuff, $a)
| ^^^^^^^ no rules expected this token in macro call
...
23 | higher!(x(7), '9');
| ------------------- in this macro invocation

我希望这最后一个标记符合 lower! 中的规则,但编译器告诉我这是意外的。我在这里错过了什么?如何将 higher! 接收到的表达式作为 $xstuff 传输到 lower!

最佳答案

调用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) 解析为表达式,而是将其解析为 token 树的集合。您需要在调用站点添加额外的分组,以便解析器知道何时停止:

macro_rules! higher {
(($($xstuff:tt)*), $a:expr) => {
lower!($($xstuff)*, $a)
};
}

fn main() {
higher!((x(7)), '9');
}

另见:

关于rust - 为什么在尝试使用外部宏的参数调用内部宏时得到 "unexpected token"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56690039/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com