使用nearley.js解析时遭遇换行符(token)报错的技术求助
解决nearley.js中换行符(NL)解析报错问题
问题分析
从报错信息和语法规则来看,核心问题出在**statements规则对换行符的强制要求以及可能的Lexer Token定义不匹配**:
- 当前
statements规则要求每个statement必须以NL结尾,包括最后一个语句,但实际代码中最后一行通常没有换行符,导致解析失败。 - 报错位置在字符串结束后,可能是Lexer未正确识别换行符,或字符串Token的正则定义存在缺陷,导致无法正确区分字符串内容和后续换行。
解决方案
1. 修正statements语法规则
将强制每个语句后必须跟NL的规则,改为允许语句间用NL分隔、最后一个语句后可选NL的结构,更符合常规代码书写习惯:
statement -> var_assign {% id %} | fun_call {% id %} | function_def {% id %} | conditional {% id %} | loop {% id %} statements -> statement {% (data) => [data[0]] %} | statements %NL statement {% (data) => [...data[0], data[2]] %}
或者用nearley的重复运算符简化写法,更简洁高效:
statements -> statement (%NL statement)* {% (data) => { const [firstStmt, restPairs] = data; return restPairs.length ? [firstStmt, ...restPairs.map(pair => pair[1])] : [firstStmt]; } %}
2. 验证并修正Lexer的Token定义
如果使用moo.js作为配套Lexer,确保以下Token定义正确:
- NL(换行符):正确匹配换行,开启行计数:
NL: { match: /\r?\n/, lineBreaks: true }, - 字符串Token:支持转义字符,避免提前终止识别:
string: { match: /"(?:\\.|[^"\\])*"/ }, - 空白字符(
_):仅匹配空格、制表符,不包含换行:_: { match: /[ \t]+/, lineBreaks: false },
3. 测试验证
用你的测试输入验证:
@name = "mohammad" call print(name)
修正后的规则会正确识别第一行语句后的NL,以及第二行作为末尾语句无需NL的情况,解决解析报错。
内容的提问来源于stack exchange,提问作者Mohammad Abbass
相关产品推荐
相关产品推荐

