2017-01-19 81 views
0

對於不LL(1)LR(1)一個人如何可以嘗試找出是否某些數量n存在使得語法可LL(n)LR(n)語言?如何識別文法是否是LR(N),LL(N)

通過查看LR(0)項目的規範集合來檢查語法是否爲LR(0)。然後,假設它不是LR(0),可以通過引入lookahead符號來檢查它是否爲LR(1)。我的簡單推理告訴我,爲了檢查它是否爲LR(2),您可能必須使前瞻包含接下來的兩個符號而不是一個。對於LR(3),您必須考慮三個符號等。

即使這種情況,即使我懷疑它,但我很難想出如何才能識別(或甚至獲得提示) n,或其不存在,對此,特定語法可以是LR(n)和/或LL(n),而不從任意向上檢查LR(m)

回答

3
  1. 如果語言是LR(ķ)的一些ķ > 1,那麼它是LR(1)。 (當然,這對於語法來說並非如此。)也就是說,如果您有一種語言的LR(語法),那麼您可以機械地構造一個LR(1)語法,它允許您恢復原始語法分析樹。這不是LL(k); LL(k)語言是LL(k +1)語言的嚴格子集。

  2. 你提議確實將讓您決定一個語法是否是LR(ķ)一段給定的K(或LL(ķ))的測試。不幸的是,除了您提出的連續搜索之外,沒有辦法計算出可能的最小值,並且不能保證搜索將永遠不會終止。

  3. 儘管在一般情況下問題很難(或不可能),但通常可以通過考慮表現出衝突的語法狀態的可能有效後繼者來針對特定語法進行回答。

在大多數現實世界的語法中,只會有一些衝突,因此可以手動檢查衝突狀態。一般而言,需要找出導致衝突狀態的路徑以及可能的延續。在很多情況下,很明顯,解析衝突可以用更多的前瞻來解決。

這將失敗的一大類語法是一組模糊語法。對於任何的模糊語法都不能是LR(k)(或LL(k))k。同樣,語法是否含糊不清的問題不是可確定的,而是存在有效的啓發式方法,其中一些包含在商業產品中。

同樣,通過視覺檢查(如上所述),或者通過將大量有效文本提供給GLR解析器(比如由野牛製作的解析器),直到在真實世界的語法中找到歧義常常很容易,直到報道含糊不清。(或者,您可以使用直接算法從語法中枚舉有效文本,並查看文本是否在枚舉中出現兩次。)

這裏有幾個可能相關的SO問題來說明分析技術。我相信還有更多。

A yacc shift/reduce conflict on an unambiguous grammar

Bison reduce/reduce situation

yacc shift-reduce for ambiguous lambda syntax

How to understand and fix conflicts in PLY

+0

你能否詳細說明一點NO3一點?人們應該尋找繼任者的特徵是什麼?另外,關於LL語法可以做些什麼? –

+0

如果我測試語法並發現它不是LR(1),LR(2),LR(3)(...),那麼在某些時候我應該開始尋找可以幫助構建一個案例的特定特徵這個語法可能根本不是LR。這樣的特徵是否會存在?如果是,他們會是什麼樣子?如果可能的話,類似的情況對於LL案件是可行的嗎? –

+0

@Eternal_Light:我試圖解決你的問題,但我擔心它仍然是非特定的。 SO中有非LR(1)語法的例子,其中大多數都帶有「我如何解決這個衝突」這個問題,並且其中很多已經在答案中進行了分析。我通常不會打擾LL的衝突,所以我在那裏幫不了你; LL解析器更常見的是要求無界的前瞻,通常的解決方案是切換到LR解析器。 – rici