1. 程式人生 > >編譯原理第七章-語義分析和中間程式碼產生

編譯原理第七章-語義分析和中間程式碼產生

語義分析的任務是:

1.審查每一個語法結構的靜態語義,即驗證語法正確的結構是否有意義。

2.在語義正確的基礎上生成一種中間程式碼或目的碼。

語義分析的範圍是:

1.確定型別:確定識別符號所關聯的資料型別。

2.型別檢查:按語言的型別規則,檢查運算的合法性與運算分量型別的一致性,必要時作型別轉換。

3.識別含義:根據語言的語義定義(形式或非形式),識別程式中各構造成分組合到一起的含義,並作相應的語義處理(生成中間程式碼或目的碼)。

4.控制流檢查:控制流語句必須轉移到合法的地方。如C中,break語句規定跳出最內層的迴圈或switch語句。

5.一致性檢查:在很多場合要求物件只能被說明一次。如:pascal語言規定同一個識別符號在一個分程式中只能被說明一次等。

6.相關名字檢查:如:Ada,迴圈或塊可以有一個名字,它出現在這些結構的開頭或結尾。編譯程式必須檢查這兩個地方用的名字是否相同。

7.其它:如名字的作用域分析等也是語義分析的工作。

中間語言的表示形式:字尾式,三地址程式碼(包括三元式、四元式、簡潔三元式),DAG圖表示。

語法制導翻譯 :對文法中的每個產生式都附加上一個語義動作或語義子程式。伴隨著語法分析,每當使用一條產生式進行推導或歸約時,就執行相應產生式的語義動作(包括:查填表格,改變變數的求值,診察與報告錯誤,生成中間程式碼等),從而完成預定的翻譯工作。

三元式由三個部分組成                      算符:OP        

第一運算分量:ARG1        第二運算分量:ARG2

語句的四元式及翻譯

說明語句的翻譯
     程式語言中的說明語句都是給編譯程式提供資訊的,諸如型別、維數、每維的界種類等,因此一般不生成目標,只是在編譯時把有關資訊填入相應表格即可。型別轉換    我們可以把型別資訊反映到運算子中,例如用+i,*i表示定點+、*,用+r,*r表示浮點+、*。有的程式設計語言允許混合運算,有的不允許。如果不允許,則發現有型別不相同的運算分量就應該報錯。如果允許,就要進行型別轉換。

過程呼叫的翻譯
    過程呼叫主要解決兩個問題:
      (1)把程式控制轉移到子程式(過程段),執行完畢再返回。這個問題很好解決。


      (2)傳遞實在引數。我們前面談到過幾種不同的引數傳遞方式(傳名、傳值、傳地址),它們的語義動作也就有所區別。

中間程式碼: 把經過語法分析和語義分析而獲得的源程式中間表 示翻譯為中間程式碼表示。中間語言
  語法樹
  字尾式
  三地址程式碼表示圖表示法
    語法樹,有向非迴圈圖和字尾式表示源程式的自然層次結構。三地址語句的種類
1.賦值語句2.無條件轉移語句3.條件轉移語句4.複製語句5.過程呼叫語句6.索引語句7.地址和指標語句布林表示式:用布林運算子號(and,or,not)作用到布林變數或關係表示式上而組成布林表示式的作用:
 1. 用作計算邏輯值
 2. 用作控制流語句如if-then,if-then-else和while-do等之中的條件表示式

回填

生成跳轉語句時,將其E.true和E.false鏈成一個連結串列,記錄在E.truelist和E.falselist中

等到轉移目標確定以後,再將轉移出口填入E.truelist和E.falselist中

翻譯模式中用到的三個函式:

①.makelist(i):建立一個僅包含i的新表,i  是四元式陣列的一個索引(下標),或說 i是四元式程式碼序列的一個標號。

②.merge(p1,p2):連線由指標p1和p2指向的兩個表並且返回一個指向連線後的表的指標。 Merg(p1,p2)= p1 p2=0;

                                                                                                                                                            p1 p2≠0;

③.backpatch(p,t):把i作為目標標號回填到p所指向的表中的每一個轉移指令中去


部分課後習題解答: