PLO語(yǔ)言功能擴(kuò)展(case語(yǔ)句和for語(yǔ)句)_第1頁(yè)
PLO語(yǔ)言功能擴(kuò)展(case語(yǔ)句和for語(yǔ)句)_第2頁(yè)
PLO語(yǔ)言功能擴(kuò)展(case語(yǔ)句和for語(yǔ)句)_第3頁(yè)
PLO語(yǔ)言功能擴(kuò)展(case語(yǔ)句和for語(yǔ)句)_第4頁(yè)
PLO語(yǔ)言功能擴(kuò)展(case語(yǔ)句和for語(yǔ)句)_第5頁(yè)
已閱讀5頁(yè),還剩8頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、汕頭大學(xué) 08計(jì)算機(jī)科學(xué)與技術(shù) 編譯原理實(shí)驗(yàn)報(bào)告 編譯原理實(shí)驗(yàn)報(bào)告 一實(shí)驗(yàn)?zāi)康模菏炀氄莆誔LO語(yǔ)言編譯程序的結(jié)構(gòu)和功能;二實(shí)驗(yàn)要求: 擴(kuò)充PLO語(yǔ)言的功能,增加for語(yǔ)句和case語(yǔ)句;已知for語(yǔ)句和case語(yǔ)句的語(yǔ)法如下: <for語(yǔ)句>:=for(賦值語(yǔ)句;關(guān)系表達(dá)式) do <語(yǔ)句> <關(guān)系表達(dá)式>:=<表達(dá)式><關(guān)系運(yùn)算符><表達(dá)式> <case語(yǔ)句>:=<case><標(biāo)識(shí)符>:<常量>:<語(yǔ)句>endcase .3. 實(shí)驗(yàn)環(huán)境與工具:(1)計(jì)算機(jī)及操作

2、系統(tǒng):WindowsXP(2)程序設(shè)計(jì)語(yǔ)言:C(3)編譯程序:PL/0 (4)實(shí)現(xiàn)工具(平臺(tái)):VC+6.04 設(shè)計(jì)方案:1. 概述: 源語(yǔ)言:pl0 目標(biāo)語(yǔ)言:類(lèi)pcode代碼 實(shí)現(xiàn)工具(平臺(tái)):VC+6.02. 結(jié)構(gòu)設(shè)計(jì)說(shuō)明: PlO所有子程序如下:過(guò)程或函數(shù)名簡(jiǎn)要功能說(shuō)明main初始化編譯環(huán)境,建立關(guān)鍵字表,調(diào)用分程序Block對(duì)源文件進(jìn)行編譯,當(dāng)編譯正確時(shí),自動(dòng)調(diào)用解釋執(zhí)行程序,對(duì)目標(biāo)代碼進(jìn)行解釋執(zhí)行。error出錯(cuò)處理,打印出錯(cuò)位置和錯(cuò)誤性質(zhì)編號(hào)。并在信息欄輸出錯(cuò)誤信息。getch過(guò)濾空格,讀取一個(gè)字符getsym詞法分析,讀取一個(gè)單詞gen生成目標(biāo)代碼(類(lèi)pcode代碼),并送入目

3、標(biāo)程序區(qū)。test測(cè)試當(dāng)前單詞是否是合法block分程序分析處理過(guò)程。enter登錄過(guò)程說(shuō)明對(duì)象包括變量、常量和過(guò)程名的屬性信息到符號(hào)表。position查找標(biāo)識(shí)符在符號(hào)表中的位置。constdeclaration常量定義處理,收集常量信息并登錄到符號(hào)表。vardeclaration變量定義處理,收集變量信息并登錄到符號(hào)表。listcode列出目標(biāo)代碼清單。statement語(yǔ)法分析,語(yǔ)句部分處理。expression表達(dá)式分析處理。term項(xiàng)分析處理過(guò)程。factor因子分析處理。condition條件處理。interpret對(duì)目標(biāo)代碼進(jìn)行解析執(zhí)行。Base通過(guò)靜態(tài)鏈求數(shù)據(jù)區(qū)首地址。3. 增

