使用nearley.js与moo.js开发编程语言时遇WS token解析错误
解决Nearley.js + Moo.js中的WS Token解析错误
问题重现
运行解析器时出现以下错误:
Unexpected WS token: " ". Instead, I was expecting to see one of the following: A identifier token based on: var_assign → ● %identifier _ "=" _ expr A identifier token based on: fun_call → ● %identifier _ "(" _ fun_call$ebnf$1 ")" at Parser.feed (C:\Users\mcqui\OneDrive\Desktop\Programming language for capstones\node_modules\nearley\lib\nearley.js:343:27) at main (C:\Users\mcqui\OneDrive\Desktop\Programming language for capstones\parse.js:15:12)
错误原因
问题出在lambda_body的块语法规则和statements规则的配合上:
- 测试代码中lambda块内的语句带有缩进(WS),但原语法中
lamba_body的块规则仅处理%NL换行,没有覆盖语句前的缩进空白。 - 当解析器遇到块内的缩进WS时,当前规则中没有对应的逻辑消耗这个WS,导致无法匹配后续的statement,抛出WS token意外的错误。
修复方案
步骤1:定义复用的换行+空白规则
在kpp.js中新增一个通用规则,处理任意空白+换行+任意空白的组合,覆盖块内缩进需求:
_NL_ -> _ %NL _
步骤2:修改statements规则,支持带空白的换行分隔
更新statements规则,允许语句之间通过包含缩进的换行分隔:
statements -> statement {% (data) => { return [data[0]] } %} | statements _NL_ statement {% (data) => { return [...data[0], data[2]] } %}
步骤3:修正lambda_body的块规则
调整块语法,允许块内前后存在多个_NL_,处理块开头/结尾的空行和缩进:
lamba_body -> expr {% (data) => { return [data[0]]; } %} | "{" _ (_NL_)* statements (_NL_)* _ "}" {% (data) => { return data[4]; } %}
验证修复
- 重新编译Nearley语法:
nearleyc kpp.ne -o kpp.js
- 运行解析器测试:
node parse.js main.kpp
此时解析器应能正确处理块内缩进空白,成功生成对应的AST文件。
内容的提问来源于stack exchange,提问作者user18353868
相关产品推荐
相关产品推荐

