編譯原理課設(shè)報告最終版_第1頁
編譯原理課設(shè)報告最終版_第2頁
編譯原理課設(shè)報告最終版_第3頁
已閱讀5頁,還剩19頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、(燕山大學(xué)姓名學(xué)編譯原理課程設(shè)計PLO Experiment Report信息科學(xué)與工程學(xué)院)班級:計算機(jī)科學(xué)與技術(shù)生學(xué)號:課指程導(dǎo)名教稱:師:編譯原理2015年12月24日i一、設(shè)計目的研究、改進(jìn)或自行設(shè)計、開發(fā)一個簡單的編譯程序或其部分功能,加深對編譯理論和編譯過程的理解。編程語言不限。二、設(shè)計任務(wù)擴(kuò)展PL/O編譯程序功能目的:擴(kuò)充PL/0編譯程序功能要求:(1)閱讀、 研究PL/0編譯程序源文件。(2) 在上述工作基礎(chǔ)上,可有選擇地補(bǔ)充、完善其中詞法分析、語法分析、語義分析、目標(biāo)代碼生成、目標(biāo)代碼解釋執(zhí)行等部分的功能。 如以語法分析部分為例,則可以增加處理更多語法成分的功能,如可處 理一

2、維數(shù)組、+、-、+=、-=、*=、/=、(取余)、!(取反)、repeat、 for、else、開方、處理注釋、錯誤提示、標(biāo)示符或變量中可以有下劃線等。還可以增加類型,如增加字符類型、實數(shù)類型;擴(kuò)充函數(shù)如有返回值和返回語句的,有參數(shù)函數(shù)等;(3) 設(shè)計編制典型的運行實例,以便能反映出自己所作的改進(jìn)。三、設(shè)計思想:PL/0語言可以看成PASCAL語言的子集,它的編譯程序是一個編譯解 釋執(zhí)行系統(tǒng)。PL/0的目標(biāo)程序為假想棧式計算機(jī)的匯編語言,與具體計算機(jī)無關(guān)。PL/0的編譯程序和目標(biāo)程序的解釋執(zhí)行程序都是用PASCAL語言書寫 的,因此PL/0語言可在配備 PASCAL語言的任何機(jī)器上實現(xiàn)。其編譯

3、過程采用一趟掃描方式,以語法分析程序為核心,詞法分析和代碼生成 程序都作為一個獨立的過程,當(dāng)語法分析需要讀單詞時就調(diào)用詞法分析程 序,而當(dāng)語法分析正確需要生成相應(yīng)的目標(biāo)代碼時,則調(diào)用代碼生成程序。用表格管理程序建立變量、常量和過程表示符的說明與引用之間的信息聯(lián) 系。當(dāng)源程序編譯正確時,PL/0編譯程序自動調(diào)用解釋執(zhí)行程序,對目標(biāo)代碼進(jìn)行解釋執(zhí)行,并按用戶程序的要求輸入數(shù)據(jù)和輸出運行結(jié)果。四、設(shè)計內(nèi)容:1 擴(kuò)充語句for(語句 ; 條件 ; 語句 ) 語句;2 擴(kuò)充語句if 條件 then 語句 else 語句;3 擴(kuò)充語句repeat 語句;until 條件;4 增加自增自減運算+和一和+=,

4、-=運算;5 修改不等號#,為!=;6 增加一維數(shù)組聲明格式: <ide nt><ide nt>/<nu mber>:<ide nt>/<nu mber>賦值格式:<ident><index>:=<表達(dá)式 >調(diào)用格式:<ide nt><i ndex>五、程序結(jié)構(gòu):表格管理程序PL/O源程序圖1編譯程序結(jié)構(gòu)圖2功能模塊調(diào)用1. 功能模塊作用如下:PlO.c :主程序Error :出錯處理,打印出錯位置和錯誤編碼Getsy m:詞法分析,讀取一個單詞Getch :漏掉空格,讀取一

