Pest解析器要求let与变量名间空格时解析失败的原因及解决方法
Pest解析器LET规则问题解答
1. 解析失败的原因
Pest默认会自动识别名为WHITESPACE的规则,并在非显式连接(未用~连接)的规则片段之间自动跳过空白。当你用~显式连接规则时,虽然自动跳过逻辑会被局部关闭,但核心问题在于:你的WHITESPACE规则已被Pest设为全局自动跳过的空白规则,解析"let"之后,Pest会自动跳过后面的空格,此时规则里的WHITESPACE+要求匹配至少一个空白,相当于需要"let"后面有至少两个空白字符,但你的输入"let var_name = "string";"里只有一个空格,因此匹配失败。
换成WHITESPACE*时,因为*允许零个匹配,自动跳过空白后零个空白也能满足条件,所以解析成功,但这就失去了强制空格的作用。
2. 强制let与变量名之间必须有空格的方法
有两种可靠的解决方式:
方法一:禁用全局自动空白跳过
在Pest语法文件顶部添加#[no_whitespace]注解,关闭Pest的自动空白跳过功能,所有空白都需要在规则中显式处理。此时原LET规则即可正常工作,WHITESPACE+会强制匹配"let"和变量名之间的至少一个空白:
#[no_whitespace] WHITESPACE = { " " | "\t" | "\n" | "\r" } STRING = @{"\"" ~ (!"\"" | "\n")* ~ "\""} Name = { ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_")* } LET = { "let" ~ WHITESPACE+ ~ Name ~ WHITESPACE* ~ "=" ~ WHITESPACE* ~ STRING ~ WHITESPACE* ~ ";" }
注:已修正你原STRING规则的语法错误(移除了多余的~ ANY)。
方法二:保留自动空白跳过,同时强制let后有空白
若需要保留其他场景的自动空白跳过功能,可以修改let的匹配规则,用否定前瞻断言确保"let"后面不是字母数字(避免letvar这类被误判的情况):
WHITESPACE = { " " | "\t" | "\n" | "\r" } STRING = @{"\"" ~ (!"\"" | "\n")* ~ "\""} Name = { ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_")* } // 用否定前瞻确保let后不是字母数字,必须有分隔符 LetKeyword = { "let" ~ !ASCII_ALPHANUMERIC } LET = { LetKeyword ~ Name ~ WHITESPACE* ~ "=" ~ WHITESPACE* ~ STRING ~ WHITESPACE* ~ ";" }
这里的!ASCII_ALPHANUMERIC会阻止let后面直接跟变量名的字符,强制必须有空白或其他分隔符,同时Pest的自动空白跳过会处理掉这个空白,既满足强制空格的要求,又保留全局自动跳过的能力。
内容的提问来源于stack exchange,提问作者Fly Man
相关产品推荐
相关产品推荐

