百灵鸟如何描述一系列可选令牌

2024-10-04 01:29:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在分析一个包含以下格式的文件:

INT32  price   min 10  max 100   alertIfSold ; 

min、max和alertIfSold令牌都是可选的,可以以任何顺序出现。那就是

^{pr2}$

都是有效的例子。在

下面是我测试的语法的一个简单版本。 运行python测试.py生成此错误:

lark.common.ParseError: Infinite recursion detected! (rule <__anon_star_1 : __anon_star_1>)

我尝试过使用其他语法规则表达相同的可选标记,结果相似(无限递归)。在

表示可选参数的正确语法是什么?在

#test.py
from lark import lark

simplified_grammar = """
    start: line+
    line:  TYPE  CNAME [MIN MAX ALERT]* ";"    -> foo

     TYPE: "INT32" | "INT64"

     MIN: "min" /[0-9]+/
     MAX: "max" /[0-9]+/
     ALERT: "alertIfSold"

     %import common.CNAME
     %import common.WS
     %ignore WS
  """

sample = """
    INT32  price    max 100   alertIfSold ; 
    INT32  price  max 100   min 10    alertIfSold ;
    INT32  price  alertIfSold ;
    INT32  price; 

"""

parser = lark.Lark(simplified_grammar)


def main():
    parse_tree = parser.parse(sample)

if __name__ == '__main__':
    main()

Tags: pyimportmain语法commonsimplifiedminprice
1条回答
网友
1楼 · 发布于 2024-10-04 01:29:37

你想要:

line:  TYPE  CNAME (MIN | MAX | ALERT)* ";"    -> foo

(注意:()而不是[]。)

在lark的EBNF语法中,[item]表示“可选的item”,而{}表示“item的任何数字(可能为零)”。所以[item]*的意思是“任何一个item或者什么都没有的数字(可能是零)”。但是“任何数量的无”是无限含糊的;你无法知道在一个空字符串中有多少个虚无。在

由于您实际上并不打算要求从句严格地连续出现,您可能会想到

^{pr2}$

这会更准确,但也会产生同样的错误信息。一般来说,不能在可为空的子模式上使用Kleene星。一些EBNF生成器将通过从重复集中删除ε(然后使重复作为一个整体是可选的)来纠正这一点,但lark不是其中之一。在这种情况下,修复是微不足道的,但在其他情况下,它更烦人。在

作为正则表达式,(a* b*)*(a? b?)*和{}在某种意义上是等价的,因为它们都能识别同一种语言。但是正则表达式是出了名的模棱两可的,解析器通常更喜欢明确的语法,或者最坏的情况下是有限歧义语法。只有最后一个正则表达式属于该类别,并且它是您通常应该喜欢的格式。在

相关问题 更多 >