5、個字符Gen:生成目標(biāo)代碼,并送入目標(biāo)程序區(qū)Test :測試當(dāng)前符號是否合法Block :分程序分析處理過程,詞法語法分析Enter :登陸名字表Positi on :查找標(biāo)識符在名字表中的位置Constdeclaration :常量定義處理 Vardeclaraction :變量說明處理 Listcode :列出目標(biāo)代碼清單 Statement :語句處理Expression :表達(dá)式處理Term:項處理Factor :因子處理Condition :條件處理Interpret :對目標(biāo)代碼的解釋執(zhí)行程序Base :通過靜態(tài)鏈求出數(shù)據(jù)取得基地址 增加兩個功能:Arraydeclaration

6、:數(shù)組聲明處理Arraycoef :數(shù)組索引計算和“虛擬機(jī)”動作生成2. 保留字:enum symbol nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,period, becomes,beginsym,endsym,ifsym,thensym,elsesym,forsym, inc,dec,whilesym, writesym,readsym,dosym,callsym, constsym,varsym,procsym,repeatsym,

7、 untilsym, plusbk,minusbk,lbrack,rbrack,colon,共 43 個,其中補(bǔ)充保留字為:else, for, repeat, until,plusbk,minusbk,Lbrack, rbrack, colon3. 名字表中的類型enum object constant, variable, procedure, arrays, 共 4 個,擴(kuò)充 arrays ,以便實現(xiàn)數(shù)組4. 虛擬機(jī)代碼enum fct lit, opr, lod, sto, cal, inte, jmp, jpc, lda, sta, 共 10 個,補(bǔ)充的 lda , sta 用于數(shù)組

8、操作6. 錯誤信息(1) c on st,var,procedure后應(yīng)為標(biāo)識符(2) 常數(shù)說明中的= 后應(yīng)是數(shù)字(3) 常數(shù)說明中的標(biāo)識符后應(yīng)是=常數(shù)說明中的=寫成了:=漏掉了,或;(6) 過程說明后的符號不正確(應(yīng)是語句開始符,或過程定義符)(7) 應(yīng)是語句開始符(8) 標(biāo)識符未說明(9) 程序結(jié)尾丟了句號。(10) 語句之間漏了;(11) call后應(yīng)為標(biāo)識符(12) 賦值語句中,賦值號左部標(biāo)識符屬性應(yīng)是變量(13) 賦值號左部標(biāo)識符屬性應(yīng)是賦值號(14) 程序體內(nèi)語句部分的后跟符不正確(15) call后標(biāo)識符屬性應(yīng)為過程(16) 條件語句中丟了 then(17) 丟了 end 或;(

9、18) while 循環(huán)語句中丟了 do(19) 語句后的符號不正確6.名字表結(jié)構(gòu)struct tablestructchar n ameal;e num object kin d;i nt val;i nt level;i nt adr;int size;/擴(kuò)充名字表結(jié)構(gòu),增加一個data域保存數(shù)組的下界int data; /*其他數(shù)據(jù),對arrays來說是下界*/7. 語法描述圖:圖7表達(dá)式語法描述圖項因子 13圖8項語法描述圖圖9因子語法描述圖四、功能擴(kuò)充1.語句處理中加入for循環(huán)語句if(sym = forsym) getsymdo;沒有左括號出錯if(sym != Ipare n)

10、 error(34); else getsymdo;stateme ntdo (n xtlev, ptx, lev); S1 if(sym != semico Ion) error(10); / else代碼語句缺少分號出錯cx1=cx;getsymdo;con diti ondo(n xtlev, ptx, lev); E if(sym!=semicolo n)error(10);代碼語句缺少分號出錯else cx2=cx;gen do(jpc,0,0);cx3=cx;gen do(jmp,0,0);getsymdo;cx4=cx;statementdo(nxtlev, ptx, lev);

