廣工編譯原理課程設計報告,廣東工業(yè)大學,編譯原理課設,13級_第1頁
廣工編譯原理課程設計報告,廣東工業(yè)大學,編譯原理課設,13級_第2頁
廣工編譯原理課程設計報告,廣東工業(yè)大學,編譯原理課設,13級_第3頁
廣工編譯原理課程設計報告,廣東工業(yè)大學,編譯原理課設,13級_第4頁
廣工編譯原理課程設計報告,廣東工業(yè)大學,編譯原理課設,13級_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、課程設計報告課程名稱 編譯原理 題目名稱 PL/0編譯器的擴充和修改學生學院 計算機學院 專業(yè)班級 計算機科學與技術13(一)學 號 31130057xx 學生姓名 xxxx 指導教師 張巍 2015 年 12 月 27日實驗目的與要求對PL/0作以下修改擴充:(1)擴充賦值運算:+=,-=, *= 和 /=(2)擴充語句(Pascal的FOR語句): FOR <變量>:=<表達式>STEP<表達式> UNTIL<表達式>Do<語句>選做內容(成績評定范圍擴大到:“優(yōu)”和“良”) 增加 注釋; 注釋由/*和*/包含;一、 實驗環(huán)境與工

2、具1、源語言:PL/0語言,PL/0語言是PASCAL語言的子集,它的編譯程序是一個編譯解析執(zhí)行系統(tǒng),后綴名為.PL0;2、目標語言:生成文件后綴為*.COD的目標代碼3、實現(xiàn)平臺:Borland C+Builder 64、運行平臺:Windows 7同學們如果需要源代碼,和測試文件可以去CSDN網站上搜索出我上傳的文件以作參考。并且在此word附上一些心得給大家。二、 設計方案1、 結構設計說明(1)PL/0 語言編譯器 PL/0語言可看成是PASCAL語言的子集,它的編譯程序是一個編譯解釋執(zhí)行系統(tǒng)。PL/0的目標程序為假想棧式計算機的匯編語言,與具體計算機無關。出錯處理函數(shù)表格管理函數(shù)PL

3、/0 源程序目標代碼生成程序程序目標代碼生成程序程序目標代碼生成程序程序目標代碼生成程序程序目標代碼生成程序程序 (2) PL/0編譯程序的語法分析過程BLOCK是整個編譯過程的核心。這里根據(jù)編譯程序的總體流程圖,來弄清BLOCK過程在整個編譯程序中的作用??偭鞒虉D如下圖所示:PL/0 的編譯程序采用一趟掃描方式,以語法分析程序為核心,詞法分析程序和代碼生成程序都作為一個獨立的過程,當語法分析需要讀單詞時就用詞法分析程序,而當語法分析正確需生成相應的目標代碼時,則調用代碼生成程序。此外,用表格管理程序建立變量,常量和過程標識符的說明與引用之間的信息聯(lián)系。用出錯處理程序對詞法和語法分析遇到的錯誤

4、給出在源程序中出錯的位置和錯誤性質。(3) 各功能模塊描述過程或函數(shù)名簡要功能說明pl0主程序error出錯處理,打印出錯位置和錯誤編碼getsym詞法分析,讀取一個單詞getch漏掉空格,讀取一個字符gen生成目標代碼,并送入目標程序區(qū)test測試當前單詞符號是否合法block分程序分析處理過程enter登錄名字表position(函數(shù))查找標識符在名字表中的位置constdeclaration常量定義處理vardeclaration變量說明處理listode列出目標代碼清單statement語句處理expression表達式處理term項處理factor因子處理condition條件處理i

5、nterpret對目標代碼的解釋執(zhí)行程序base(函數(shù))通過靜態(tài)鏈求出數(shù)據(jù)區(qū)的基地址2、主要成分描述符號表為了組成一條指令,編譯程序必須知道其操作碼及其參數(shù)(數(shù)或地址)。這些值是由編譯程序本身聯(lián)系到相應標識符上去的。這種聯(lián)系是在處理常數(shù)、變量和過程說明完成的。為此,標識符表應包含每一標識符所聯(lián)系的屬性;如果標識符被說明為常數(shù),其屬性值為常數(shù)值;如果標識符被說明成變量,其屬性就是由層次和修正量(偏移量)組成的地址;如果標識符被說明為過程,其屬性就是過程的入口地址及層次。常數(shù)的值由程序正文提供,編譯的任務就是確定存放該值的地址。我們選擇順序分配變量和代碼的方法;每遇到一個變量說明,就將數(shù)據(jù)單元的下

