PLO語言功能擴展_第1頁
PLO語言功能擴展_第2頁
PLO語言功能擴展_第3頁
PLO語言功能擴展_第4頁
PLO語言功能擴展_第5頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、編譯原理實驗報告一實驗目的:熟練掌握PLO語言編譯程序的結構和功能;二實驗要求:擴充PLO語言的功能,增加for語句和case語句;已知for語句和case語句的語法如下:for語句:二for(賦值語句;關系表達式)do語句關系表達式 := 表達式關系運算符表達式case 語句:二case標識符:常量:語句endcase .三.實驗環(huán)境與工具:計算機及操作系統(tǒng):WindowsXP程序設計語言:C編譯程序:PL/0實現(xiàn)工具(平臺):VC+6.0四設計方案:概述:源語言:pl0目標語言:類pcode代碼實現(xiàn)工具(平臺):VC+6.0結構設計說明:PlO所有子程序如下:過程或函數(shù)名簡要功能說明mai

2、n初始化編譯環(huán)境,建立關鍵字表,調用分程序Block對源文件進行編譯, 當編譯正確時,自動調用解釋執(zhí)行程序,對目標代碼進行解釋執(zhí)行。error出錯處理,打印出錯位置和錯誤性質編號。并在信息欄輸出錯誤信息。get ch過濾空格,讀取一個字符getsym詞法分析,讀取一個單詞gen生成目標代碼(類pcode代碼),并送入目標程序區(qū)。test測試當前單詞是否是合法block分程序分析處理過程。enter登錄過程說明對象包括變量、常量和過程名的屬性信息到符號表。position查找標識符在符號表中的位置。constdeclaration常量定義處理,收集常量信息并登錄到符號表。vardeclarati

3、on變量定義處理,收集變量信息并登錄到符號表。listcode列出目標代碼清單。statement語法分析,語句部分處理。expression表達式分析處理。term項分析處理過程。factor因子分析處理。condition條件處理。interpret對目標代碼進行解析執(zhí)行。Base通過靜態(tài)鏈求數(shù)據(jù)區(qū)首地址。增加for語句:(1)設計思想:For語句的語法分析::二for(賦值語句;關系表達式)do語句設計思路:主要分為兩部分模塊:一,for和;之間的賦值語句處理;二,條件語句處理和最后的語句處 理。首先獲取賦值號左邊的標識符,從符號表中找到它的信息,并確認這個標識符確為變量名。 然后通過調

4、用表達式處理過程算得賦值號右部的表達式的值并生成相應的指令保證這個值放在運 行期的數(shù)據(jù)棧頂。最后通過前面查到的左部變量的位置信息,生成相應的STO指令,把棧頂值存入 指定的變量的空間,實現(xiàn)了賦值操作。返回函數(shù)值也是用賦值語句進行返回值的儲存。首先調用cond it ion函數(shù)處理條件語句,并且把當前condi tion處理生成的判斷條件操作代 碼的的地址cx保存到cxl。每個循環(huán)體中,在循環(huán)體結束前,設置跳回判斷操作判斷當前條件是否 跳出循環(huán)。都把本循環(huán)體結束的下一個位置保存到cx2生成跳轉,并在循環(huán)結束時用cx2更新為目 前循環(huán)結束跳轉地址。難點分析:本模塊,主要難點是處理循環(huán)體的跳轉,解決

5、方法參照上點。不過可以參照if語 句和while語句。(2)擴充代碼:在頭文件plO.h中的符號symbol中增加所要求增加的符號,用加粗傾斜紅色字體標出:源代碼:if(sym=forsym) /*準備按照for語句處理*/getsymdo;if(sym=ident) /*按照賦值語句處理*/i=pos tio n(id,*p tx); if(i=0)error(11); /* 變量未找到 */ elseif(t ablei.kind!二variable)error(12); /* for語句格式錯誤或者賦值語句格式錯誤*/ i=0; getsymdo;if(sym=becomes)getsy

