如何编写捕获括号的宏参数?

时间:2018-03-28 05:09:36

标签: macros rust

我希望编写一个Rust宏,它将整个参数转发给第二个宏 - 即使该参数包含令人兴奋的括号。

这是我到目前为止所尝试的内容:

macro_rules! parse {
    (done) => (println!("done!"));
    (if ($cond:tt) {$then:tt}) => (println!("if! "); parse!($cond); parse($then));
}

macro_rules! forward {
    ($($e:tt)*) => (parse!($($e)*; done));
}

fn main() {
    forward!(if (done) {done} );
}

这不起作用,并产生错误:

error: no rules expected the token `if`

我在这里做错了什么?

编辑:除了简单地将参数转发给forward之外,我希望能够"粘贴"标记; doneforward的参数末尾。有没有办法在保留这种行为的同时完成这项工作?

1 个答案:

答案 0 :(得分:3)

问题是; done中的forward。这里发生的是宏扩展代码一次一个地匹配文字输入令牌。如果一只手臂没有匹配,它会放弃并尝试下一只手臂。当它用完手臂试试时,它必须失败并解释原因。

但输入中的哪个令牌是问题?当有可能涉及多个武器的时候回答是很难的,所以相反它只是挑选第一个令牌并说'#34;这就是问题"。

每当你看到一个宏扩展抱怨输入中的第一个令牌不匹配时,它很可能会在输入中的某些东西中绊倒它。

修复该问题(以及修复错过其parse的{​​{1}}次调用)会产生:

!