【问题标题】:How best to parse a comma separate list in PEG grammar如何最好地解析 PEG 语法中的逗号分隔列表
【发布时间】:2019-06-12 02:10:57
【问题描述】:

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

(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]

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

【问题讨论】:

    标签: parsing grammar left-recursion pegjs


    【解决方案1】:

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

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

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

    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 (', ' some_digits)?
    • @LeonStarr 哦,你想让我回答你帖子的第二部分吗?对不起,我忘记了
    • 不需要詹姆斯,你的回答为我澄清了 PEG 解析逻辑(这是我真正的问题)。不过谢谢你的提问。
    【解决方案2】:

    一行:

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

    这取决于您想要的值和 PEG 实现,但通过这种方式提取它们可能更容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多