[英]Lark parser grammar works with Earley but not LALR
考慮一下Python Lark解析器的以下簡單測試:
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:在第2行第12行沒有為“ {”定義終端
內部:{
這只是一個MWE。 我的實際語法也遇到同樣的問題。
LALR失敗的原因是,其前瞻性為1(與Earley不同,后者具有無限前瞻性),並且attribute_name
和string
之間混淆了。 一旦它與另一個匹配(在本例中為attribute_name
),就不可能回溯並匹配另一個規則。
如果對attribute_name終端使用較低的優先級,則它將起作用。 例如:
attribute_name: ATTR
ATTR.0: /[A-Za-z_][A-Za-z_#0-9]*/
但是,建議的做法是,如果可能的話,對兩者都使用相同的終端,以便解析器可以代替詞法分析器為您做思考。 解析完成后,您可以添加額外的驗證(如果需要)。
兩種方法(更改優先級或合並終端)都可以解決您的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.