簡體   English   中英

是不是使用前瞻的LR(0)解析器?

[英]Isn't an LR(0) parser using lookaheads as well?

LL(1)-parser需要一個先行符號才能決定使用哪個生產。 這就是我一直認為使用術語“lookahead”的原因,當解析器查看下一個輸入標記而不“消耗”它時(即它仍然可以通過下一個動作從輸入中讀取)。 然而,LR(0)解析器讓我懷疑這是正確的:

我見過的LR(0)-parsers的每個例子也使用下一個輸入標記來決定是移位還是減少。 在減少的情況下,不消耗輸入令牌。

我使用免費軟件工具“ParsingEmu”生成LR表並在下面對單詞“aab”執行LR評估。 如您所見,列標題包含標記。 從評估中可以看出,解析器通過查看下一個輸入令牌來決定使用哪個列。 但是當解析器在步驟4-6中減少時,輸入不會改變(盡管解析器在執行到下一狀態的轉換時需要知道下一個輸入令牌“$”)。

語法:

S -> A
A -> aA
A -> b

表: LR表

評價: LR評估

現在我因為混亂的原因做了以下假設:

  1. 我對“lookahead”(lookahead =輸入令牌未被消耗)的定義的假設是錯誤的。 Lookahead對於LL解析器或LR解析器來說只意味着兩種不同的東西。 如果是這樣,那么如何定義“先行”?

  2. LR解析器(從理論的角度來看,當你使用下推自動機時)有額外的內部狀態,它們通過將輸入令牌放在堆棧上來消耗輸入令牌,因此只需查看就可以做出移位減少決策在堆棧上。

  3. 上面顯示的評估是LR(1)。 如果是,LR(0)評估會是什么樣的?

現在什么是正確的,1,2或3或完全不同的東西?

准確地說很重要:

LRk )解析器使用curent解析器狀態和k先行符號來決定是否減少 ,如果是,則減少哪個生產。

它還使用移位轉換表來決定在移動下一個輸入令牌后它應該移動到哪個解析狀態。 無論k的值如何,移位轉移表都由當前狀態和(單個)令牌移位來鎖定。

如果在給定的解析器狀態中,可以生成shift和reduce操作,則解析器具有shift / reduce沖突,並且它是無效的。 因此,理論上可以非確定地進行上述兩個確定。

如果在給定的解析器狀態中,不可能進行reduce,並且下一個輸入符號不能被移位(也就是說,該輸入符號沒有轉換該狀態),則解析失敗並且算法終止。

另一方面,如果移位轉換導致指定的Accept狀態,則解析成功並且算法終止。

所有這一切意味着前瞻用於預測應該應用哪種減少(如果有的話)。 LR (0)解析器中,必須在讀取下一個輸入令牌之前做出移位(更准確地說,嘗試移位)的決定,但是在讀取令牌之后進行要轉換到do的狀態的計算。如果無法進行換檔,它將發出錯誤信號。


LLk )解析器必須在看到非終端時預測哪個生產替換非終端。 基本的LL算法以包含[ S$ ](從上到下)的堆棧開始,並且在完成之前執行以下任何一項操作:

  • 如果堆棧的頂部是非終端,則用該非終端的一個產品替換堆棧的頂部,使用下一個k輸入符號來決定哪一個(不移動輸入光標),然后繼續。

  • 如果堆棧頂部是終端,請讀取下一個輸入令牌。 如果它是同一個終端,則彈出堆棧並繼續。 否則,解析失敗並且算法結束。

  • 如果堆棧為空,則解析成功並且算法結束。 (我們假設在輸入結束時有一個唯一的EOF標記$ 。)


在這兩種情況下,前瞻具有相同的含義:它包括在不移動輸入光標的情況下查看輸入令牌。

如果k為0,則:

  • LRk )解析器必須決定是否在不檢查輸入的情況下進行減少,這意味着沒有狀態可以具有兩個不同的reduce動作或者reduce和shift動作。

  • LLk )解析器必須在不檢查輸入的情況下決定給定非終端的哪個生成是可用的。 實際上,這意味着每個非終端只能有一個產品,這意味着語言必須是有限的。

暫無
暫無

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

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