簡體   English   中英

雲雀解析器語法適用於Earley,但不適用於LALR

[英]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_namestring之間混淆了。 一旦它與另一個匹配(在本例中為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM