You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nearley解析器如何无歧义返回不定数量匹配?附量词含义问询

Nearley解析器歧义问题解决与语法量词说明

问题背景与现状

我正在开发一款用于发布分支型冒险故事的软件,计划用Nearley替换自研的JavaScript解析器。目前编写的Nearley语法如下:

main->(excludebrackets link:+ excludebrackets):+
link->"[LINK:"i excludebrackets "|" excludebrackets "]"
{% (d) => {return'<a href ="func__' + d[3][0].join("") + '()>'+d[1][0].join("")+"</a>"}%} 
excludebrackets->[^\[\]]:+ | null

单个链接标记[LINK: shoot | shoot_dragon]可被正确转换为<a href ="func__shoot_dragon()>shoot</a>,但处理包含多个链接的文本时,解析器出现歧义并返回多个结果,需要实现无歧义的不定数量匹配。

歧义解决方法

问题根源在于main规则的嵌套重复结构(excludebrackets link:+ excludebrackets):+——这种写法会让解析器对“普通文本+链接”的组合产生多种拆分逻辑(比如将多个链接归为一组或拆分为多组),进而引发歧义。

调整后的无歧义语法如下:

main -> (excludebrackets | link):*
link -> "[LINK:"i excludebrackets "|" excludebrackets "]"
{% (d) => {return '<a href="func__' + d[3][0].join('') + '()">' + d[1][0].join('') + '</a>'} %}
excludebrackets -> [^\[\]]:+

关键修改点:

  • 将main规则改为(excludebrackets | link):*,表示零个或多个“普通文本段”或“链接”的交替序列,彻底避免嵌套重复带来的拆分歧义
  • 移除excludebrackets的null选项,因为main的:*已经覆盖了空输入场景,null选项会导致解析器匹配空文本段,额外增加歧义风险

语法量词含义说明

Nearley中的:*、:+、:?是用于规则重复匹配的量词,具体含义:

  • :+:匹配前置规则1次或多次,必须至少出现1次。例如link:+表示当前位置至少存在一个链接
  • :*:匹配前置规则0次或多次,可以完全不出现。例如(excludebrackets | link):*允许文本全为普通内容、全为链接,或是两者混合
  • :?:匹配前置规则0次或1次,即该规则是可选的。例如若有规则foo -> bar:? baz,则bar可以出现1次,也可以完全不出现,仅保留baz

内容的提问来源于stack exchange,提问作者user1833028

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 09:15:31