6、mdo;else error(13); /*檢測賦值符號*/ memcpy(nx tl ev,fsys,sizeof(bool)*symnum); expressiondo(nxtlev,ptx,lev); /*處理賦值符號右側表達式*/ if(i!=0)gendo(sto,lev-tablei.level, tablei.adr); /* expression 將執(zhí)行一系列指令,但最終 結果將會保存在棧頂,執(zhí)行sto命令完成賦值*/else error(17);cx1=cx; /*保存判斷條件操作的位置*/getsymdo;memcpy(nx tl ev,fsys,sizeof(bool)*

7、symnum);nxtlevdosym二true; /* 后跟符號為 do */conditiondo(nxtlev,ptx,lev); /* 調用條件處理 */cx2=cx; /*保存循環(huán)體的結束的下一個位置*/ gendo(jpc,0,0); /*生成條件跳轉,但跳出循環(huán)的地址未知*/ if(sym=dosym)getsymdo;else error(18); /* 缺少 do */stat emen tdo(fsys,p tx,lev); /* 循環(huán)體 */ gendo(jmp,0,cxl); /*回頭重新判斷條件*/ codecx2.a=cx; /*反填跳出循環(huán)的地址,與if類似*/

8、增加case語句:(1)設計思想:Case語句的語法分析:case語句:二case標識符:常量:語句endcase設計思路:按照上述語法分析圖,先寫出格式判斷,建立語句處理的框架。再細致寫出偽代碼的生成核 心部分。(以下分析中提及的“循環(huán)體”是指上面語法分析圖的循環(huán)結構)依照語法要求寫出語法分析的框架,大致如上分析圖。首先,將變量的位置存到blpst,供后面生成變量與常量比較指令用。用casenum記下case 含有的情況個數(shù)。每個循環(huán)體開始,取得常量之后,生成三條指令lod (將變量壓到棧頂)、lit (將 常量押到棧頂)、opr 0 8 (兩者作比較)。在生成后面語句的代碼之前,生成jpc

9、利用變量和常量 比較所得結果進行跳轉,若為假,則跳到本循環(huán)體結束的地方。接著,對循環(huán)體內語句進行處理。 生成無條件跳轉指令跳轉到case語句結束,由于地址未知,要等先把各個循環(huán)體中的無條件跳轉 指令的地址放到cxjmpadr數(shù)組中,待case結束后再回填跳轉地址。最后,回填本循環(huán)體頭的條件 跳轉地址。難點分析:1處理常量與變量的比較。一開始以為應該跟if語句類似,處理常量與變量的比 較的時候發(fā)現(xiàn)這一點跟if語句壓根不同,而且要難得多。不過,后來認識到變量的本質,從生成 的匯編代碼的角度出發(fā),利用生成三條指令lod (將變量壓到棧頂)、lit (將常量押到棧頂)、opr0 8 (兩者作比較)解決

10、了這個問題。2循環(huán)體的跳轉問題,比較復雜。簡單來說,三點跳轉的關鍵 點:一,循環(huán)體頭的判斷跳轉;二,循環(huán)倒數(shù)第二個操作,跳出case語句操作;三,最后的回填 條件跳轉操作。(2)擴充代碼: 在頭文件plO.h中的符號symbol中增加所要求增加的符號,用加粗傾斜紅色字體標出:源代碼:if(sym=casesym) /*case 語句*/getsymdo;if(sym!=ident)error(14);/* case后應為標識符*/elseint blpst=i=postion(id, *ptx);/*將變量的 position 保存在 blpst 中*/ if(i=0)error(ll);/*

11、標識符未找到*/elseif(t ablei.kind!二variable)error(38);/* case后的標識符應該為變量*/getsymdo;if(sym!=colon)error(39);/*應該為冒號*/elseint casenum=0;/*casenum 記錄情況個數(shù) */int cxjmpadr50;/*cxjmpadr用于存儲各 種情況中轉移指令的地址*/int cxb=cx;/*cxb存儲case語句開始的指令地址*/int cjpc;/*當前情況處理完常量標號后的跳轉指令地址*/ int varpst=i;/*存放 case 后面變量的 position*/ int

12、conpst;/*存放當前處理情況的常量標號的position*/ int jjj;for(jjj=0;jjj50;jjj+)cxjmpadrjjj=0;dogetsymdo;if(sym!二iden t)/*是否為標識符*/error(37);/*case語句體中,冒號前面應該為標識符*/elseconpst=i=postion(id, *ptx);if(i=0)error(ll);/*標識符未找到*/elseif(t ablei.kind!=cons tant)error(40);/*標識符應該為常量*/getsymdo;if(sym!二colon)error(39);/*應該為冒號*/m

13、emcpy(nxtlev, fsys, sizeof(bool)*symnum);nxtlevsemicolon二true;nxtlevcolon二true;nxtlevendcasesym二true;/* 后跟符號為分號或 end */getsymdo;變量放到棧頂*/常量放到棧頂*/否為假放到次棧頂*/gendo(lod,lev-tableblpst. level,tableblpst .adr);/*將 case 后 gendo(lit, lev-tableconpst. level,tableconpst. val);/*將 當 前 變量放到棧頂*/常量放到棧頂*/否為假放到次棧頂*/

