【问题标题】:PEG parsing match at least one preserving orderPEG 解析匹配至少一个保留顺序
【发布时间】:2016-02-22 10:46:44
【问题描述】:

鉴于 PEG 规则:

rule = element1:'abc' element2:'def' element3:'ghi' ;

我如何重写它以使其匹配至少一个元素但可能同时执行它们的顺序?

即我想匹配以下所有行:

abc def ghi
abc def
abc     ghi
    def ghi
abc
    def
        ghi

但不是空字符串或错误排序的表达式,例如def abc.

当然,对于三个元素,我可以在单独的规则中拼出组合,但是随着元素数量的增加,这很容易出错。

有没有办法以简洁的方式指定这一点?

【问题讨论】:

    标签: parsing ebnf peg grako


    【解决方案1】:

    您可以使用选项:

    rule = [element1:'abc'] [element2:'def'] [element3:'ghi'] ;
    

    您将使用rule 的语义操作来检查是否至少匹配了一个标记:

    def rule(self, ast):
        if not (ast.element1 or ast.element2 or ast.element3):
            raise FailedSemantics('Expecting at least one token')
        return ast
    

    另一种选择是使用多种选择:

    rule 
        = 
           element1:'abc' [element2:'def'] [element3:'ghi'] 
        | [element1:'abc']  element2:'def' [element3:'ghi'] 
        | [element1:'abc'] [element2:'def'] element3:'ghi' 
        ;
    

    缓存将使后者与前者一样高效。

    然后,您可以添加 cut 元素以提高效率和更有意义的错误消息:

    rule 
        = 
           element1:'abc' ~  [element2:'def' ~] [element3:'ghi' ~] 
        | [element1:'abc' ~]  element2:'def' ~  [element3:'ghi' ~] 
        | [element1:'abc' ~] [element2:'def' ~] element3:'ghi'  ~
        ;
    

    或:

    rule = [element1:'abc' ~] [element2:'def' ~] [element3:'ghi' ~] ;
    

    【讨论】:

    • 感谢您如此彻底地解释这些选项。
    【解决方案2】:

    答案是:析取的一个前提条件,然后是一系列可选项。

    rule = &(e1 / e2 / e3) e1? e2? e3?
    

    这是标准的 PEG,其中 & 表示“必须存在但不能消耗”和 ?意思是“可选的”。如果没有这些符号,大多数 PEG 解析器都具有这些功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 2013-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多