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

时间:2019-06-12 02:10:57

标签: parsing grammar left-recursion pegjs

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

(1、4、3)

()

(4)

我可以想到两种方法来执行此操作,并且想知道为什么失败的示例无法正常工作。我相信这是正确的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]

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

1 个答案:

答案 0 :(得分:1)

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

  

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

所以这导致我找到解决方案:

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

此方法起作用的原因:

输入:(1,4)

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

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