Pegjs解析数字开头字符串报错,如何修改语法规则满足需求
问题原因
PEG.js的分支匹配按顺序执行,且默认不回溯未完成的分支:当前代码优先匹配NUMBER规则,输入1abcd时会先匹配到开头的1作为数字,后续遇到a不符合数字规则时直接抛出错误,不会回退尝试STRING分支。同时原NUMBER规则的两个分支存在重叠,[0-9\.]+已经覆盖纯整数场景,导致纯整数分支永远不会触发。
修改方案
var parser = peg.generate(` start = number:NUMBER !. { return { case: "=", item: number } } / string:STRING { return { case: "=", item: string.join("") } } NUMBER = int:[0-9]+ "." dec:[0-9]+ { return parseFloat(int.join("") + "." + dec.join("")); } / int:[0-9]+ { return parseInt(int.join(""), 10); } STRING = string:[^*]+ { return string; } `); console.log(parser.parse("123")) console.log(parser.parse("123.45")) console.log(parser.parse("abcd")) console.log(parser.parse("abcd-efgh")) console.log(parser.parse("1abcd"))
修改说明
- 给
start的NUMBER匹配分支增加!.断言:表示匹配完数字后必须到达输入结尾,没有剩余字符。如果匹配完数字后还有其他内容,该分支自动失效,回溯尝试STRING分支。 - 调整
NUMBER规则的匹配逻辑:先匹配明确带小数点的浮点数格式,再匹配纯整数格式,解决原规则分支重叠的问题,保证整数、浮点数都能正确转换为对应类型。
修改后所有测试用例均可正常输出,输入1abcd时会自动匹配STRING分支,返回{ item: '1abcd', case: '=' }的预期结果。
内容的提问来源于stack exchange,提问作者kiran
相关产品推荐
相关产品推荐

