lol*_*lad 0 macros compiler-errors rust
我在宏中调用宏,即
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);
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨我在调用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)
Run Code Online (Sandbox Code Playgroud)
为什么它不扩展?
宏是用其未扩展的参数调用的。macro_call!(arg)是三令牌树,而不是一棵:
macro_rules! example {\n ($($x:tt)+) => {\n $(eprintln!(">{}<", stringify!($x));)*\n }\n}\n\nfn main() {\n example!(macro_call!(arg));\n}\nRun Code Online (Sandbox Code Playgroud)\n>macro_call<\n>!<\n>(arg)<\nRun Code Online (Sandbox Code Playgroud)\n您的宏仅允许单个标记树 ( $args: tt)。这与宏的名称匹配,留下!. 这与任何内容都不匹配,所以你会得到错误。
你可能想要$args: expr。
\n\n之前有办法扩展吗?我想手动解析数组的一些元素
\n
据我所知,还没有“更热切”的扩张。它已在各种 RFC 中建议(例如Eager Macro Expansion \xe2\x80\x94 2320)。
\n我建议重排您的代码,以便parse_rule调用foo/本身,或者将/bar的逻辑直接烘焙到. 内部规则对此很常见。foobarparse_rule
也可以看看:
\n\n| 归档时间: |
|
| 查看次数: |
1340 次 |
| 最近记录: |