簡體   English   中英

雲雀如何描述一系列可選令牌

[英]Lark how to describe a series of optional tokens

我正在解析的文件格式可以包括:

INT32  price   min 10  max 100   alertIfSold ; 

min,max和alertIfSold令牌都是可選的,可以按任何順序顯示。 那是

INT32  price    max 100   alertIfSold ; 
INT32  price  max 100   min 10    alertIfSold ;
INT32  price  alertIfSold ;
INT32  price; 

都是有效的例子。

以下是我正在測試的語法的簡單版本。 運行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()

你要:

line:  TYPE  CNAME (MIN | MAX | ALERT)* ";"    -> foo

(注意:( ()代替[] 。)

在雲雀的EBNF語法, [item]的意思是“一個可選item ”和item* “的任何數目(可能為零)的裝置item ”。 所以[item]*表示“任一的任何數目(可能為零) item或全無”。 但是“無數無數”是無限模棱兩可的。 您無法判斷一個空字符串中有多少個空字符。

由於您實際上並不打算要求這些條款嚴格連續出現,因此您可能一直在考慮

line:  TYPE  CNAME ([MIN] [MAX] [ALERT])* ";"    -> foo

那本來會更准確,但也會產生相同的錯誤消息。 通常,不能在可為空的子模式上使用Kleene星。 一些EBNF生成器會通過從重復集中刪除ε(然后將整個重復設為可選)來糾正這一問題,但百靈鳥不是其中之一。 在這種情況下,修復很簡單,但在其他情況下更令人討厭。

作為正則表達式, (a* b*)*(a? b?)*(a|b)*在它們都識別相同語言的意義上是等效的。 但是正則表達式眾所周知是模棱兩可的,並且解析器通常更喜歡模棱兩可的語法,或者最糟糕的是有限的模棱兩可的語法。 只有最后一個正則表達式屬於該類別,並且它通常是您應首選的形式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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