P - 簡單的程式碼生成程式【編譯原理】
阿新 • • 發佈:2020-12-10
P - 簡單的程式碼生成程式
Description
通過三地址程式碼序列生成計算機的目的碼,在生成演算法中,對暫存器的使用順序為:暫存器中存有 > 空暫存器 > 記憶體中存有 > 以後不再使用 > 最遠距離使用
Input
單組輸入,給定輸出的三地址程式碼的個數和暫存器的個數.所有的變數為大寫字母,暫存器的數量不超過9
Output
參照示例格式輸出,不需要將最後的暫存器中的值寫回記憶體
不再使用變數不用寫回記憶體
Sample
Input
4 2 T:=A-B U:=A-C V:=T+U W:=V+U
Output
LD R0, A SUB R0, B LD R1, A SUB R1, C ADD R0, R1 ADD R0, R1
#include <bits/stdc++.h> using namespace std; char p[100];// 模擬暫存器的個數 char s[100][100];// 輸入表示式字串 int n,m,top = 0;//n輸入的表示式,m是暫存器個數 // 暫存器中是否存在該變數 int get(char ch) { for(int i = 0; i < m;i ++) { if(ch == p[i]) return i; } return -1; } ///暫存器的使用順序為: ///暫存器中存有 > 空暫存器 > 記憶體中存有 > 以後不再使用 > 最遠距離使用 //判斷後面是否還會使用 //x是輸入表示式的編號,語句執行順序 //ch需要判斷的字元 int use(int x, char ch) { for(int i = x; i < n; i ++) { // A:=B+C這裡就是B、C // 如果有就返回第幾句用到 if(ch == s[i][3] || ch == s[i][5]) return i; } return n; } ///暫存器的使用順序為: ///暫存器中存有 > 空暫存器 > 記憶體中存有 > 以後不再使用 > 最遠距離使用 int find(int x) { // 如果top小於m,就說明就空的暫存器可以使用 if(top < m) return top++; //否則就是 int t = -1; int ans = -1; for(int i = 0; i < m; i ++) { // 逐個判斷在第x句之後,存在暫存器中的字元的使用順序 // 返回值k是執行順序的標號 int k = use(x,p[i]); // 我們的目的是找到最遠不適用的,如果返回值越大,那就是最遠不適用的 // 記錄標號存在t裡面 if(k > ans) { ans = k; t = i; } } return t; } // 減加乘除 void print1(char ch) { if(ch == '+')printf("ADD "); else if(ch == '-') printf("SUB "); else if(ch == '*') printf("MUL "); else if(ch == '\\') printf("DIV "); } // 第二個運算元的使用 void print2(char ch) { // 檢視是否在暫存器中 int x = get(ch); // 如果在暫存器中,那就直接使用 if(x != -1){ printf("R%d\n",x); } else { // 否則就直接使用記憶體中的即可,因為已經有一個暫存器了 printf("%c\n",ch); } } int main() { cin >> n >> m; for(int i = 0; i < n;i ++) { cin >> s[i]; } for(int i = 0; i < n; i ++) { // 將第1個運算元取出來,get()來獲取暫存器中是否存在該變數 // T:=A-B中的A int x = get(s[i][3]);//如果不為-1,得到的x為所在暫存器的標號 // 如果x為-1說明該數不在暫存器中,需要做處理 if(x == -1) { //此時的x是我們可以使用的暫存器標號 x = find(i); // 如果p[x]中有東西,並且use(i,p[x]) < n即後面會使用到 //那我們就把原來在暫存器中的字元ST到記憶體中 if(p[x] != '\0' && use(i,p[x]) < n) { printf("ST R%d, %c\n",x,p[x]); p[x] = NULL; } //將該運算元載入到我們使用的暫存器標號中 printf("LD R%d, %c\n",x,s[i][3]); } // 這裡下面的操作就是執行運算 // 1、輸出操作符,這裡是加減乘除 print1(s[i][4]); //2、輸出暫存器標號,需要的運算元已經載入到裡面了 printf("R%d, ",x); //3、第二個運算元的使用 print2(s[i][5]); // 暫存器中當前存的數值就是該表示的左邊的字元,即T:=A-B中的T p[x] = s[i][0]; } return 0; }