我正在分析一个包含以下格式的文件:
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()
你想要:
(注意:
()
而不是[]
。)在lark的EBNF语法中,}表示“
[item]
表示“可选的item
”,而{item
的任何数字(可能为零)”。所以[item]*
的意思是“任何一个item
或者什么都没有的数字(可能是零)”。但是“任何数量的无”是无限含糊的;你无法知道在一个空字符串中有多少个虚无。在由于您实际上并不打算要求从句严格地连续出现,您可能会想到
^{pr2}$这会更准确,但也会产生同样的错误信息。一般来说,不能在可为空的子模式上使用Kleene星。一些EBNF生成器将通过从重复集中删除ε(然后使重复作为一个整体是可选的)来纠正这一点,但lark不是其中之一。在这种情况下,修复是微不足道的,但在其他情况下,它更烦人。在
作为正则表达式,}在某种意义上是等价的,因为它们都能识别同一种语言。但是正则表达式是出了名的模棱两可的,解析器通常更喜欢明确的语法,或者最坏的情况下是有限歧义语法。只有最后一个正则表达式属于该类别,并且它是您通常应该喜欢的格式。在
(a* b*)*
、(a? b?)*
和{相关问题 更多 >
编程相关推荐