如何让Rust宏匹配除逗号外的所有token tree?
解决Rust宏
local ambiguity问题:匹配除逗号外的顶级Token Tree 原宏定义因tt会匹配逗号,导致编译器无法区分逗号是条目内容还是分隔符,触发local ambiguity when calling macro 'foo'错误。我们需要让宏准确匹配顶级逗号分隔的条目(条目内部的括号、逗号不受影响,比如0(t1)这类结构),最终生成指定的数组结构。
正确宏实现
macro_rules! foo { // 空输入时返回空数组 () => { [] }; // 匹配带后续逗号的条目 + 剩余内容 ( $($entry:tt)+ , $($rest:tt)* ) => { [ bar!($($entry)+), $(foo!($($rest)*)),* ] }; // 匹配最后一个条目(无后续逗号) ( $($entry:tt)+ ) => { [ bar!($($entry)+) ] }; }
原理说明
- 利用递归匹配逻辑,逐个识别顶级逗号分隔的条目:
- 第二个分支先匹配一组连续的Token Tree(
$($entry:tt)+),直到遇到顶级逗号,将这组Token传给bar!,再递归处理剩余内容。 - 第三个分支处理最后一个没有尾随逗号的条目。
- 第一个分支处理空输入的边界情况。
- 第二个分支先匹配一组连续的Token Tree(
测试验证
输入示例:
foo!( add t0 zero zero, add t1 t0 a0, lb t1 0(t1), )
生成结果:
[ bar!(add t0 zero zero), bar!(add t1 t0 a0), bar!(lb t1 0(t1)), ]
原宏错误原因
原宏$( $( $tok:tt )* ,)*的写法存在歧义:$tok:tt可以匹配任意Token Tree(包括逗号),编译器无法判断某个逗号是属于当前条目内容,还是作为条目分隔符,因此抛出local ambiguity错误。
内容的提问来源于stack exchange,提问作者uben
相关产品推荐
相关产品推荐

