You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Rust Pest crate实现自定义语言时语法规则匹配失败求助

Rust Pest crate实现自定义语言时语法规则匹配失败求助

我帮你排查了一下,你遇到的这个解析错误大概率是Pest没有自动忽略空白字符导致的,具体原因和解决方法如下:

核心问题:空白字符未被自动忽略

你虽然定义了WHITESPACE规则,但Pest默认不会自动忽略它——必须显式告诉解析器要跳过空白字符。如果没开启这个设置:

  • 当解析a = in "How are ya? "时,a后面的空格会被视为需要匹配的“有效字符”,而你的assignment规则里ident之后直接期望:=,空格的存在会导致assignment分支匹配失败。
  • 解析器会转而尝试func_call分支:a匹配func_head后,!="="断言会误判(因为当前位置是空格而非=,断言通过),但后续无法匹配expr*(因为空格后是=,不是合法表达式),最终导致所有stmt分支都匹配失败,出现你看到的错误。

快速修复:启用空白忽略

在你的Rust代码中,给#[derive(Parser)]的结构体加上whitespace = "WHITESPACE"参数,告诉Pest自动忽略空白字符:

#[derive(Parser)]
#[grammar = "你的语法文件名.pest", whitespace = "WHITESPACE"]
struct 你的解析器结构体名;

额外优化建议

  1. assignment加前瞻断言
    你注释里提到要“提前确认标识符后有=”,但当前规则没有实现这个逻辑。可以给assignment加上正前瞻,让解析器更快判断是否符合规则,减少不必要的回溯:

    assignment = { ident ~ (":" ~ ident)? ~ &"=" ~ "=" ~ expr }
    

    这里的&"="是正前瞻断言,确保后面确实存在=后再正式匹配它,让规则逻辑更贴合你的预期。

  2. 确认func_call的断言逻辑
    启用空白忽略后,func_call里的!="="会自动跳过空格再检查后续是否是=,这样就能正确区分:

    • a = 1:会匹配assignment分支(因为a后跳过空格能找到=
    • a 1:会匹配func_call分支(因为a后跳过空格是1,不是=

验证修复效果

启用空白忽略后,测试代码里的a = in "How are ya? "应该能被正确解析:

  • a匹配assignmentident
  • 跳过空格后匹配=
  • in "How are ya? "作为expr(属于func_call类型)被正确识别

如果还有问题,可以再检查一下你的Rust代码里是否正确引用了语法文件,以及有没有其他未处理的字符问题~

火山引擎 最新活动