鉴于PEG规则:
rule = element1:'abc' element2:'def' element3:'ghi' ;
我如何重写这一点,使其至少与其中一个元素匹配,但可能同时强制执行其命令?
即。我想匹配以下所有行:
abc def ghi
abc def
abc ghi
def ghi
abc
def
ghi
但不是空字符串或错误的表达式,例如def abc
。
当然有三个元素,我可以在不同的规则中拼出组合,但随着元素数量的增加,这就容易出错。
有没有办法以简洁的方式指定它?
答案 0 :(得分: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' ~] ;
答案 1 :(得分:1)
答案是:分离的一个先决条件,然后是一系列的选项。
rule = &(e1 / e2 / e3) e1? e2? e3?
这是标准PEG,含有&意思是“必须存在但不能消费”和?意思是'可选'。如果没有这些符号,大多数PEG解析器都具有这些功能。