Atitti. 語法樹AST、後綴表達式、DAG、三地址代碼

Atitti. 語法樹AST、後綴表達式、DAG、三地址代碼javascript

 

 

抽象語法樹的觀點認爲任何複雜的語句嵌套狀況均可以藉助於樹的形式加以描述。確實,不得不認可應用抽象語法樹可使語句翻譯變得相對容易,它很好地描述了語句、表達式之間的聯繫。不過,因爲Neo Pascal並不會顯式構造抽象語法樹,因此不得不借助於其餘數據結構實現。根據先前的經驗,棧結構就是不二之選。html

 

DAG(有向無環圖)java

 

後綴表達式:也稱爲逆波蘭表達式,這種形式簡單明晰,便於存儲。在處理表達式翻譯時,後綴表達式有着其餘形式沒法比擬的優點。不過,因爲後綴表達式的應用領域比較單一,因此不多獨立做爲一個實際編譯器的IR存在。程序員

1. 後綴表達式

 編輯算法

不包含括號,運算符放在兩個運算對象的後面,全部的計算按運算符出現的順序,嚴格從左向右進行(再也不考慮運算符的優先規則,如:(2 + 1) * 3 , 即2 1 + 3 *後端

做者::  ★(attilax)>>>   綽號:老哇的爪子  全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿爾 拉帕努伊  漢字名:艾龍,  EMAIL:1466519819@qq.com數據結構

轉載請註明來源: http://www.cnblogs.com/attilax/架構

 

1.1. 前綴記法、中綴記法和後綴記法

它們都是對錶達式的記法,所以也被稱爲前綴記法、中綴記法和後綴記法。它們之間的區別在於運算符相對與操做數的位置不一樣:前綴表達式的運算符位於與其相關的操做數以前;中綴和後綴同理。

舉例:
(3 + 4) × 5 - 6 就是中綴表達式
- × + 3 4 5 6 前綴表達式
3 4 + 5 × 6 - 後綴表達式優化

 

中綴表達式(中綴記法)
中綴表達式是一種通用的算術或邏輯公式表示方法,操做符以中綴形式處於操做數的中間。中綴表達式是人們經常使用的算術表示方法。
雖然人的大腦很容易理解與分析中綴表達式,但對計算機來講中綴表達式倒是很複雜的,所以計算表達式的值時,一般須要先將中綴表達式轉換爲前綴或後綴表達式,而後再進行求值。對計算機來講,計算前綴或後綴表達式的值很是簡單。ui

 

 

三地址代碼:也稱爲"四元組",即操做符和三個操做數地址。這是一種最爲常見的IR。甚至有些書籍認爲IR就是中間代碼(即三地址代碼

 

 

所謂的三地址,指的就是每一行代碼一般包含三個地址信息,即操做數一、操做數二、結果操做數。例如,(ADD  A,1,C )這行三地址代碼的含義就是A+1→C。這種形式初看與彙編語言有點相似

固然,三地址代碼也不是完美的,因爲它是相對離散的,在分析源程序結構方面,它就不及語法樹便捷

 

 

 三地址代碼的理由以下:三地址代碼是一種線性IR。因爲輸入源程序及輸出目標程序都是線性的,所以,線性IR有着其餘形式沒法比擬的優點。另外,相對於其餘表示形式而言,程序員對於線性表示形式一般會有一種莫名的親切感,編譯器設計者固然也不例外。早期編譯器設計者每每都是彙編語言程序設計的高手,能夠很是天然、流暢地閱讀線性的三地址代碼形式。同時,線性表示形式也會下降輸入輸出的實現難度。隨着編譯器"端"、"遍"等概念的出現,IR已經不只僅是一種存儲在內存中的數據結構。有時它也須要以文件形式轉存輸出,做爲接口供其餘系統讀取使用。

 

爲何將其設計爲"三地址"的形式呢?實際上,這是計算機科學家通過多年實踐探索後才獲得共識的。三地址代碼並非惟一的線性IR,只能說是最爲常見的而已。在編譯技術領域,二地址代碼、單地址代碼(即棧式機代碼)都曾出現過,也曾在某些應用領域盛行一時,尤爲是單地址代碼。

 

然而,單地址代碼的狀況則大相徑庭了,在現代編譯器設計中,單地址代碼也是應用比較普遍的一種IR。尤爲是近年隨着混合語言的日漸壯大,單地址代碼也從新進入了人們的視野。因爲執行單地址代碼程序的棧式機架構相對比較簡單,能夠很是方便地構造相關的解釋器或虛擬機,因此單地址代碼深受混合語言設計者的歡迎。讀者熟悉的Java字節碼、.NET的IL都是單地址代碼

 

三地址代碼是在二地址代碼的基礎上發展而來的。二地址代碼的不足之處在於它一般會給其中一個源操做份量帶來必定反作用。固然,這種設計的靈感最初是來源於x86指令系統的,可是卻忘了一個重要的區別:x86指令中每每都是以寄存器做爲暫存空間的。而暫存空間對於二地址代碼倒是一個棘手的問題。爲了解決二地址代碼的不足,人們提出了一個對源操做份量不產生任何反作用的形式,那就是三地址代碼。也就是說,在一行三地址代碼中,任何運算都不會改變兩個源操做份量。這是三地址代碼與二地址代碼的主要區別。這個特性是很是重要的,它將使得編譯器更自由地複用名字與值,沒必要考慮代碼帶來的反作用。

 

最後,再來談談IR的級別,即IR依賴於目標機的程度。按級別分類,可將IR分紅三類:高級形式(HIR)、中級形式(MIR)、低級形式(LIR),也可稱爲高級中間語言、中級中間語言、低級中間語言。

高級形式(HIR)是一種儘量保持了源語言程序結構的IR,這種形式能較好地保留源程序的原始語義信息。因爲高級形式太接近源語言程序結構,因此不多有編譯器將其獨立做爲IR傳遞給後端。

中級形式(MIR)既要以一種與語言無關的方式在必定程度上反映源語言的特性,又要可以適應多種體系結構的IR。中級形式是一種比較經常使用的IR,它兼顧了源語言、目標機的特性,又能適用於大多數優化算法。當一個編譯器僅設計一種IR時,中級形式是較理想的選擇。

低級形式(LIR)就是在必定程度上包含某些目標機特性的IR,比目標語言稍高級,常做爲一些機器相關的優化算法的輸入。不過,實際上,除了一些較大型的編譯器須要使用低級形式以外,低級形式並非很常見。由於更多編譯器設計者更願意直接基於目標語言做優化。

 

 

表5-6  if語句的翻譯方案

 

if語句

   

if <表達式> then

   <語句1>

else

   <語句2>

<表達式翻譯>

(JNT                   , <表達式結果> , null , __L1 )

<語句1>

(JMP                   , __L2 , null , null )

(LABEL              , __L1 , null , null )

<語句2>

(LABEL              , __L2 , null , null )

 

若是省略了else部分,那麼只需將翻譯方案中第4~6行語句省略,並將第7行的"__L2"替換爲"__L1"便可。semantic06八、semantic06九、semantic070主要的功能就是根據翻譯方案翻譯輸入的if語句。也就是說,試圖依靠這三個語義子程序,完成翻譯方案中黑體語句的生成。在上述翻譯方案中,能夠暫且將"__L1"稱爲"假分支標號",而將"__L2"稱爲"出口標號"。另外,需注意一點,當輸入語句是if-then結構時,第7行語句的標號不該該取出口標號,而應該取假分支標號,由於此時並不存在真正意義的假分支,所以,能夠將假分支標號看成出口標號使用。

 

while語句的翻譯方案

 

while語句

翻譯方案

while <表達式> do

      <語句>

(LABEL ,__L1,null,null)

<表達式翻譯>

(JNT               ,<表達式結果>,null,__L0)

<語句>

(JMP               ,__L1,null,null)

(LABEL ,__L0,null,null)

 

 

 

5.1.2 IR設計及其級別 - 51CTO.COM.html

相關文章
相關標籤/搜索