gpt4 book ai didi

python - Lark 解析器语法适用于 Earley,但不适用于 LALR

转载 作者:行者123 更新时间:2023-12-01 00:55:23 25 4
gpt4 key购买 nike

考虑 Python Lark parser 的这个简单测试:

GRAMMAR = '''
start: container*

container: string ":" "{" (container | attribute | attribute_value)* "}"
attribute: attribute_name "=" (attribute_value | container)
attribute_value: string ":" _value ("," _value)*
_value: number | string

attribute_name: /[A-Za-z_][A-Za-z_#0-9]*/

string: /[A-Za-z_#0-9]+/
number: /[0-9]+/

%import common.WS
%ignore WS
'''

data = '''outer : {
inner : {
}
}'''

parser = Lark(GRAMMAR, parser='lalr')
parser.parse(data)

这适用于 parser='earley',但使用 parser='lalr' 则失败。我不明白为什么。错误信息是:

UnexpectedCharacters: No terminal defined for '{' at line 2 col 12

inner : {

这只是一个 MWE。我的实际语法也遇到同样的问题。

最佳答案

LALR 失败的原因是它的前瞻为 1(与 Earley 不同,Earley 具有无限的前瞻),并且它会混淆 attribute_namestring 。一旦它与另一个规则之一匹配(在本例中为 attribute_name),它就不可能回溯并匹配不同的规则。

如果您对 attribute_name 终端使用较低的优先级,它将起作用。例如:

attribute_name: ATTR

ATTR.0: /[A-Za-z_][A-Za-z_#0-9]*/

但建议的做法是,如果可能的话,对两者使用相同的终端,以便解析器(而不是词法分析器)可以为您进行思考。如果需要,您可以在解析完成后添加额外的验证。

两种方法(更改优先级或合并终端)都可以解决您的问题。

关于python - Lark 解析器语法适用于 Earley,但不适用于 LALR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56274704/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com