如何最好地解析 PEG 语法中的逗号分隔列表



我正在尝试解析逗号分隔的列表。为了简化起见,我只是使用数字。这些表达式将有效:

(1, 4, 3)

()

(四)

我可以想到两种方法来做到这一点,我想知道为什么失败的示例不起作用。我相信这是一个正确的 BNF,但我无法让它作为 PEG 工作。谁能解释为什么?我试图更好地了解PEG解析逻辑。

我正在这里使用在线浏览器解析器生成器进行测试: https://pegjs.org/online

这不起作用:

list = '(' some_digits? ')'
some_digits = digit / ', ' some_digits
digit = [0-9]

(实际上,它解析正常,喜欢()或(1)但无法识别(1,2)

但这确实有效:

list = '(' some_digits? ')'
some_digits = digit another_digit*
another_digit = ', ' digit
digit = [0-9]

为什么?(语法新手在这里)

很酷的问题,在他们的文档中挖掘了一秒钟后,我发现/字符的意思是:

尝试匹配第一个表达式,如果不成功,请尝试 第二个,等等。返回第一个成功匹配结果 匹配的表达式。如果没有匹配的表达式,请考虑匹配 失败。

因此,这让我找到了解决方案:

list = '(' some_digits? ')'
some_digits = digit ', ' some_digits / digit
digit = [0-9]

这样做的原因:

输入: (1, 4)

  • 吃'('
  • 检查是否有一些数字?
  • 检查some_digits - 第一个条件:
    • 吃 '1'
    • 吃', '
    • 检查some_digits - 第一个条件:
      • 吃 '4'
      • 吃不下', '
    • 检查some_digits - 第二个条件:
      • 吃 '4'
      • 成功
    • 成功
  • 吃')'
  • 成功

如果颠倒some_digits条件的顺序,遇到的第一个数字会被digit吃掉,并且不会发生递归。然后它会抛出一个错误,因为")"不存在。

在一行中:

some_digits = '(' digit (', ' digit)* ')'

这取决于你想要的值和PEG实现,但这样提取它们可能会更容易。

相关内容

  • 没有找到相关文章

最新更新