6、標加一(PL/0 機中,每個變量占一個存貯單元)。開始編譯一個過程時,要對數(shù)據(jù)單元的下標dx 賦初值,表示新開辟一個數(shù)據(jù)區(qū)。dx 的初值為3,因為每個數(shù)據(jù)區(qū)包含三個內部變量RA,DL 和SL。 運行時存儲組織和管理對于源程序的每一個過程(包括主程序),在被調用時,首先在數(shù)據(jù)段中開辟三個空間,存放靜態(tài)鏈SL、動態(tài)鏈DL和返回地址RA。靜態(tài)鏈記錄了定義該過程的直接外過程(或主程序)運行時最新數(shù)據(jù)段的基地址。動態(tài)鏈記錄調用該過程前正在運行的過程的數(shù)據(jù)段基址。返回地址記錄了調用該過程時程序運行的斷點位置。對于主程序來說,SL、DL和RA的值均置為0。靜態(tài)鏈的功能是在一個子過程要引用它的直接或間接父過程

7、(這里的父過程是按定義過程時的嵌套情況來定的,而不是按執(zhí)行時的調用順序定的)的變量時,可以通過靜態(tài)鏈,跳過個數(shù)為層差的數(shù)據(jù)段,找到包含要引用的變量所在的數(shù)據(jù)段基址,然后通過偏移地址訪問它。在過程返回時,解釋程序通過返回地址恢復指令指針的值到調用前的地址,通過當前段基址恢復數(shù)據(jù)段分配指針,通過動態(tài)鏈恢復局部段基址指針。實現(xiàn)子過程的返回。對于主程序來說,解釋程序會遇到返回地址為0的情況,這時就認為程序運行結束。解釋程序過程中的base函數(shù)的功能,就是用于沿著靜態(tài)鏈,向前查找相差指定層數(shù)的局部數(shù)據(jù)段基址。這在使用sto、lod、stoArr、lodArr等訪問局部變量的指令中會經常用到。類PCODE

8、代碼解釋執(zhí)行的部分通過循環(huán)和簡單的case判斷不同的指令,做出相應的動作。當遇到主程序中的返回指令時,指令指針會指到0位置,把這樣一個條件作為終至循環(huán)的條件,保證程序運行可以正常的結束。 語法分析方法語法分析子程序采用了自頂向下的遞歸子程序法,語法分析同時也根據(jù)程序的語義生成相應三元代碼,并提供了出錯處理的機制。語法分析主要由分程序分析過程(BLOCK)、參數(shù)變量分析過程(ParaDeclaration)、參數(shù)變量處理過程(ParaGetSub)、數(shù)組處理過程(ParaGetSub)、常量定義分析過程(ConstDeclaration)、變量定義分析過程(Vardeclaration)、語句分

9、析過程(Statement)、表達式處理過程(Expression)、項處理過程(Term)、因子處理過程(Factor)和條件處理過程(Condition)構成。這些過程在結構上構成一個嵌套的層次結構。除此之外,還有出錯報告過程(Error)、代碼生成過程(Gen)、測試單詞合法性及出錯恢復過程(Test)、登錄名字表過程(Enter)、查詢名字表函數(shù)(Position)以及列出類 PCODE代碼過程(Listcode)作過語法分析的輔助過程。 中間代碼表示中間代碼是是源程序的一種內部表示,復雜性介于源語言和目標機語言之間。中間代碼的表示方法有逆波蘭式、三元式、樹形、四元式等。(1) 逆波蘭

10、記號是最簡單的一種中間代碼表示形式,早在編譯程序出現(xiàn)之前,它就用于表示算術表達式。后綴表示法表示表達式,其最大的優(yōu)點是易于棧式計算機處理表達式。(2) 每個三元式由三個部分組成:A. 算符opB. 第一運算對象ARG1C. 第二運算對象ARG2運算對象可能是源程序中的變量,也可能是某個三元式的結果,用三元式的編號表示。(3) 樹形表示是三元式表示的翻版。(4) 四元式是一種比較普遍采用的中間代碼形式:算符op,運算對象ARG1,運算對象ARG2,運算結果RESULT三、 開發(fā)過程和完成情況(一)增加單詞:運算符 *=,/=,+=,-=,F(xiàn)ORSYM,運算符 *= ,/=,+= ,-= 分別對應