4、加for語(yǔ)句:(1) 設(shè)計(jì)思想:For語(yǔ)句的語(yǔ)法分析:<for語(yǔ)句>:=for(賦值語(yǔ)句;關(guān)系表達(dá)式) do <語(yǔ)句>do;:=條件表達(dá)式identfor語(yǔ)句設(shè)計(jì)思路:主要分為兩部分模塊:一,for和;之間的賦值語(yǔ)句處理;二,條件語(yǔ)句處理和最后的語(yǔ)句處理。首先獲取賦值號(hào)左邊的標(biāo)識(shí)符,從符號(hào)表中找到它的信息,并確認(rèn)這個(gè)標(biāo)識(shí)符確為變量名。然后通過(guò)調(diào)用表達(dá)式處理過(guò)程算得賦值號(hào)右部的表達(dá)式的值并生成相應(yīng)的指令保證這個(gè)值放在運(yùn)行期的數(shù)據(jù)棧頂。最后通過(guò)前面查到的左部變量的位置信息,生成相應(yīng)的STO指令,把棧頂值存入指定的變量的空間,實(shí)現(xiàn)了賦值操作。返回函數(shù)值也是用賦值語(yǔ)句進(jìn)行返回值

5、的儲(chǔ)存。首先調(diào)用condition函數(shù)處理?xiàng)l件語(yǔ)句,并且把當(dāng)前condition處理生成的判斷條件操作代碼的的地址cx保存到cx1。每個(gè)循環(huán)體中,在循環(huán)體結(jié)束前,設(shè)置跳回判斷操作判斷當(dāng)前條件是否跳出循環(huán)。都把本循環(huán)體結(jié)束的下一個(gè)位置保存到cx2生成跳轉(zhuǎn),并在循環(huán)結(jié)束時(shí)用cx2更新為目前循環(huán)結(jié)束跳轉(zhuǎn)地址。難點(diǎn)分析:本模塊,主要難點(diǎn)是處理循環(huán)體的跳轉(zhuǎn),解決方法參照上點(diǎn)。不過(guò)可以參照if語(yǔ)句和while語(yǔ)句。(2) 擴(kuò)充代碼: 1)在頭文件pl0.h中的符號(hào)symbol中增加所要求增加的符號(hào),用加粗傾斜紅色字體標(biāo)出: 2)源代碼:if(sym=forsym) /* 準(zhǔn)備按照f(shuō)or語(yǔ)句處理 */get

6、symdo;if(sym=ident) /* 按照賦值語(yǔ)句處理 */i=postion(id,*ptx);if(i=0)error(11); /* 變量未找到 */elseif(tablei.kind!=variable)error(12); /* for語(yǔ)句格式錯(cuò)誤或者賦值語(yǔ)句格式錯(cuò)誤 */i=0;getsymdo;if(sym=becomes)getsymdo;else error(13); /* 檢測(cè)賦值符號(hào) */memcpy(nxtlev,fsys,sizeof(bool)*symnum);expressiondo(nxtlev,ptx,lev); /* 處理賦值符號(hào)右側(cè)表達(dá)式 */i

7、f(i!=0)gendo(sto,lev-tablei.level,tablei.adr); /* expression將執(zhí)行一系列指令,但最終結(jié)果將會(huì)保存在棧頂,執(zhí)行sto命令完成賦值 */ else error(17);cx1=cx; /* 保存判斷條件操作的位置 */getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlevdosym=true; /* 后跟符號(hào)為do */conditiondo(nxtlev,ptx,lev); /* 調(diào)用條件處理 */cx2=cx; /* 保存循環(huán)體的結(jié)束的下一個(gè)位置 */gendo(jpc,0,0)

8、; /* 生成條件跳轉(zhuǎn),但跳出循環(huán)的地址未知 */if(sym=dosym)getsymdo;else error(18); /* 缺少do */statementdo(fsys,ptx,lev); /* 循環(huán)體 */gendo(jmp,0,cx1); /* 回頭重新判斷條件 */codecx2.a=cx; /* 反填跳出循環(huán)的地址,與if類(lèi)似 */4. 增加case語(yǔ)句:(1) 設(shè)計(jì)思想:Case語(yǔ)句的語(yǔ)法分析:<case語(yǔ)句>:=<case><標(biāo)識(shí)符>:<常量>:<語(yǔ)句>endcase identcaseendcase語(yǔ)句:ide