14、gendo(jpc,0,0);/*設置條件跳轉,地址暫時未知*/statementdo(nxtlev, ptx, lev);cxjmpadrcasenum+二ex;/*記住當前情況的jmp語句代碼地址*/gendo(jmp,0,0);/*設置跳出case語句,跳轉地址暫時未知*/codecjpc.a=cx;/*回填 jpc 跳轉地址*/pri ntf (%dn,codecjpc.a);while(sym=semicolon);if(sym!二endcasesym)error(36);/*結束符號因該為endcase*/*回填各個情況處理中的jmp語句的跳轉地址*/ for(jjj=0;jjjc

15、asenum;jjj+)codecxjmpadrjjj.a=cx;getsymdo;5.相關代碼的修改說明:修改部分為紅色加粗字體.h中文件的修改:/*關鍵字個數(shù)*/#define norw 17/*符號*/enum symbolnul,ide nt,n umber,plus,minus ,ti mes,slash,oddsym,eql,neq,lss,leq, gt r,geq,lparen,rparen,comma,semicolon,colon,period,becomes,beginsym, endsym,ifsym ,t hensym,whilesym,wri tesym,reads

16、ym,dosym,callsym,cons tsym,varsym,procsym, forsym,casesym,endcasesym;#define symnum 36初始化函數(shù)init()中的修改:/*設置保留字名字*/st rcpy (&(word00),begin);st rcpy( &(wordl0),call);st rcpy( &(word20),case);st rcpy (&(word30),cons t);st rcpy( &(word40),do);st rcpy (&(word50),end);st rcpy( &(word60),endcase);st rcpy(

17、&(word70),for);st rcpy (&(word80),if);st rcpy( &(word90),odd);st rcpy (&(word100),procedure);st rcpy (&(wordll0),read);st rcpy( &(word120), then);st rcpy (&(word130),var);st rcpy (&(word140),while);st rcpy (&(word150),wr it e); /*設置保留字符號*/ wsym0=beginsym; wsym1=callsym;wsym2=casesym;wsym3=constsym;

18、wsym4=dosym; wsym5=endsym; wsym6=endcasesym; wsym7=forsym; wsym8=ifsym; wsym9=oddsym; wsym10=procsym; wsym11=readsym; wsym12二thensym; wsym13=varsym; wsym14=whilesym; wsym15=writesym;新增錯誤編號及含義:read語句缺少右括號read語句缺少左括號read ()中的標識符應為聲明過的變量case 中丟了 endcasecase語句體開頭應為標識符case后的標識符應為變量case變量后應為冒號case語句體開頭因為常

19、量五測試數(shù)據(jù)及結果:測試用例一1.測試代碼:文件名:success .txt代碼:cons t a=l,c=2,d=3;var b,i,k;beginread(k);b:=0;for i:=0;i=k dobeginb:=b+i;i:=i+l;end;writ e(b);read(i);case i:a:b:=11;c:b:=22;d:b:=33endcase;writ e(b)end.2測試說明:首先輸入源文件文件全名success. txt。在輸入一個整數(shù)x,函數(shù)將輸出x從0到x的所有整數(shù)和。接著,輸入1或者2或者3,將相應輸出11、22、33。本測試用例中既含有for語句,有含有case

20、語句,同時測試了兩種語句的功能。3.運行截圖:21既含有for語句,有含有case語句,同時測試了兩種語句的功能。3.運行截圖:21write;24read;26case i:S6a:S6b:=11 ;3333c :33b:=22;4040d:40b:=3345endcase ;4747 0 6opr 0 16sto 0 534lit0235opr0836JPC04037lit02238sto0339jmp04740lod0441lit0342opr0843JPC04744lit03345sto03Jup 0 47lod 0 3opr 0 14opr 0 15opr 0 0start pl0?1005050?333Press ani/ key to cont inue測試用例二1.測試代碼:文件名: error .txt代碼:cons t a=10,c=l,d=2;var b,i,k;beginread(k);b:=0;for i:=0;ikbeginb:=b+i;i:=i+1end;writ e(b ;b:=1;case a:a:b:=a;c:b:=c+a;b:b:=aendcase;writ e(b)e

溫馨提示

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

評論

0/150

提交評論