1. 程式人生 > >將算術表示式轉換成四元式的程式實現

將算術表示式轉換成四元式的程式實現

第一部分:實驗內容描述

29. 題目:將算術表示式轉換成四元式的程式實現

設計內容及要求:設計一個語法制導翻譯器,將算術表示式翻譯成四元式。要求:

先確定一個定義算術表示式的文法,為其設計一個語法分析程式,為每條產生式配備一個語義子程式,按照一遍掃描的語法制導翻譯方法,實現翻譯程式。對使用者輸入的任意一個正確的算術表示式,程式將其轉換成四元式輸出(可按一定格式輸出到指定檔案中)。

實驗原理:四元式是一個帶有四個域的記錄結構,這四個域分別為op,arg1,arg2及result。域op包含一個代表運算子的內部碼。

由於這種形式的中間程式碼便於優化處理,因此,在目前許多編譯程式中得到了廣泛的應用。具體的形式為:(op,arg1,arg2,result) 。

例如,語句 a=b+(c-d)*e+f/g*(h-i+j/(k+l*m-n)) 的四元式表示如下:

(1) (-,c,d,t1)

(2) (*,t1,e,t2)

(3) (+,b,t2,t3)

(4) (/,f,g,t4)

(5) (+,t3,t4,t5)

(6)(-,h,i,t6)

(7)(*,l,m,t7)

(8)(+,k,t4,t7)

(9)(-,t7,n,t8)

(10)(/,j,t8,t9)

(11)(+,t6,t9,t10)

(12)(=,t10,-,a)

1).檢查輸入的元素;

2).如果是一個運算元,則進棧;

3).如果是操作符,則

i). 如果符號棧不為空或者此操作符的優先順序大於符號棧棧頂的優先順序,則將此運算子壓棧;

ii).如果符號棧不為空或者此操作符的優先順序小於符號棧棧頂的優先順序,棧頂操作符出棧並進行相應的操作;

4).假定輸入完畢,棧中剩餘的所有操作符出棧並進行相應操作。

第二部分:實驗過程與結果分析

一、實驗過程(包括除錯方法描述、實驗資料記錄,實驗現象記錄,實驗過程發現的問題等)

按照順序將任意一個正確的算術表示式拆分成操作符和運算元部分併入棧,而後比較優先順序按照優先順序高低出棧,執行操作:將算術表示式轉換成四元式輸出。本程式共有兩個函式,一個將算術表示式翻譯成四元式的函式 int translate(string s),是本程式的主要函式;另一個是主函式,負責呼叫翻譯函式和輸入輸出處理。

具體如下:

先定義兩個棧結構用來儲存運算子號和字元,掃描整個算術表示式時,如果是字母則代表碰到一個變數,就無條件入棧,如果為”(”則表示下面會是一個在括號內進行的運算,且應該先運算,所以要不處理符號棧頂的符號,如果不是括號裡為負數的形式,將“(”進棧,否則先執行將負值賦給一個臨時變數,同時臨時變數入字元棧,並向下繼續搜尋,如果為“)”則一-定會執行完整個括號中的運算式,因此應該在碰到“=”或“(”停止四元式語句的產生,而對於一般的運算子號,則根本先算乘除後算加減,從左到右運算的原則,進行判定,從而確定是將運算子號存入棧還是用來產生四元式。還要注意的是“=”一定是在最後產生,依照這樣的法則就會產生四元式。以一個表示式為例:

Y=a+b*(c-(-d))

首先掃描到Y入字元棧,然後“=“入符號棧,然後a入字元棧,“+”入符號棧,b入字元棧,搜尋到“*”時,因為*優先順序比+大,所以入棧,再向後搜尋到“(”判斷得下一個不是“-”所以入棧,c入字元棧,再搜尋到“(”判斷得後面的為“-”,所以產生一個四元式uminus(負數標誌) d_ (空值標誌) T1 (新產生的臨時變數)再把T1 入字元棧,最後掃描到“)”則在棧頂不是“(”時將棧頂出棧同時產生四元式- c T1 T2,然後繼續產生四元式*bT2T3,+aT3T4,:=T4一Y,至此產生結束。

核心資料結構如下:

struct TOKEN

{

  char t;

  int i;

} ;

struct TOKEN word, sem[10];

  int i_sem;

 

struct QT

{

  char w;

  struct TOKEN word1;

  struct TOKEN word2;

  struct TOKEN temp;

} ;

編譯原理

完整程式碼見https://download.csdn.net/download/gyx1549624673/10840211