簡體   English   中英

用替代方法解析CFG

[英]Parsing a CFG with alternatives

我有一種相當簡單的語言,表示為CFG。

S → A z
A → A y A
  | A x A
  | A w
  | v

由於存在左遞歸,因此遞歸下降解析器將不會削減它。 但是,我還需要找到所有可能的解釋:給定vxvyvz ,我需要我的解析器來找到(vx (vyv)) z((vxv) yv) z

我有什么選擇? 帶有減少回溯的Shift-reduce可以找到所有可能性,但是我聽說,向Shift-reduce解析器添加回溯可以使其呈指數級的時間復雜性。 這個CFG足夠小,沒關系,但是我需要將其擴展到更大的語法(有成千上萬個終端)。

可以實施Earley算法 (及其變體,例如GLR)來創建在立方時間內工作的解析器。 由於可能的解析數目是指數級的,因此復雜性只是建立“解析森林”,它是包含所有可能解析的DAG。 實際枚舉解析將花費的時間與可能性的數量成正比。

請注意,當我們在這里談論時間復雜度時,我們是在談論輸入字符串的長度,而不是語法的大小。 如果語法有影響,則大小當然是線性的,但通常取決於線性大小,但是取決於您如何測量大小,但是假設是針對特定語法構建了解析器(可能需要根據語法進行預處理)尺寸。)

上面鏈接的Wikipedia文章列出了各種語言的實現,其中一些旨在用於生產,而其他一些只是為了演示算法。 注意,由野牛產生的GLR解析器不是三次的。 在病理情況下,它可以是指數的。 另外,它不會構建解析樹(或森林); 留給用戶,不共享存儲空間的幼稚算法可能需要指數空間和時間。 (盡管如此,它對於現實世界的語法還是很有用的。)

有幾類上下文無關的語法。 存在確定性語法,可以使用移位減少解析器對其進行解析。 存在非確定性語法,其解決方案通常是動態超前或回溯。 而且,模棱兩可的語法(如您所描述的那樣)可以通過專門為歧義而設計的算法來最佳解決。

兩種這樣的算法是Earley(如@rici所指出的)和CYK。 它們旨在返回您需要的所有可能的推導,並且可用於創建SPPF(共享壓縮分析森林),這對於高度歧義的語法是非常有效的結構(無論您的語法是否適合此描述,我當然不能說)。

如果要嘗試使用它,可以嘗試使用我的python Lark解析庫,該庫同時實現Earley和CYK,並可以為您提供所有可能的輸入派生列表(但是,SPPF支持仍在進展)。

暫無
暫無

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

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