11、/S2 代碼if(sym != rparen) error(22);/ 缺少右括號出錯 else gendo(jmp,0,cx1); getsymdo;cx5=cx;statementdo(nxtlev, ptx, lev); /S3代碼codecx3.a=cx5;gendo(jmp,0,cx4); codecx2.a=cx; 2. 在語句處理中增加 repeat-until 語句if(sym = repeatsym) cx1 = cx; getsymdo; statementdo(nxtlev, ptx, lev);if(sym = untilsym) getsymdo; condition

12、do(nxtlev, ptx, lev); cx2=cx; gendo(jpc, 0, 0); codecx2.a=cx1; else error(33); / 沒有寫 until 出錯 3. 擴(kuò)充 +和運算符對于 +和 - 運算符,擴(kuò)充時要注意存在兩個情況: 1)作為語句的時候; 2) 作為表達(dá)式中的因子的時候。注 意 : 擴(kuò) 充 時 增 加 因 子 開 始 符 facbegsysincs=true 和 facbegsysdecs=true 。擴(kuò)充的語法描述見結(jié)構(gòu)設(shè)計中的 PL/0 分程序和主要語句的語法描述中的 描述圖,詳細(xì)代碼見程序。1)作為語句的時候,有四種情況:a+; a-; +a;

13、 -a;文法的EBNF表示形式為:< 自增自減語句 >:=< 標(biāo)識符 >+ |-|+|- <標(biāo)識符 >10文法分析過程大體如下圖:+a禾口一 aa+禾口 a生成中間代碼對于 a+;+a;和a-;-a;語句的處理如下:先將變量的值取出放在棧頂,后將1入棧,后執(zhí)行加法或減法運算oprv指令的2 (加法)、3 (減法),后將運算后的棧頂值存回變 量。a+;和 +a;語句的中間代碼:lod 0 3;lit 0 1;opr 0 2;sto 0 3;a-;和-a;語句的中間代碼:lod 0 3;lit 0 1;opr 0 3;sto 0 3;2)作為因子的時候,有兩種情

14、況:a+ 和a-作為因子,比如: b:=a+*a-; 語句+a 和-a作為因子,比如: b:=-a+2*+a; 語句文法的EBNF表示形式為:< 表達(dá)式 >:=.+|-< 標(biāo)識符 >|< 標(biāo)識符 >+| -.其中的表示前后都可以有其他的項或因子生成中間代碼A對于因子+a和-a的中間代碼生成處理和a+;等語句處理一樣;B對于因子a+和a的中間代碼生成處理如下:a+:lod 0 3;lit 0 1;opr 0 2;sto 0 3;lod 0 3;lit 0 1;opr 0 3;a-:lod 0 3;lit 0 1;opr 0 3;sto 0 3;lod 0 3;

15、lit 0 1;opr 0 2;先將變量的值取出放在棧頂,后將1入棧,后執(zhí)行加法或減法運算opr指令的2(加法)、3 (減法),后將運算后的棧頂值存回變量,后將 變量的值又取出來放入棧頂,后將1入棧,如果是a+就執(zhí)行減法,如果是a就執(zhí)行加法,以實現(xiàn)先用a的值后再加1。4. 語句處理中加入if-then-else 語句在原有程序if(sym=then).后加入下列代碼:cx1 = ex;gen do(jpe, 0, 0);stateme ntdo(fsys, ptx, lev);if(sym = elsesym)getsymdo;11 cx2 = cx;gendo(jmp, 0, 0);code

16、cx1.a = cx;statementdo(fsys, ptx, lev);codecx2.a = cx;elsecodecx1.a = cx;5. 修改不等號 #為 !=注釋源程序中的 ssym'#' = neq 語句,在 getsym 中加入下列代碼: / 修改不等號為 !=else if(ch='!')getchdo;if(ch='=')sym=neq;getchdo; else sym=nul; 6. 加入對一維數(shù)組的支持本程序?qū)?shù)組看做變量的一種,由 var 聲明函數(shù)調(diào)用 array 聲明函數(shù) 完成數(shù)組聲明,這樣就處加入文件輸出的相關(guān)

