簡體   English   中英

為什么左遞歸、非確定性或二義性文法不能是 LL(1)?

[英]Why can't a left-recursive, non-deterministic, or ambiguous grammar be LL(1)?

我從幾個來源了解到 LL(1) 語法是:

  1. 毫不含糊,
  2. 不是左遞歸,
  3. 和,確定性的(左分解)。

我無法完全理解的是為什么上述內容適用於任何 LL(1) 語法。 我知道 LL(1) 解析表將在某些單元格中有多個條目,但我真正想要的是以下命題的正式和一般(沒有示例)證明:

左遞歸 (1)、非確定性 (2) 或歧義 (3) 文法不是 LL(1)。

我做了更多的研究,我想我已經找到了第一和第二個問題的解決方案,至於第三個問題,我在 SO 上找到了一個現有的解決方案,證明嘗試寫在下面:

我們首先編寫 LL(1) 文法定義的三個規則:

對於每個產生式A -> α | β A -> α | βα ≠ β

  1. FIRST(α) ∩ FIRST(β) = Ø
  2. 如果β =>* εFIRST(α) ∩ FOLLOW(A) = Ø (同樣,如果α =>* εFIRST(β) ∩ FOLLOW(A) = Ø )。
  3. 在規則 (1) 中包含ε意味着至多αβ可以推導出ε

命題 1:非因式分解文法不是 LL(1)。

證明:

如果文法 G 是非因式分解的,則 G 中存在以下形式的產生式:

A -> ωα1 | ωα2 | ... | ωαn

(其中αi是第i-th α ,而不是符號αi ),其中α1 ≠ α2 ≠ ... ≠ αn 然后我們可以很容易地證明:

∩(i=1,..,n) FIRST(ωαi) ≠ Ø

這與定義的規則 (1) 相矛盾,因此,非因式分解文法不是 LL(1)。

命題 2:左遞歸文法不是 LL(1)。

證明:

如果文法是左遞歸的,則 G 中存在以下形式的產生式:

S -> Sα | β

這里出現三種情況:

  1. 如果FIRST(β) ≠ {ε}則:

    FIRST(β) ⊆ FIRST(S)

    => FIRST(β) ∩ FIRST(Sα) ≠ Ø

    這與定義的規則(1)相矛盾。

  2. 如果FIRST(β) = {ε}則:

    2.1. 如果ε ∈ FIRST(α)那么:

    ε ∈ FIRST(Sα)

    這與定義的規則(3)相矛盾。

    2.2. 如果ε ∉ FIRST(α)那么:

    FIRST(α) ⊆ FIRST(S) (因為β =>* ε

    => FIRST(α) ⊆ FIRST(Sα) ........ (I)

    我們也知道:

    FIRST(α) ⊆ FOLLOW(S) ........ (II)

    (I)(II) ,我們有:

    FIRST(Sα) ∩ FOLLOW(S) ≠ Ø

    並且由於β =>* ε ,這與定義的規則(2)相矛盾。

在每種情況下,我們都會遇到矛盾,因此,左遞歸文法不是 LL(1)。

命題 3:歧義文法不是 LL(1)。

證明:

雖然上面的證據是我的,但這個不是,它是由Kevin A. Naudé 提供的,我從他的回答中得到,鏈接如下:

https://stackoverflow.com/a/18969767/6275103

這些問題的答案(它們對任何有限 k 的 LL(k) 都有效)與解析堆棧在 LL 解析器中的工作方式有關。

在文法中一個非終結符的開頭處,解析器必須通過僅向前看 k(在 LL(1) 中為 1) 個 case 標記來確定是否將特定規則壓入堆棧或使用其他規則解析文本。 因此,讓我們看看這些案例中的每一個,看看它如何影響該決策。

  1. 左遞歸。 有兩種左遞歸情況。

    一種。 遞歸后,左遞歸中沒有標記。 規則類似於:

非期限:非期限;

這樣的規則不起作用,無論您遞歸多少次都不會改變您正在解析的內容。

b. The left-recursion has tokens in it after the recursion.  A rules something like:

非術語:非術語“X”;

在此規則中,您需要將非項規則推入堆棧,其數量與非項之后的 X 一樣多。 您無法僅使用 k 個前瞻標記來確定有多少個 X。 如果你猜測和猜測太小,你最終會剩下 Xs,並且對於任何猜測,語言中都會有超過那么多 X 標記的情況。 如果您猜測並且您猜測的太大,您最終會在堆棧中得到 extern nonterm 規則。 你不能刪除它們。 無論哪種情況,您都錯了。

  1. 非確定性。 非確定性文法與左遞歸文法具有相同的特征。 是否應該推送是不確定的。 回文語言是典型的非確定性例子,但不是唯一的例子。 在回文語言中,您不知道是應該將另一個非終結符推入堆棧還是使用您看到的令牌來幫助您彈出堆棧。 如果您做出錯誤的選擇,您將再次錯誤解析輸入。

  2. 模糊的。 問題又是類似的。 在這種情況下,有兩種可能的解析。 一個推送一個非終結符並成功解析輸入,另一個解析沒有(可能現在或稍后在解析中推送另一個非終結符)。 任何一個都會產生正確的解析。 現在,在模棱兩可的情況下,推送非終結符不一定會導致解析錯誤,您只需選擇一個潛在的解析,而忽略另一個。 如果您的語義要求選擇其他解析,問題將在稍后出現。 請注意,當然,最模糊的文法也是不確定的。

現在,如果您查看這些情況,您會發現,如果您能以某種方式將非終結符推入堆棧而不是將其推入堆棧,您就可以使用語法解析輸入。 並且,在模棱兩可的情況下,生成一組與輸入匹配的解析。 有一些技術可以做到這一點,我相信它們被認為是 GLL(廣義 LL)——LR 解析器生成器的等效技術稱為 GLR。 結果輸出通常被認為是“解析森林”(或有時是解析 dag、有向無環圖)。

[注意:我首先在 Quora 上看到了上述問題,此答案是從那里復制的。]

暫無
暫無

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

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