9、nt:設(shè)計(jì)思路: 按照上述語(yǔ)法分析圖,先寫(xiě)出格式判斷,建立語(yǔ)句處理的框架。再細(xì)致寫(xiě)出偽代碼的生成核心部分。(以下分析中提及的“循環(huán)體”是指上面語(yǔ)法分析圖的循環(huán)結(jié)構(gòu)) 依照語(yǔ)法要求寫(xiě)出語(yǔ)法分析的框架,大致如上分析圖。 首先,將變量的位置存到blpst,供后面生成變量與常量比較指令用。用casenum記下case含有的情況個(gè)數(shù)。每個(gè)循環(huán)體開(kāi)始,取得常量之后,生成三條指令lod(將變量壓到棧頂)、lit(將常量押到棧頂)、opr 0 8(兩者作比較)。在生成后面語(yǔ)句的代碼之前,生成jpc利用變量和常量比較所得結(jié)果進(jìn)行跳轉(zhuǎn),若為假,則跳到本循環(huán)體結(jié)束的地方。接著,對(duì)循環(huán)體內(nèi)語(yǔ)句進(jìn)行處理。生成無(wú)條件跳轉(zhuǎn)

10、指令跳轉(zhuǎn)到case語(yǔ)句結(jié)束,由于地址未知,要等先把各個(gè)循環(huán)體中的無(wú)條件跳轉(zhuǎn)指令的地址放到cxjmpadr數(shù)組中,待case結(jié)束后再回填跳轉(zhuǎn)地址。最后,回填本循環(huán)體頭的條件跳轉(zhuǎn)地址。 難點(diǎn)分析:1.處理常量與變量的比較。一開(kāi)始以為應(yīng)該跟if語(yǔ)句類(lèi)似,處理常量與變量的比較的時(shí)候發(fā)現(xiàn)這一點(diǎn)跟if語(yǔ)句壓根不同,而且要難得多。不過(guò),后來(lái)認(rèn)識(shí)到變量的本質(zhì),從生成的匯編代碼的角度出發(fā),利用生成三條指令lod(將變量壓到棧頂)、lit(將常量押到棧頂)、opr 0 8(兩者作比較)解決了這個(gè)問(wèn)題。2.循環(huán)體的跳轉(zhuǎn)問(wèn)題,比較復(fù)雜。簡(jiǎn)單來(lái)說(shuō),三點(diǎn)跳轉(zhuǎn)的關(guān)鍵點(diǎn):一,循環(huán)體頭的判斷跳轉(zhuǎn);二,循環(huán)倒數(shù)第二個(gè)操作,跳出c

11、ase語(yǔ)句操作;三,最后的回填條件跳轉(zhuǎn)操作。(2)擴(kuò)充代碼: 1)在頭文件pl0.h中的符號(hào)symbol中增加所要求增加的符號(hào),用加粗傾斜紅色字體標(biāo)出:2)源代碼:if(sym=casesym) /*case 語(yǔ)句*/getsymdo;if(sym!=ident)error(14);/* case后應(yīng)為標(biāo)識(shí)符*/ elseint blpst=i=postion(id, *ptx);/*將變量的position保存在blpst中*/if(i=0)error(11);/* 標(biāo)識(shí)符未找到 */elseif(tablei.kind!=variable)error(38);/* case后的標(biāo)識(shí)符應(yīng)該為

12、變量 */getsymdo;if(sym!=colon)error(39);/*應(yīng)該為冒號(hào)*/elseint casenum=0;/*casenum記錄情況個(gè)數(shù)*/int cxjmpadr50;/*cxjmpadr用于存儲(chǔ)各 種情況中轉(zhuǎn)移指令的地址*/int cxb=cx;/*cxb存儲(chǔ)case語(yǔ)句開(kāi)始的指令地址*/int cjpc;/*當(dāng)前情況處理完常量標(biāo)號(hào)后的跳轉(zhuǎn)指令地址*/int varpst=i;/*存放case后面變量的position*/int conpst;/*存放當(dāng)前處理情況的常量標(biāo)號(hào)的position*/int jjj;for(jjj=0;jjj<50;jjj+)cxj