17、語句外,可以完全保留 block 函數(shù)和 enter 函數(shù);通過改寫 factor 函數(shù)使數(shù)組因子包括了后綴的 索引號,這樣就可以調(diào)用通用的表達(dá)式函數(shù)賦值數(shù)組了。為了方便完成數(shù)組相關(guān)功能,擴(kuò)充了虛擬機(jī)處理代碼。 數(shù)組的越界及非法調(diào)用錯誤處理沒有完善,僅給出了錯誤代碼。在頭文件 pl0.h 中:/* 定義兩個全局變量,用來保存數(shù)組定義的下界和容量 */ static int g_arrBase = 0;static int g_arrSize = 0;/* 虛擬機(jī)代碼 */ 增加 lda,sta 專門由于數(shù)組的處理/ 增加兩個虛擬機(jī)指令 lda,sta, 分別用來從數(shù)組中取數(shù)和存到數(shù)組中/ 數(shù)組

18、元素的訪問和存儲,是將 () 后的當(dāng)成表達(dá)式,先處理,得到元 素的索引,放在棧頂/ 最后根據(jù)數(shù)組的首地址,得到某個元素的地址enum fct .lda, sta / 擴(kuò)充名字表結(jié)構(gòu) , 增加一個 data 域保存數(shù)組的下界struct data; /*其他數(shù)據(jù) , 對 arrays 來說是下12界*/* 名字表中的類型 */enum object .arrays /添加數(shù)組類型 / 數(shù)組聲明處理 , 下界和上界允許已經(jīng)定義過的常量標(biāo)識符int arraydeclaration(int* ptx, int lev, int* pdx);/ 數(shù)組元素索引計算與“虛擬

19、機(jī)”生成int arraycoef(bool *fsys,int *ptx,int lev);在源程序文件 pl0.c 中:編寫相關(guān)的 arraydeclaration , arraycoef 兩個功能函數(shù): /* 數(shù)組聲明處理 , 下界和上界允許已經(jīng)定義過的常量標(biāo)識符 */ int arraydeclaration(int* ptx, int lev, int* pdx)char arrIdal; /* 暫存數(shù)組標(biāo)識名 , 避免被覆蓋 */ int cstId; /*常量標(biāo)識符的位置 */int arrBase=-1, arrTop=-1; /*數(shù)組下界、上界的數(shù)值 */getsymdo;i

