为什么我的 Nearley 语法会导致循环?

Why is my Nearley grammar causing a loop?

我正在玩 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

非常感谢您!

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

如果你看第二个元素k,这可以解释为:

  • space + 表达式
  • space + 等级

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

这个returns一个解决方案(我在expression之前省略了可选的白色space):


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 %}