gpt4 book ai didi

rust - 为什么另一个宏内的宏调用不会扩展,而是出现 “no rules expected the token ` !`”?

转载 作者:行者123 更新时间:2023-12-03 07:37:40 26 4
gpt4 key购买 nike

我在宏中调用宏,即

macro_rules! foo {
(yes) => {
true
};
() => {
false
};
}

macro_rules! baz {
() => {
[(); 0]
};
($args: tt) => {
$args
};
}

macro_rules! parse_rule {
($rule: tt, $args: tt, $newline: expr) => {
println!("The rule is {}, with args {:?}", $rule, $args);
if $newline {
println!()
}
};
}

macro_rules! bar {
($($rule: tt $([$($args: tt),*])? $($flag: ident)?);+) => {
$(parse_rule!($rule, baz!($([$($args),*])?), foo!($($flag)?)));+
}
}

fn main() {
bar!("hi" yes; "there" ["are", "some", "args"]; "no" yes);
}
编译器提示我在 baz调用中调用 parse_rule:
error: no rules expected the token `!`
--> src/main.rs:30:33
|
19 | macro_rules! parse_rule {
| ----------------------- when calling this macro
...
30 | $(parse_rule!($rule, baz!($([$($args),*])?), foo!($($flag)?)));+
| ^ no rules expected this token in macro call
...
35 | bar!("hi" yes; "there" ["are", "some", "args"]; "no" yes);
| ---------------------------------------------------------- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
为什么不扩展?

最佳答案

宏将使用其未扩展的参数来调用。 macro_call!(arg)的三棵 token 树,而不是一棵:

macro_rules! example {
($($x:tt)+) => {
$(eprintln!(">{}<", stringify!($x));)*
}
}

fn main() {
example!(macro_call!(arg));
}
>macro_call<
>!<
>(arg)<
您的宏仅允许使用单个 token 树( $args: tt)。匹配宏的名称,保留 !。没有任何匹配,因此您会遇到错误。
您可能需要 $args: expr

is there a way to expand it before? I want to parse some of the elements of the array manually


据我所知,没有“更渴望”的扩展。在各种RFC(例如 Eager Macro Expansion — 2320)中都提出了建议。
我建议您对代码进行重排,以便 parse_rule调用 foo/ bar本身,或者将 foo/ bar的逻辑直接烘焙到 parse_rule中。内部规则对此非常普遍。
也可以看看:
  • What does an @ symbol mean in a Rust declarative macro?
  • 关于rust - 为什么另一个宏内的宏调用不会扩展,而是出现 “no rules expected the token ` !`”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65204193/

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