簡體   English   中英

你如何在 Pyparsing 中找出哪些 ParserElements 匹配字符串?

[英]How do you find out which ParserElements are matching strings in Pyparsing?

我有一個復雜的子 ParserElements 像這樣組合在一起,我計划添加更多。

Group(multi_line ^ macro_parser ^ numeric_assignment ^ assert_parser ^ db ^
                                  charmap_parser ^ comment_parser ^
                                  include_parser ^ label ^ expression ^ macro_call ^
                                  newcharmap_parser ^ popc ^ pushc ^ redef ^ control ^ Literal("\n"))

我遇到了問題,其中一個子 ParserElements 在不應該匹配時會匹配,並且我會得到一個 ParseException ,它不會告訴我是哪個 ParserElement 引發了它。 這意味着我必須四處尋找哪些表達式與哪些行匹配,這需要很多時間。

有沒有辦法在引發異常時獲得更多有用的信息? 我嘗試將 .setDebug() 附加到上面的解析器,但錯誤消息不再有用。

有用的事情是幫助您的最終用戶通過使用您的解析器邏輯來理解他們自己的解析失敗,通過使用以下方法來增強您自己的 ParserElements 的錯誤輸出:

  • .setName() Python 方法
  • 有選擇地使用 PyParsing/Python -運算符,而不是+運算符。

.setName()

.setName()允許您重新陳述您的解析錯誤輸出(用簡單的 8 年級“英語”句子,或最簡單的 BNF,甚至助記符),盡管我經常使用由一對三元組( ””” )。

.setName()的默認值,您在 Python 賦值時定義到 ParserElement ......到那個 Python 變量,是以文本形式顯示字符串中使用的整個“PyParsing-ese”邏輯的字符串,這通常是對普通用戶幫助不大。

每當最終用戶遇到該變量中發生的ParseExceptions時,將顯示該 PyParsing 變量的新的更簡單的.setName()文本。

有選擇地使用減號

將 SOME +替換為-可以幫助您的最終用戶(和您)更接近那個冒犯角色的“更正確”的位置偏移。

對語法錯誤進行“更准確”的偏移也有助於 parseException 選擇“更正確”的 PyParsing 變量/組。 使用正確的變量,其(更好地選擇) .setName()輸出將幫助最終用戶能夠推斷出他們(或您的)錯誤……更快。

然后 parseException 將從包含您的 PyParsing 邏輯 (ParserElement) 的 Python 分配中輸出新的.setName()文本字符串。

示例 Python

這是在parseException事件中輸出簡化的 EBNF 的示例:

uri = Literal(‘file:///‘) | Literal(‘https://‘)
uri.setName(“””[
   https://
   | file:///
]”””
)
…

my_filepath = Optional(uri) - Optional(directory) - full_filename
my_filepath.setName(‘[ <uri> ] [ <directory-path> ] <full-filename>’j

ls_command = Suppress(Literal(‘ls’)) - my_filepath
ls_command.setName(‘ls <filepath>’)

常規輸出

而是看到一個很長的默認輸出,但在parseException時間看起來很神秘:

{{{{{{{{{{{{{Suppress(‘ls’) + {Optional( …

可讀輸出

新的輸出現在是

‘ls <filepath>’

或者

[ <uri> ] [ <directory-path> ] <full-filename>

或者

[
   https://
   | file:///
]

取決於他們在哪里破壞了您的解析器邏輯。

概括

使用.setName() /minus-operator duo,我很少使用 PyParsing 調試器開銷,如果有的話。

當然,您的邏輯越復雜,是時候開始將.setName()添加到每個受影響的分配中了。

每添加一個 .setName,解析 parseException 的時間就會變短……不僅對您,PyParsing 邏輯的開發人員,而且對您的最終用戶也是如此。

有一個項目用 PyParsing 編寫了超過 4,000 個邏輯,用於 bind9_parser 中 ISC Bind9 DNS 服務器的named.conf配置文件。 Bind9_parse 很好地利用了這對二重奏。

bind9_parser 的最終用戶更容易破譯解析錯誤有點重要。

暫無
暫無

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

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