編譯器設計-解析類型

編譯器設計-解析類型算法

Compiler Design - Types of Parsingspa

語法分析器遵循由上下文無關語法定義的產生式規則。生成規則的實現方式(派生)將解析分爲兩種類型:自上而下解析和自下而上解析。設計

自頂向下分析Top-down Parsing              3d

當解析器開始從開始符號構造解析樹,而後嘗試將開始符號轉換爲輸入時,稱爲自頂向下解析。              指針

遞歸降低解析:它是自頂向下解析的一種常見形式。它被稱爲遞歸,由於它使用遞歸過程來處理輸入。遞歸降低解析受到回溯的影響。              blog

回溯:這意味着,若是產品的一個派生失敗,語法分析器將使用同一產品的不一樣規則從新啓動進程。這種技術能夠屢次處理輸入字符串以肯定正確的生產。              遞歸

自下而上分析Bottom-up Parsing              進程

顧名思義,自底向上的解析從輸入符號開始,並嘗試構建解析樹直至開始符號。ip

Example:字符串

Input string : a + b * c

Production rules:

S → E

E → E + T

E → E * T

E → T

T → id

Let us start bottom-up parsing

a + b * c

讀取輸入並檢查是否有任何生產與輸入匹配:

a + b * c
T + b * c
E + b * c
E + T * c
E * c
E * T
E
S

在上一章中,咱們瞭解到自頂向下解析技術解析輸入,並開始從根節點逐漸向下移動到葉節點構建解析樹。

遞歸降低分析Recursive Descent Parsing             

遞歸降低是一種自頂向下的解析技術,它從頂部構造解析樹,從左到右讀取輸入。它對每一個終端和非終端實體使用過程。這種解析技術遞歸地解析輸入以生成解析樹,這可能須要也可能不須要回溯。但與之相關聯的語法(若是沒有保留因子)不能避免回溯。一種不須要任何回溯的遞歸降低解析稱爲預測解析。             

這種解析技術被認爲是遞歸的,由於它使用的上下文無關語法本質上是遞歸的。             

回溯Back-tracking             

自上而下的解析器從根節點(開始符號)開始,並根據生產規則匹配輸入字符串以替換它們(若是匹配)。要理解這一點,請以CFG爲例:

S  rXd | rZd
X  oa | ea
Z  ai

對於輸入字符串:read,自上而下的解析器,其行爲以下:             

它將從生產規則中的S開始,並將其收益率與輸入的最左邊的字母(即「r」)匹配。S(S→rXd)的產生與之相匹配。因此自上而下的解析器前進到下一個輸入字母(即「e」)。解析器嘗試展開非終端「X」,並從左側檢查其結果(X→oa)。它與下一個輸入符號不匹配。因此自上而下的解析器回溯以得到X的下一個產生式規則(X→ea)。             

如今解析器按順序匹配全部輸入字母。接受字符串。

預測分析器 Predictive parser            

Predictive parser是一種遞歸降低解析器,它可以預測將使用哪一個產品來替換輸入字符串。預測解析器不受回溯的影響。             

爲了完成它的任務,預測解析器使用一個前瞻指針,它指向下一個輸入符號。爲了使解析器無需回溯,預測解析器對語法施加一些約束,只接受一類稱爲LL(k)語法的語法。

預測性分析使用堆棧和分析表來分析輸入並生成分析樹。堆棧和輸入都包含一個結束符號$,表示堆棧爲空而且輸入被消耗。解析器引用解析表來決定輸入和堆棧元素的組合。

在遞歸降低解析中,對於單個輸入實例,解析器可能有多個產品可供選擇,而在預測解析器中,每一個步驟最多有一個產品可供選擇。可能存在沒有與輸入字符串匹配的產品的實例,從而致使分析過程失敗。             

LL分析器LL Parser             

LL語法分析器接受LL語法。LL文法是上下文無關文法的一個子集,但有必定的限制,要獲得簡化的版本,才能實現容易。LL語法能夠經過遞歸降低和表驅動兩種算法來實現。             

LL解析器表示爲LL(k)。第一個L in LL(k)從左到右解析輸入,第二個L in LL(k)表示最左邊的派生,k自己表示look ahead的數量。通常k=1,因此LL(k)也能夠寫成LL(1)。

LL解析算法 LL Parser Algorithm            

對於解析器的解釋,咱們可使用肯定性的LL(1),由於表的大小隨着k的值呈指數增加。其次,若是給定的語法不是LL(1),那麼對於任何給定的k,一般都不是LL(k)。              

下面給出了LL(1)解析的算法:

Input:
   string ω
   parsing table M for grammar G
 
Output:
   If ω is in L(G) then left-most derivation of ω,
   error otherwise.
 
Initial State : $S on stack (with S being start symbol)
   ω$ in the input buffer
 
SET ip to point the first symbol of ω$.
 
repeat
   let X be the top stack symbol and a the symbol pointed by ip.
 
   if X∈ Vt or $
      if X = a
         POP X and advance ip.
      else
         error()
      endif
      
   else       /* X is non-terminal */
      if M[X,a] = X  Y1, Y2,... Yk    
         POP X
         PUSH Yk, Yk-1,... Y1 /* Y1 on top */
         Output the production X  Y1, Y2,... Yk
      else
         error()
      endif
   endif
until X =/* empty stack */

若是A→α|β是G的兩個不一樣乘積,則語法G是LL(1):             

對於無終端,α和β都導出以a開頭的字符串。             

α和β中至多有一個能夠導出空字符串。             

若是β→t,則α不導出以跟隨(a)中的終端開始的任何字符串。

相關文章
相關標籤/搜索