第七章 語義分析和中間程式碼生成
1、 編譯程式的任務是把源語言程式翻譯成目標程式,有些編譯程式在編譯過程中,不產生中間語言,而是直接從源語言程式翻譯成目標語言程式。
以上編譯過程省略了中間語言,它不利於編譯所產生的目的碼的優化.為了產生高質量的程式碼,可以將源語言程式首先翻譯成一種特殊形式的中間語言程式碼形式,並對其進行優化,然後再將它翻譯成最終的目的碼。
中間程式碼
中間程式碼也叫中間語言
(Intermediate code /language)是:源程式的一種內部表示,不依賴目標機的結構,複雜性介於源語言和機器語言之間。
中間程式碼的優點
1、邏輯結構清楚;
2、利於不同目標機上實現同一種語言;
3、利於進行與機器無關的優化;
在詞法分析和語法分析之後,編譯程式要完成語義分析和翻譯工作。由於編譯器完成的分析是靜態定義的,所以,語義分析也可稱作靜態語義分析 (taticsemantic analysis)。
語義分析的具體工作1、型別檢查;
2、控制流檢查;
3、一致性檢查;
4、相關名字檢查
語法制導翻譯對文法中的每個產生式都附加一個語義動作或語義子程式,且在語法分析過程中,每當需要使用一個產生式進行推導或規約時,語法分析程式除執行相應的語法分析動作之外,還要執行相應地語義動作或語義子程式。每個語義子程式都指明瞭相應產生式中各個符號的具體含義,並規定了使用該產生式進行分析時所應採取的語義動作。
由此可見:抽象文法符號的具體語義資訊,是在語法分析同步的語義處理過程中獲取和加工的。
屬性文法
將語義以“屬性”的形式附加到各文法符號上,再根據產生式所蘊含的語義,給出每個文法符號的屬性的求值規則,從而形成一種帶有語義屬性的前後文無關文法,即屬性文法。
屬性一個文法符號X的語義資訊我們稱之為語義屬性或簡稱為屬性(Atrributes)
X.TYPE表示為X的型別
X.VAL表示為X的值
例:對於文法:E→E+T | T
T→ digit
語法制導翻譯的實質
根據文法中每個產生式所蘊含的語義,為其配備一個(或多個)語句或子程式,對所要完成的功能進行描述,在語法分析過程中,當分析器使用該產生式進行語法分析時(不論是推導還是規約),除完成語法分析動作之外,還將呼叫為其配備的語義子程式,進行相應地語義處理,完成語義翻譯工作。
1、字尾式
2、圖表示法
抽象語法樹、DAG圖
3、三地址程式碼
三元式、四元式、間接三元式
字尾式字尾式是波蘭邏輯學家盧卡西維奇(J.Lukasiewicz)提出的一種對錶達式的表示方法:每一運算子都置於其運算物件之後,即運算元寫在前面,算符寫在後面。
它的特點是:表示式中各個運算是按運算子出現的順序進行的,故無需用括號來指示運算順序,因而又稱為無括號式。
結論從以上兩個例子我們可得出:
1、在兩種表示中,運算物件出現的順序相同;
2、在後綴表示中,運算子按實際計算順序從左到右排列,且每一運算子總是跟在運算物件之後。
圖表示法-抽象語法樹在語法樹中去掉一些對翻譯不必要的資訊後,獲得的更有效的源程式的中間表示,這種經過變換後的語法樹稱為抽象語法樹。
在抽象語法樹中,操作符和關鍵字都不作為葉子節點出現,而是把它們作為內部節點,即這些葉子節點的父節點。
抽象語法樹的表示方法
1、每一個結點用一個記錄來表示,該記錄包括一個運算子域和若干個指向子結點的指標域。
例: a:=b*-c+b*-c方法1
方法2
把所有的結點安排在一個記錄的陣列中,結點的位置或索引作為指向地點的指標。
圖表示法-DAG圖
DAG(Directed Acyclic Graph)有向無迴圈圖
對錶達式中的每個子表示式,DAG都有一個結點,一個內部結點代表一個操作符,他的孩子代表運算元。在一個DAG中代表公共子表示式的節點具有多個父結點(與抽象語法樹中公共子表示式被表示為重複的子樹不同)
例:
a:=b*-c+b*-c
三地址程式碼
三地址程式碼最基本的用法形式:
x:=y op z
其中x、y、z為名字、常數或編譯時產生的臨時變數;op代表運算子號。每個語句的右邊只能有一個運算子。
例如:x+y*z可以翻譯為:
T1:=y*z
T2:=x+T1
T1、T2位編譯時產生的臨時變數
三地址程式碼可以看成是抽象語法樹一種線性表示三地址程式碼可以看成是DAG的一種線性表示
三地址碼的各種形式:
賦值語句翻譯為三地址碼的屬性文法
三地址程式碼—四元式四元式實際上是一種“三地址語句”的等價表示,是一個帶有四個域的記錄結構。它
的一般形式為:
(op,arg1,arg2,result)
需要指出的是:每個四元式只能有一個運算子,所以,一個複雜的表示式只能由多個四元式構成的序列表示。
例:a:=b*-c+b*-c
三地址程式碼-三元式
三元式顧名思義就是帶有三個域的記錄結構,他的一般形式為
(i)(op,arg1,arg2)
其中,(i)為三元式的編號,也代表了該式的運算結果,op,arg1,arg2的含義與四元式類似,區別在於arg可以是某三元式的序號,表示用該三元式的結果作為運算物件。
例:a:=b*-c+b*-c
三元式和四元式的比較
相同點:
1、無論在一個三元式序列還是四元式序列中,各個三元式或四元式都是按相應表示式的實際運算順序出現的;
2、對同一表示式而言,所需的三元式或
四元式的個數一般都是相同的。
不同點:
1、由於三元式沒有result欄位,且不需要臨時變數,故三元式比四元式佔用的儲存空間少;
2、在進行程式碼優化處理時,常常需要挪動一些運算的位置,這對於三元式序列來說是很困難的,但對於四元式來說,由於四元式之間的相互聯絡是通過臨時變數來實現的,所以,更改其中一些四元式給整個系列帶來的影響就比較小。
三地址程式碼-間接三元式建立兩個與三元式有關的表格,一個稱為三元式表,用於存放各三元式本身;另一個稱為執行表,它按照三元式的執行順序,依次列出相應各三元式在三元式表中的位置,也就是說我們用一個三元式表連同執行表來表示中間程式碼。通常我們稱這種表示方法為間接三元式。
三元式
x:=(a+b)*c
b:=a+b
y:=c*(a+b)
(1)(+,a,b) (5) (+,a,b)
(2)(*,(1),c) (6)(*,c,(5))
(3)(:=,x,(2)) (7)(:=,y,(6))
(4)(:=,b,(1))
間接三元式執行表 三元式表
(1) (1)(+,a,b)
(2) (2)(*,(1),c)
(3) (3)(:=,x,(2))
(4) (4)(:=,b,(1))
(1) (5)(:=,y,(2))
(2)
(5)
三元式與間接三元式之間的區別1、由於間接三元式在執行表中已經依次列出每次要執行的那個三元式,若其中有相同的三元式,則僅需在三元式表中儲存其中之一,即三元式的項數一般比執行表的項數少;
2、當進行程式碼優化需要挪動運算順序時,則只需對執行表進行相應地調整,而不必再改動三元式本身,這樣,就避免了前面講到的因改變三元式的順序所引起的麻煩。
語法制導的翻譯方法:
就是對文法中的每個產生式都附加一個
語義動作或語義子程式,且在語法分析過程中,每當需要使用一個產生式進行推導或歸約時,語法分析程式除執行相應的語法分析動作之外,還要執行相應地語義動作或語義子程式。每個語義子程式都指明瞭相應產生式中各個符號的具體含義,並規定了使用該產生式進行分析時所應採取的語義動作
這種模式既把語法分析與語義處理分開,又
令其平行地進行,讓其在同一遍掃描中同時完成語法分析和語義處理兩項工作。
7.2 說明語句的翻譯
一.過程中的說明語句
說明語句的翻譯,主要工作是填符號表、分配地址
說明語句的文法產生式及語義動作如下:
7.3 賦值語句的翻譯
7.3.1 簡單算術表示式及賦值語句的翻譯
簡單算術表示式及賦值語句的產生式及語義動作如下:
Lookup為查符號表過程
Emit過程用於生成三地址碼指令語句並送往輸出檔案
7.3.2陣列元素的引用
一、陣列元素的地址計算
1、一維陣列
設陣列A[low..n],每個元素佔w個單元,則
LOC(A[i])=base+(i-low)*w
=i*w+(base-low*w)
其中varpart=i*w C=low*w
conspart=base-C
即地址 D= varpart+conspart
2、二維陣列(按行存放)
設 i1,i2的下界為low1,low2,陣列是n1×n2,每個元素佔w個單元,則
LOC(A[i1,i2])=base+((i1-low1)*n2+i2-low2)*w
=(i1*n2+i2)*w+(base-(low1*n2+low2)*w)
其中varpart=(i1*n2+i2)*w
C=(low1*n2+low2)*w)
conspart=base-C
即地址D=varpart+conspart
例:
A [x] 地址可變部分為x*W, 應生成指令:
(T’:=X*W)
A [x,y] 地址可變部分為(x*n2+y) *W, 應生成指令:
(T1:=X*n2)
(T1:=T1+y)
(T’:=T1*W)
A [x,y,z]地址可變部分為((x*n2+y)*n3+z) *W, 應生成指令:
(T1:=X*n2)
(T1:=T1+y)
(T2:=T1*n3)
(T3:=T2+z)
(T’:=T3*W)
地址不變部分的指令為:(T=A-C)
地址結果指令為:(T’’=T[T’])
二、賦值語句中陣列元素的翻譯
含陣列元素的賦值語句的文法
7.4布林表示式的翻譯
相關推薦
第七章 語義分析和中間程式碼生成
1、 編譯程式的任務是把源語言程式翻譯成目標程式,有些編譯程式在編譯過程中,不產生中間語言,而是直接從源語言程式翻譯成目標語言程式。 以上編譯過程省略了中間語言,它不利於編譯所產生的目的碼的優
編譯原理第七章-語義分析和中間程式碼產生
語義分析的任務是:1.審查每一個語法結構的靜態語義,即驗證語法正確的結構是否有意義。2.在語義正確的基礎上生成一種中間程式碼或目的碼。語義分析的範圍是:1.確定型別:確定識別符號所關聯的資料型別。2.型別檢查:按語言的型別規則,檢查運算的合法性與運算分量型別的一致性,必要時作
編譯原理第七章——語義分析和中間程式碼的產生
1、知識點圖重點記憶:說明語句的翻譯 程式語言中的說明語句都是給編譯程式提供資訊的,諸如型別、維數、每維的界種類等,因此一般不生成目標,只是在編譯時把有關資訊填入相應表格即可。賦值語句的翻譯 1.簡單算術表示式的賦值語句: 所謂簡單指不考慮陣列元素、記錄、函
第七章:語義分析和中間程式碼的產生
一.語義分析概述1.語義分析的任務 1)審查每一個語法結構的靜態語義,即驗證語法正確的結構是否有意義。如:賦值語句:x:=x+y,左邊變數型別與右邊變數型別是否一致。2)在語義正確的基礎上生成一種中間程式碼或目的碼。2.語義分析的範圍1)確定型別:確定識別符號所關聯的資料型別
《利用python進行資料分析.第三版》 第七章 資料清洗和準備
7.1 處理缺失資料 缺失資料在pandas中呈現的方式有些不完美,但對於大多數使用者可以保證功能正常。對於數值資料,pandas使用浮點值NaN(Not a Number)表示缺失資料。我們稱其為哨兵值,可以方便的檢測出來。 處理缺失資料有以下幾個方
第十章-語義分析之類型檢查
編譯 表達式 第十章 階段 靜態 實現 循環 由於 靜態類型 由於Java是靜態類型的語言,所以在編譯階段,所有的變量都能得出確定的類型。 1、類型循環繼承、循環引用 Java是單繼承的,也就是說Java只能繼承一個實現類。但是在繼承過程中可能會形成循環,接口也是。
(譯)Netty In Action第七章—事件迴圈和執行緒模型
請尊重勞動成果,未經本人允許,拒絕轉載,謝謝! 這章包涵以下內容 - 執行緒模型概覽 - 事件迴圈概念和實現 - 任務排程 - 實現細節 簡單地說,執行緒模型指定了OS、程式語言、框架或應用程式的上下文中的執行緒管理的關鍵方面。執行緒創造的方式和時間明顯對於應用程
第5章 概率分析和隨機演算法
練習 5.1-1 證明:因為在過程HIRE-ASSISTANT的第4行中,我們總能決定哪一個應聘者最佳,所以我們能比較任意兩個應聘者的好壞,則意味著我們知道應聘者排名的全部次序。 5.2-1 當面試的第一個應聘者是最好的應聘者時,你正好僱用一次。所以你正好僱用一次的概
NeHe OpenGL教程 第七課:光照和鍵盤 程式碼
#include <windows.h> // Windows的標頭檔案 #include <glew.h> // 包含最新的gl.h,glu.h庫 #include <glut.h> // 包含OpenGL實用庫 #include <stdio.h
第七章:模組和庫類
第一節:關於模組和類庫 使用系統標準庫 什麼是模組? 可以說,一個 xxx.py 就是一個模組。 什麼是類庫? 裝有很多個模組的資料夾包,可以稱為一個類庫,更多的時候,這些python檔案都是有機關聯的。 有了模組和類庫,我們可以輕鬆地站在巨人的肩膀上進行程
第4章 需求分析和model設計
本章主要內容: django app的設計 各個app models的設計 資料表生成與修改 django app的設計 安裝環境python27下 建立虛擬環境 mkvirtualenv mxonline pip inst
linux學習第七章使用RAID和LVM磁碟陣列技術
一、RAID磁碟冗餘陣列 1988年,加利福尼亞大學伯克利分校首次提出並定義了RAID技術的概念。RAID技術通過把多個硬碟裝置
編譯原理實驗報告一:PL0語言編譯器分析(PL0,詞法分析,語法分析,中間程式碼生成)
實驗報告一:PL0語言編譯器分析一、實驗目的 通過閱讀與解析一個實際編譯器(PL/0語言編譯器)的原始碼, 加深對編譯階段(包括詞法分析、語法分析、語義分析、中間程式碼生成等)和編譯系統軟體結構的理解,並達到提高學習興趣的目的。二、實驗要求(1) 要求掌握基本
編譯原理實驗報告三:語法分析(PL0,詞法分析,語法分析,中間程式碼生成)
實驗報告三:語法分析一、實驗目的 通過設計、開發一個S語言的語法分析程式,實現對源程式的語法檢查和結構分析,加深對相關課堂教學內容的理解,提高語法分析方法的實踐能力。二、實驗要求根據下列S語言的語法規則,進行語法分析(1) <程式>→[<常量說明
快學scala 第七章 包和引入 讀書筆記及習題答案程式碼
chapter 7 包和引入 標籤:快學scala 一、筆記 scala中的包名是相對的,原始檔的目錄與包之間沒有強制的關聯關係,完全可以在同一檔案中為多個包貢獻內容。 包可以包含類、物件和特質,但是不能包含函式和變數的定義,這是java虛擬機器的侷限,但是包物件
第七章之main函數和啟動例程
gcc 清理 其它 運行 start call 返回 argv -a main函數和啟動例程 為什麽匯編程序的入口是_start,而C程序的入口是main函數呢?本節就來解釋這個問題。在講例 18.1 “最簡單的匯編程序”時,我們的匯編和鏈接步驟是: $ as hello
第八章需求分析跟第九章項目經理學習總結------(第七)
總結 重新 需求 需求分析 需求量 團隊項目 div 改進 缺點 本周我看了第八章需求分析跟第九章項目經理,以下是我的學習總結。 一 .如何了解用戶的軟件需求 1.獲取和引導需求。軟件團隊需要找到軟件的利益相關者,了解和挖掘他們對軟件的需求,引導他們表達出軟件的需求。軟件團
深入.NET平臺和C#編程筆記 第七章 深入理解多態
定義 方式 目前 rtu ride 筆記 總結 理解 hello 第七章 深入理解多態 1.裏氏替換原則: 在一個軟件系統中,如果子類出現在父類出現的位置,而整個軟件功能又沒有影響,那麽咱們稱為裏氏替換。 父類變量指向子類對象!! 2.Is 和as Is
Python第七課----正則和日誌分析
python一、正則表達式:1、分類: 1、BRE基本正則,grep、sed,vi等軟件支持,vim有擴展 2、ERE擴展正則,egrep、grep-E,sed-r等 3、PCRE最重要的,高級語言中的2、基本語法: 1、元字符 metacharacter.匹配除了換行符外任意一字符,叠代
第七章 if條件語句的知識和實踐(郵件報警)
current num 任務 bar == 數字 tee centos dev 範例7-2:開發一個腳本判斷系統剩余內存的大小,如果低於100MB,就郵件報警給系統管理員,並將腳本加入系統定時任務,即每3分鐘執行一次。首先搞定郵件服務,我的centos 7上面沒有mail包