Rust递归宏无法递归解析带!的表达式问题咨询
Rust递归宏处理感叹号时的编译错误分析与解决
问题根源
Rust宏的解析依赖**TokenTree(令牌树)**而非原始文本。单独调用宏处理!'a'时,宏解析器会将其拆分为!和'a'两个独立令牌,能匹配对应规则;但递归调用时,如果宏规则没正确拆分令牌树,直接把!'a'作为整体传入递归宏,解析器会将其视为一个无法匹配任何规则的复合令牌,从而抛出no rules expected the token !'a'`错误。本质是宏展开时的令牌是结构化的树,不会自动重新拆分组合后的令牌。
解决方法
确保递归调用时传递拆分后的独立令牌,而非复合令牌。以下是正确的宏实现示例:
macro_rules! strip_exclamation { // 优先匹配带!开头的表达式,剥离!后递归处理内部表达式 (! $expr:expr) => { strip_exclamation!($expr) }; // 匹配不带!的基础表达式,直接返回 ($expr:expr) => { $expr }; } fn main() { // 单独调用场景 let x = strip_exclamation!(!'a'); assert_eq!(x, 'a'); // 递归嵌套场景 let y = strip_exclamation!(!(!'b')); assert_eq!(y, 'b'); }
核心要点:
- 规则顺序优先:把匹配
! $expr的规则放在前面,避免被通用表达式规则优先匹配 - 递归传递拆分后的令牌:每次递归只传入解析器能识别的合法表达式令牌,而非复合的
!'a'这类结构
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