11、 TIMESBECOMES, SLASHBECOMES, PLUSBECOMES, MINUSBECOMES。1.1保留字typedef enum NUL, IDENT, NUMBER, PLUS, MINUS, TIMES, SLASH, ODDSYM, EQL, NEQ, LSS, LEQ, GTR, GEQ, LPAREN, RPAREN, COMMA, SEMICOLON, PERIOD, BECOMES, BEGINSYM, ENDSYM, IFSYM, THENSYM, WHILESYM, WRITESYM, READSYM, DOSYM, CALLSYM, CONSTSYM, V

12、ARSYM, PROCSYM, PROGSYM , ELSESYM, FORSYM, STEPSYM, UNTILSYM, RETURNSYM, TIMESBECOMES, SLASHBECOMES, ANDSYM, ORSYM, NOTSYM, PLUSBECOMES, MINUSBECOMES SYMBOL;char *SYMOUT = "NUL", "IDENT", "NUMBER", "PLUS", "MINUS", "TIMES", "SLASH"

13、;, "ODDSYM", "EQL", "NEQ", "LSS", "LEQ", "GTR", "GEQ", "LPAREN", "RPAREN", "COMMA", "SEMICOLON", "PERIOD", "BECOMES", "BEGINSYM", "ENDSYM", "IFSY

14、M", "THENSYM", "WHILESYM", "WRITESYM", "READSYM", "DOSYM", "CALLSYM", "CONSTSYM", "VARSYM", "PROCSYM", "PROGSYM" ,"ELSESYM", "FORSYM","STEPSYM","UNTILSYM",

15、"RETURNSYM", "PLUSBECOMES", "MINUSBECOMES", "TIMESBECOMES", "SLASHBECOMES", "ANDSYM", "ORSYM", "NOTSYM"strcpy(KWORD 1,"BEGIN"); strcpy(KWORD 2,"CALL"); strcpy(KWORD 3,"CONST"); strcpy(KWORD

16、4,"DO"); strcpy(KWORD 5,"ELSE"); strcpy(KWORD 6,"END"); strcpy(KWORD 7,"FOR"); strcpy(KWORD 8,"IF"); strcpy(KWORD 9,"ODD"); strcpy(KWORD10,"PROCEDURE"); strcpy(KWORD11,"PROGRAM"); strcpy(KWORD12,"READ"); strcpy

17、(KWORD13,"RETURN"); strcpy(KWORD14,"STEP"); strcpy(KWORD15,"THEN"); strcpy(KWORD16,"UNTIL"); strcpy(KWORD17,"VAR"); strcpy(KWORD18,"WHILE"); strcpy(KWORD19,"WRITE"); WSYM 1=BEGINSYM; WSYM 2=CALLSYM; WSYM 3=CONSTSYM; WSYM 4=DOSYM;

18、WSYM 5=ELSESYM; WSYM 6=ENDSYM; WSYM 7=FORSYM; WSYM 8=IFSYM; WSYM 9=ODDSYM; WSYM10=PROCSYM; WSYM11=PROGSYM; WSYM12=READSYM; WSYM13=RETURNSYM; WSYM14=STEPSYM; WSYM15=THENSYM; WSYM16=UNTILSYM; WSYM17=VARSYM; WSYM18=WHILESYM; WSYM19=WRITESYM; SSYM'+'=PLUS; SSYM'-'=MINUS; SSYM'*'=

19、TIMES; SSYM'/'=SLASH; SSYM'('=LPAREN; SSYM')'=RPAREN; SSYM'='=EQL; SSYM','=COMMA; SSYM'.'=PERIOD; /SSYM'#'=NEQ; /將'#'替換成"<>"需注釋該語句 SSYM''=SEMICOLON; SSYM'&'=ANDSYM; SSYM'!'=NOTSYM; 1.2運算符 在Get