13、mpadrjjj=0; do getsymdo; if(sym!=ident)/*是否為標(biāo)識(shí)符*/error(37);/*case語(yǔ)句體中,冒號(hào)前面應(yīng)該為標(biāo)識(shí)符*/elseconpst=i=postion(id, *ptx);if(i=0)error(11);/* 標(biāo)識(shí)符未找到 */else if(tablei.kind!=constant)error(40);/* 標(biāo)識(shí)符應(yīng)該為常量 */getsymdo;if(sym!=colon)error(39);/*應(yīng)該為冒號(hào)*/memcpy(nxtlev, fsys, sizeof(bool)*symnum);nxtlevsemicolon=true

14、;nxtlevcolon=true;nxtlevendcasesym=true;/* 后跟符號(hào)為分號(hào)或end */getsymdo; gendo(lod,lev-tableblpst.level,tableblpst.adr);/*將case后變量放到棧頂*/ gendo(lit,lev-tableconpst.level,tableconpst.val);/*將當(dāng)前常量放到棧頂*/gendo(opr,0,8);/*將當(dāng)前棧頂和次棧頂比較,看是否相等,是為真,否為假放到 次 棧頂*/cjpc=cx;/*記住跳轉(zhuǎn)語(yǔ)句代碼地址*/gendo(jpc,0,0);/*設(shè)置條件跳轉(zhuǎn),地址暫時(shí)未知*/st

15、atementdo(nxtlev, ptx, lev);cxjmpadrcasenum+=cx;/*記住當(dāng)前情況的jmp語(yǔ)句代碼地址*/gendo(jmp,0,0);/*設(shè)置跳出case語(yǔ)句,跳轉(zhuǎn)地址暫時(shí)未知*/codecjpc.a=cx;/*回填jpc跳轉(zhuǎn)地址*/printf("%dn",codecjpc.a);while(sym=semicolon);if(sym!=endcasesym) error(36);/*結(jié)束符號(hào)因該為endcase*/*回填各個(gè)情況處理中的jmp語(yǔ)句的跳轉(zhuǎn)地址*/for(jjj=0;jjj<casenum;jjj+)codecxjmpa

16、drjjj.a=cx;getsymdo;5. 相關(guān)代碼的修改說(shuō)明:修改部分為紅色加粗字體1).h中文件的修改:/* 關(guān)鍵字個(gè)數(shù) */#define norw 17/* 符號(hào) */enum symbolnul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,colon,period,becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,constsym

17、,varsym,procsym,forsym,casesym,endcasesym;#define symnum 362)初始化函數(shù) init()中的修改:/* 設(shè)置保留字名字 */strcpy(&(word00),"begin");strcpy(&(word10),"call");strcpy(&(word20),"case");strcpy(&(word30),"const");strcpy(&(word40),"do");strcpy(&(w

18、ord50),"end");strcpy(&(word60),"endcase");strcpy(&(word70),"for");strcpy(&(word80),"if");strcpy(&(word90),"odd");strcpy(&(word100),"procedure");strcpy(&(word110),"read");strcpy(&(word120),"then&quo

19、t;);strcpy(&(word130),"var");strcpy(&(word140),"while");strcpy(&(word150),"write");/* 設(shè)置保留字符號(hào) */wsym0=beginsym;wsym1=callsym;wsym2=casesym;wsym3=constsym;wsym4=dosym;wsym5=endsym;wsym6=endcasesym;wsym7=forsym;wsym8=ifsym;wsym9=oddsym;wsym10=procsym;wsym11=readsym;wsym12=thensym;wsym13=varsym;wsym14=whilesym;wsym15=writesym;3) 新增錯(cuò)誤編號(hào)及含義: 33 read語(yǔ)句缺少右括號(hào) 34 read語(yǔ)句缺少左括號(hào) 35 read()中的標(biāo)識(shí)符應(yīng)為聲明過(guò)的變量 36 case中丟了endcase 37 case語(yǔ)句體開(kāi)頭應(yīng)為標(biāo)識(shí)符 38 case后的標(biāo)識(shí)符應(yīng)為變量 39 case變量后應(yīng)為冒號(hào) 40 case語(yǔ)句體開(kāi)頭因?yàn)槌A? 測(cè)試數(shù)據(jù)及結(jié)果:測(cè)試用例一1.測(cè)試代碼:文件名:success.txt代碼:const a=1,c=2,d=3;var b,i,k;begin read(

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論