20、f(sym=lbrack) /* 標(biāo)識符之后是 '', 則識別為數(shù)組 */ strcpy(arrId, id);/* 檢查下界 */getsymdo;if(sym=ident)if(cstId=position(id,(*ptx)!=0) arrBase=(constant=tablecstId.kind)?tablecstId.val:-1; else arrBase=(sym=number)?num:-1;if(-1=arrBase)error(50);return -1; /* 檢查冒號 */getsymdo;if(sym!=colon)error(50);return

21、-1;/* 檢查上界 */getsymdo;if(sym=ident)if(cstId=position(id,(*ptx)!=0)arrTop=(constant=tablecstId.kind)?tablecstId.val:-1;else arrTop=(number=sym)?num:-1;13 if(arrTop=-1) error(50); / 隨意指定 , 因為原程序?qū)﹀e誤號的規(guī)劃極差 return -1;/* 檢查 '' */getsymdo;if(sym!=rbrack)error(50);return -1;/* 上下界是否符合條件檢查 */ g_arrSi

22、ze=arrTop-arrBase+1;g_arrBase=arrBase;if(g_arrSize<=0) error(50); return -1;/* 恢復(fù)數(shù)組的標(biāo)識符 */strcpy(id, arrId);return 1;return 0;/* 數(shù)組元素索引計算與“虛擬機(jī)”生成 */int arraycoef(bool *fsys,int *ptx,int lev)bool nxtlevsymnum;int i = position(id,*ptx);getsymdo;if (sym=lbrack) /* 索引是括號內(nèi)的表達(dá)式 */ getsymdo;memcpy(nxtle

23、v,fsys,sizeof(bool)*symnum); nxtlevrbrack=true;expressiondo(nxtlev,ptx,lev);if (sym=rbrack)gendo(lit,0,tablei.data);gendo(opr,0,3); /* 系數(shù)修正 , 減去下界的值 */ return 0; else error(22); /* 缺少右括號 */else error(51); /* 數(shù)組訪問錯誤 */ return -1;14修改函數(shù) enter ,block ,vardeclaration , factor 及 statement ,使 其具備處理數(shù)組的功能:

24、/ 將數(shù)組變量登陸名字表 void enter(enum object k, int * ptx, int lev, int * pdx)case arrays: /*數(shù)組名 , 進(jìn)行記錄下界等 */table(*ptx).level = lev;table(*ptx).adr = (*pdx); table(*ptx).data = g_arrBase; table(*ptx).size = g_arrSize;*pdx = (*pdx)+g_arrSize;break;./ 輸出數(shù)組名字表到控制臺和文件 fas.tmpint block(int lev, int tx, bool * fs

25、ys)case arrays: printf("%d array %s ", i, ); printf("lev=%d addr=%d size=%dn", tablei.level, tablei.adr, tablei.size);fprintf(fas, "%d array %s ", i, );fprintf(fas, "lev=%d addr=%d size=%dn", tablei.level, tablei.adr, tablei.size);/ 加入數(shù)組聲

26、明int vardeclaration(int * ptx, int lev, int * pdx)int arrayRet=-1;if (sym=ident)arrayRet=arraydeclaration(ptx,lev,pdx); /* 先判斷數(shù)組 */ switch(arrayRet)case 1:enter(arrays,ptx,lev,pdx); / 填寫數(shù)組名 getsymdo;break;case 0:enter(variable,ptx,lev,pdx); / 填寫名字表 /getsymdo;break;15 default:return -1; /* 數(shù)組定義解析出錯 *

27、/else error(4); /* var 后應(yīng)是標(biāo)識 */return 0;/* 當(dāng)因子是數(shù)組型變量時,調(diào)用 arraycodefdo 將數(shù)組的索引入棧頂,之后 按 vatiabler 變量操作 */int factor(bool * fsys, int * ptx, int lev)switch (tablei.kind)case arrays: /* 名字為數(shù)組名 */ arraycoefdo(fsys,ptx,lev); gendo(lda,lev-tablei.level,tablei.adr); /* 找 到變量地址并將其值入棧 */. . int statement(bool

28、* fsys, int * ptx, int lev)if (sym = ident)if (tablei.kind != variable)&&(tablei.kind != arrays)error(12); i = 0;elseenum fct fct1 = sto; switch(tablei.kind)case arrays: arraycoefdo(fsys, ptx, lev); fct1 = sta; /*數(shù)組保存 , 要多讀一個棧 */case variable:. / 增加的兩個虛擬機(jī)代碼的處理 :lda,stavoid interpret()case ld

29、a: /* 數(shù)組元素訪問 ,當(dāng)前棧頂為元素索引 ,執(zhí)行后 ,棧頂變成 元素的值 */st-1 = sbase(i.l,s,b) + i.a + st-1;break;case sta: /* 棧頂?shù)闹荡娴綌?shù)組中 , 索引為次棧頂 */16t-=2;sbase(i.l,s,b) + i.a + st = st+1;break; .五、調(diào)試及運行結(jié)果1.測試 repeat.until.測試文件:4.txtvar a,b ,n;beginb:=4;a:=1;read( n);repeata:=a+1;b:=b+1;un til a>n;write(a);write(b);en d.當(dāng)輸入的 n 為 3 時,repeat.until. a=4,b=7語句功能測試結(jié)果:start plO?37語句中的循環(huán)體執(zhí)行 3,所以2.測試增加的+,-功能測試文件:2.txt var a,b;測試結(jié)果:begina:=1;b:=3;a+;b-; write(a); write(b);start plO22end.3.測試 if-then-else 功能測試文件:3.txt測試結(jié)果:

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論