Eli*_*Eli 4 python grammar lark-parser
我正在解析一个文件,其格式可以包括:
INT32 price min 10 max 100 alertIfSold ;
Run Code Online (Sandbox Code Playgroud)
min、max 和alertIfSold 令牌都是可选的,并且可以按任何顺序出现。那是
INT32 price max 100 alertIfSold ;
INT32 price max 100 min 10 alertIfSold ;
INT32 price alertIfSold ;
INT32 price;
Run Code Online (Sandbox Code Playgroud)
都是有效的例子。
下面是我正在测试的语法的简单版本。运行 python test.py 会生成此错误:
lark.common.ParseError:检测到无限递归!(规则 <__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()
Run Code Online (Sandbox Code Playgroud)
你要:
\n\nline: TYPE CNAME (MIN | MAX | ALERT)* ";" -> foo\nRun Code Online (Sandbox Code Playgroud)\n\n(注:()代替[]。)
在lark的EBNF语法中,[item]表示“可选item”,item*表示“任意数量(可能为零)item”。So 的[item]*意思是“任意数量(可能为零)的其中之一item或什么都没有”。但“任意数量的无”是无限模糊的;你无法知道一个空字符串中有多少个“无”。
由于您实际上并不打算要求这些子句严格连续出现,因此您可能一直在考虑
\n\nline: TYPE CNAME ([MIN] [MAX] [ALERT])* ";" -> foo\nRun Code Online (Sandbox Code Playgroud)\n\n这样会更准确,但也会产生相同的错误消息。一般来说,您不能在可为 null 的子模式上使用 Kleene 星形。一些 EBNF 生成器会通过从重复集中删除 \xce\xb5 (然后使重复作为一个整体可选)来纠正这一问题,但 lark 不是其中之一。在这种情况下,修复是微不足道的,但在其他情况下,修复会更烦人。
\n\n作为正则表达式,(a* b*)*、(a? b?)*和(a|b)*是等效的,因为它们都识别相同的语言。但正则表达式的二义性是出了名的,解析器通常更喜欢明确的语法,或者最坏的情况是有限二义性的语法。只有最后一个正则表达式属于该类别,并且它是您通常应该更喜欢的形式。
| 归档时间: |
|
| 查看次数: |
1735 次 |
| 最近记录: |