首页 > 解决方案 > 为什么我的 Nearley 语法会导致循环?

问题描述

我在玩 nearley.js,有些东西让我很困惑。作为测试,我正在尝试构建一个解析扑克等级的解析器。

现在,这个语法按预期工作:

@{% function nuller() { return null; } %}

main -> _ composition _                         {% nuller %}

composition -> _ expression _                   {% nuller %}
    | composition _ "," _ rank                  {% nuller %}

expression -> _ rank _                          {% nuller %}
rank -> [a, k, q, j, t, A, K, Q, J, T, 2-9]     {% nuller %}

_ -> [\s]:*                                     {% nuller %}

但是,我更改| composition _ "," _ rank为第二个,| composition _ "," _ expression然后我结束了一个循环:

@{% function nuller() { return null; } %}

main -> _ composition _                         {% nuller %}

composition -> _ expression _                   {% nuller %}
    | composition _ "," _ expression            {% nuller %}

expression -> _ rank _                          {% nuller %}
rank -> [a, k, q, j, t, A, K, Q, J, T, 2-9]     {% nuller %}

_ -> [\s]:*                                     {% nuller %}

有人可以解释一下为什么会这样吗?代码可以在操场上快速测试: https ://omrelli.ug/nearley-playground/

我使用的测试字符串是:a, k, q, j, t, 9, 8, 7, 6, 5, 4, 3, 2

非常感谢您!

标签: nearley

解决方案


好吧,字符串中的每个值都可能有多种解释,这是因为您在表达式和排名之前都有可选的空格:

如果您查看第二个元素k,则可以将其解释为:

  • 空格+表达式
  • 空格+排名

由于字符串中的 12 个项目有 2 种可能性,因此您将获得 144 种可能的组合。

这将返回一个解决方案(我之前省略了可选的空格expression):


main -> _ composition _                         {% nuller %}

composition -> _ expression _                   {% nuller %}
    | composition _ "," expression              {% nuller %}

expression -> _ rank _                          {% nuller %}
rank -> [a, k, q, j, t, A, K, Q, J, T, 2-9]     {% nuller %}

_ -> [\s]:*                                     {% nuller %}

推荐阅读