20、Sym()函數(shù)中在相應位置增加下面所示的語句: else if(CH='*')/實現(xiàn)*= GetCh(); if(CH='=') SYM=TIMESBECOMES;GetCh(); else SYM=TIMES; else if('/'=CH)/實現(xiàn)/= GetCh(); if(CH='=') SYM=SLASHBECOMES;GetCh(); else if(CH='*') i=0; do GetCh(); if(CH='*') i=1; else if(CH='/')if(i=1

21、) i=2; else i=0;while(i!=2); GetCh(); else SYM=SLASH; else if (CH='+') /實現(xiàn)+= GetCh(); if (CH='=') SYM=PLUSBECOMES; GetCh(); else SYM=PLUS; else if (CH='-') /實現(xiàn)-= GetCh(); if (CH='=') SYM=MINUSBECOMES; GetCh(); else SYM=MINUS; else SYM=SSYMCH; GetCh(); 1.2.2在void STATE

22、MENT(SYMSET FSYS,int LEV,int &TX)函數(shù)中增加:case IDENT:i=POSITION(ID,TX);if (i=0) Error(11);else if (TABLEi.KIND!=VARIABLE) /*ASSIGNMENT TO NON-VARIABLE*/Error(12); i=0; GetSym(); SYMBOL TEMP;if (SYM=BECOMES) GetSym(); else if(SYM=TIMESBECOMES|SLASHBECOMES|PLUSBECOMES |MINUSBECOMES) TEMP=SYM; GEN(LOD

23、,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);/取值到棧頂 GetSym(); else Error(13); EXPRESSION(FSYS,LEV,TX); if (TEMP = TIMESBECOMES) GEN(OPR,0,4); else if (TEMP = SLASHBECOMES) GEN(OPR,0,5); else if (TEMP = PLUSBECOMES) GEN(OPR,0,2); else if (TEMP = MINUSBECOMES) GEN(OPR,0,3);if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL

24、,TABLEi.vp.ADR);break;1.3單詞總數(shù)原單詞總數(shù)是33,故所有“i<33” (i實際上是指單詞總數(shù))因為新增加單詞10個,故應改為“i<43”(因為添加+=,-=,*=,/=故為45)。為了方便以后新增加單詞,特加入了常量const WNUM = 45;然后把所有的45替換成了WNUM,以后要增加單詞,就可以直接修改該值,不必再重新把所有的值找出來做替換。2.增加循環(huán)語句的FOR子句,要求:寫出相關文法,語法圖,語義規(guī)則。(1)FOR <變量>:=<表達式> STEP <表達式> UNTIL <表達式> DO &l

25、t;語句>(2)語法圖(3) 代碼修改在void STATEMENT(SYMSET FSYS,int LEV,int &TX)中加入ELSE的實現(xiàn)語句case FORSYM: GetSym(); if (SYM!=IDENT) Error(13);/是否為 變量符號 else i=POSITION(ID,TX); if (i=0) Error(11); else if (TABLEi.KIND!=VARIABLE) /賦值語句中,賦值左部標識符是變量 Error(12); i=0; GetSym(); if(SYM!=BECOMES) Error(13); else GetSym

26、(); /*處理賦值語句右部的表達式*/ EXPRESSION(SymSetUnion(SymSetNew(UNTILSYM,STEPSYM,DOSYM),FSYS),LEV,TX); if(i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /保持初始值 CX1=CX;/如果是賦值語句,跳轉到untilsym執(zhí)行 GEN(JMP,0,0); CX1=CX; /保持循環(huán)開始點 if(SYM!=STEPSYM) Error(19); else GetSym() EXPRESSION(SymSetUnion(SymSetNew(UNTILSYM,ST

27、EPSYM,DOSYM),FSYS),LEV,TX); GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /循環(huán)變量放到棧頂 GEN(OPR,0,2); GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);/將棧頂?shù)闹捣湃胙h(huán)變量 if(SYM!=UNTILSYM) Error(19); else CODECX1-1.A=CX; /如果是賦值語句,跳轉到untilsym執(zhí)行 GetSym() EXPRESSION(SymSetUnion(SymSetNew(UNTILSYM,STEPSYM,DOSYM),FSYS),LEV,TX); GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GEN(OPR,0,12); /次棧頂是否比棧頂小,是,1進棧,否,0進棧 CX2=CX; GEN(JPC,0,0);/ 棧頂布爾值非0則轉移 if(SYM=DOSYM) GetSym(); STATEMENT(FSYS,LEV,TX); GEN(JMP,0,CX1);/跳回step CODECX2.A=CX; else Error(19); /跳出for循環(huán) br

溫馨提示

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

評論

0/150

提交評論