2014廣工編譯原理實驗報告_第1頁
2014廣工編譯原理實驗報告_第2頁
2014廣工編譯原理實驗報告_第3頁
2014廣工編譯原理實驗報告_第4頁
2014廣工編譯原理實驗報告_第5頁
已閱讀5頁,還剩9頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、實 驗 報 告 課程名稱 編譯原理 題目名稱 PL/0編譯器的擴充 學(xué)生學(xué)院 計算機學(xué)院 專業(yè)班級 計算機科學(xué)與技術(shù)12(4)學(xué) 號 學(xué)生姓名 柏石先 指導(dǎo)教師 李楊 程序功能完成情況測試用例全面程度學(xué)生對所編程序熟悉程度報告格式是否與要求相符報告內(nèi)容是否準確、全面2014 年 12 月 20日一、 實驗?zāi)康呐c要求對PL/0作以下修改擴充:(1) 增加單詞:保留字 ELSE,F(xiàn)OR,STEP,UNTIL,DO,RETURN運算符 *=,/=,&,|,!(2)修改單詞:不等號# 改為 (3)增加條件語句的ELSE子句,要求:寫出相關(guān)文法,語法描述圖,語義描述圖。二、 實驗環(huán)境與工具1、源語言:P

2、L/0語言,PL/0語言是PASCAL語言的子集,它的編譯程序是一個編譯解析執(zhí)行系統(tǒng),后綴名為.PL0;2、目標語言:生成文件后綴為*.COD的目標代碼3、實現(xiàn)平臺:Borland C+Builder 64、運行平臺:Windows 8.1三、 設(shè)計方案1、 結(jié)構(gòu)設(shè)計說明(1)PL/0 語言編譯器 PL/0語言可看成是PASCAL語言的子集,它的編譯程序是一個編譯解釋執(zhí)行系統(tǒng)。PL/0的目標程序為假想棧式計算機的匯編語言,與具體計算機無關(guān)。出錯處理函數(shù)表格管理函數(shù)PL/0 源程序目標代碼生成程序程序目標代碼生成程序程序目標代碼生成程序程序目標代碼生成程序程序目標代碼生成程序程序 (2) PL/

3、0編譯程序的語法分析過程BLOCK是整個編譯過程的核心。這里根據(jù)編譯程序的總體流程圖,來弄清BLOCK過程在整個編譯程序中的作用。總流程圖如下圖所示:PL/0 的編譯程序采用一趟掃描方式,以語法分析程序為核心,詞法分析程序和代碼生成程序都作為一個獨立的過程,當語法分析需要讀單詞時就用詞法分析程序,而當語法分析正確需生成相應(yīng)的目標代碼時,則調(diào)用代碼生成程序。此外,用表格管理程序建立變量,常量和過程標識符的說明與引用之間的信息聯(lián)系。用出錯處理程序?qū)υ~法和語法分析遇到的錯誤給出在源程序中出錯的位置和錯誤性質(zhì)。(3) 各功能模塊描述過程或函數(shù)名簡要功能說明pl0主程序error出錯處理,打印出錯位置和

4、錯誤編碼getsym詞法分析,讀取一個單詞getch漏掉空格,讀取一個字符gen生成目標代碼,并送入目標程序區(qū)test測試當前單詞符號是否合法block分程序分析處理過程enter登錄名字表position(函數(shù))查找標識符在名字表中的位置constdeclaration常量定義處理vardeclaration變量說明處理listode列出目標代碼清單statement語句處理expression表達式處理term項處理factor因子處理condition條件處理interpret對目標代碼的解釋執(zhí)行程序base(函數(shù))通過靜態(tài)鏈求出數(shù)據(jù)區(qū)的基地址2、主要成分描述符號表為了組成一條指令,編譯

5、程序必須知道其操作碼及其參數(shù)(數(shù)或地址)。這些值是由編譯程序本身聯(lián)系到相應(yīng)標識符上去的。這種聯(lián)系是在處理常數(shù)、變量和過程說明完成的。為此,標識符表應(yīng)包含每一標識符所聯(lián)系的屬性;如果標識符被說明為常數(shù),其屬性值為常數(shù)值;如果標識符被說明成變量,其屬性就是由層次和修正量(偏移量)組成的地址;如果標識符被說明為過程,其屬性就是過程的入口地址及層次。常數(shù)的值由程序正文提供,編譯的任務(wù)就是確定存放該值的地址。我們選擇順序分配變量和代碼的方法;每遇到一個變量說明,就將數(shù)據(jù)單元的下標加一(PL/0 機中,每個變量占一個存貯單元)。開始編譯一個過程時,要對數(shù)據(jù)單元的下標dx 賦初值,表示新開辟一個數(shù)據(jù)區(qū)。dx

6、 的初值為3,因為每個數(shù)據(jù)區(qū)包含三個內(nèi)部變量RA,DL 和SL。 運行時存儲組織和管理對于源程序的每一個過程(包括主程序),在被調(diào)用時,首先在數(shù)據(jù)段中開辟三個空間,存放靜態(tài)鏈SL、動態(tài)鏈DL和返回地址RA。靜態(tài)鏈記錄了定義該過程的直接外過程(或主程序)運行時最新數(shù)據(jù)段的基地址。動態(tài)鏈記錄調(diào)用該過程前正在運行的過程的數(shù)據(jù)段基址。返回地址記錄了調(diào)用該過程時程序運行的斷點位置。對于主程序來說,SL、DL和RA的值均置為0。靜態(tài)鏈的功能是在一個子過程要引用它的直接或間接父過程(這里的父過程是按定義過程時的嵌套情況來定的,而不是按執(zhí)行時的調(diào)用順序定的)的變量時,可以通過靜態(tài)鏈,跳過個數(shù)為層差的數(shù)據(jù)段,找

7、到包含要引用的變量所在的數(shù)據(jù)段基址,然后通過偏移地址訪問它。在過程返回時,解釋程序通過返回地址恢復(fù)指令指針的值到調(diào)用前的地址,通過當前段基址恢復(fù)數(shù)據(jù)段分配指針,通過動態(tài)鏈恢復(fù)局部段基址指針。實現(xiàn)子過程的返回。對于主程序來說,解釋程序會遇到返回地址為0的情況,這時就認為程序運行結(jié)束。解釋程序過程中的base函數(shù)的功能,就是用于沿著靜態(tài)鏈,向前查找相差指定層數(shù)的局部數(shù)據(jù)段基址。這在使用sto、lod、stoArr、lodArr等訪問局部變量的指令中會經(jīng)常用到。類PCODE代碼解釋執(zhí)行的部分通過循環(huán)和簡單的case判斷不同的指令,做出相應(yīng)的動作。當遇到主程序中的返回指令時,指令指針會指到0位置,把這

8、樣一個條件作為終至循環(huán)的條件,保證程序運行可以正常的結(jié)束。 語法分析方法語法分析子程序采用了自頂向下的遞歸子程序法,語法分析同時也根據(jù)程序的語義生成相應(yīng)三元代碼,并提供了出錯處理的機制。語法分析主要由分程序分析過程(BLOCK)、參數(shù)變量分析過程(ParaDeclaration)、參數(shù)變量處理過程(ParaGetSub)、數(shù)組處理過程(ParaGetSub)、常量定義分析過程(ConstDeclaration)、變量定義分析過程(Vardeclaration)、語句分析過程(Statement)、表達式處理過程(Expression)、項處理過程(Term)、因子處理過程(Factor)和條件

9、處理過程(Condition)構(gòu)成。這些過程在結(jié)構(gòu)上構(gòu)成一個嵌套的層次結(jié)構(gòu)。除此之外,還有出錯報告過程(Error)、代碼生成過程(Gen)、測試單詞合法性及出錯恢復(fù)過程(Test)、登錄名字表過程(Enter)、查詢名字表函數(shù)(Position)以及列出類 PCODE代碼過程(Listcode)作過語法分析的輔助過程。 中間代碼表示中間代碼是是源程序的一種內(nèi)部表示,復(fù)雜性介于源語言和目標機語言之間。中間代碼的表示方法有逆波蘭式、三元式、樹形、四元式等。(1) 逆波蘭記號是最簡單的一種中間代碼表示形式,早在編譯程序出現(xiàn)之前,它就用于表示算術(shù)表達式。后綴表示法表示表達式,其最大的優(yōu)點是易于棧式計

10、算機處理表達式。(2) 每個三元式由三個部分組成:A. 算符opB. 第一運算對象ARG1C. 第二運算對象ARG2運算對象可能是源程序中的變量,也可能是某個三元式的結(jié)果,用三元式的編號表示。(3) 樹形表示是三元式表示的翻版。(4) 四元式是一種比較普遍采用的中間代碼形式:算符op,運算對象ARG1,運算對象ARG2,運算結(jié)果RESULT四、 開發(fā)過程和完成情況(一)增加單詞:保留字 ELSE,F(xiàn)OR,STEP,UNTIL,DO , RETURN運算符 *=,/=,&,|,!新增6個保留字和5個運算符,合計11個單詞。其中保留字ELSE,F(xiàn)OR,STEP,UNTIL,DO, RETURN 分

11、別對應(yīng)ELSESYM,FORSYM, STEPSYM, UNTILSYM,DOSYM,RETURNSYM;運算符 *= ,/= ,& ,| , ! 分別對應(yīng) TIMESBECOMES, SLASHBECOMES, ANDSYM, ORSYM, NOTSYM。注:要求只做詞法分析部分,不做語義分析處理,實驗的結(jié)果只是識別新增的保留字和運算符,并且將其打印顯示出來。1.1保留字typedef enum NUL, IDENT, NUMBER, PLUS, MINUS, TIMES, SLASH, ODDSYM, EQL, NEQ, LSS, LEQ, GTR, GEQ, LPAREN, RPAREN

12、, COMMA, SEMICOLON, PERIOD, BECOMES, BEGINSYM, ENDSYM, IFSYM, THENSYM, WHILESYM, WRITESYM, READSYM, DOSYM, CALLSYM, CONSTSYM, VARSYM, PROCSYM, PROGSYM, ELSESYM, FORSYM, STEPSYM, STEPSYM, RETURNSYM, TIMESBECOMES, SLASHBECOMES, ANDSYM, ORSYM, NOTSYM SYMBOL;char *SYMOUT = NUL, IDENT, NUMBER, PLUS, MINU

13、S, 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, VARSYM, PROCSYM, PROGSYM, ELSESYM, FORSYM, STEPSYM, STEPSYM, RETURNSYM, TIMESBECOMES, SLASHBECOMES, ANDSY

14、M, ORSYM, NOTSYM ;strcpy(KWORD 1,BEGIN); strcpy(KWORD 2,CALL); strcpy(KWORD 3,CONST); strcpy(KWORD 4,DO); strcpy(KWORD 5,ELSE); strcpy(KWORD 6,END); strcpy(KWORD 7,FOR); strcpy(KWORD 8,IF); strcpy(KWORD 9,ODD); strcpy(KWORD 10,PROCEDURE); strcpy(KWORD 11,PROGRAM); strcpy(KWORD12,READ); strcpy(KWORD1

15、3,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; WSYM 5=ELSESYM; /*增加保留字符號elsesym*/ WSYM 6=ENDSYM; WSYM 7=FORSYM; WSYM 8=IFSYM; WSYM 9=ODDSY

16、M; WSYM 10=PROCSYM; WSYM 11=PROGSYM; WSYM12=READSYM; WSYM13=RETURNSYM; WSYM14=STEPSYM; WSYM15=THENSYM; WSYM16=UNTILSYM; WSYM17=VARSYM; WSYM18=WHILESYM; WSYM19=WRITESYM; SSYM+=PLUS; SSYM-=MINUS; SSYM*=TIMES; SSYM/=SLASH; SSYM(=LPAREN; SSYM)=RPAREN; SSYM=EQL; SSYM,=COMMA; SSYM.=PERIOD; SSYM;=SEMICOLON

17、; SSYM&=ANDSYM; SSYM!=NOTSYM;在void STATEMENT(SYMSET FSYS,int LEV,int &TX)函數(shù)中增加:case FORSYM: GetSym(); Form1-printfs(保留字:FORSYM); break;case STEPSYM: GetSym(); Form1-printfs(保留字:STEPSYM); break;case UNTILSYM: GetSym(); Form1-printfs(保留字:UNTILSYM); break;case RETURNSYM: GetSym(); Form1-printfs(保留字:RET

18、URNSYM); break;case DOSYM: GetSym(); Form1-printfs(保留字:DOSYM); break; 1.2運算符1.2.1在GetSym()函數(shù)中在相應(yīng)位置增加下面所示的語句:else if (CH=:) GetCh();if (CH=) SYM=BECOMES; GetCh(); else SYM=NUL; else if(CH = *) GetCh(); if(CH = =) SYM = TIMESBECOMES; GetCh(); else SYM=SSYM*; else if(CH = /) GetCh(); if(CH = =) SYM = S

19、LASHBECOMES; GetCh(); else SYM=SSYM/; else /* THE FOLLOWING TWO CHECK WERE ADDED BECAUSE ASCII DOES NOT HAVE A SINGLE CHARACTER FOR = */ if (CH=) SYM=NEQ; GetCh(); /不等號加 else SYM=LSS;else if (CH=) GetCh(); if (CH=) SYM=GEQ; GetCh(); else SYM=GTR; else if (CH=&) SYM=ANDSYM; GetCh(); else if (CH=|) Ge

20、tCh(); if (CH=|) SYM=ORSYM; GetCh(); else Error(19); else if (CH=!) SYM=NOTSYM; GetCh(); else SYM=SSYMCH; GetCh(); 1.2.2在void STATEMENT(SYMSET FSYS,int LEV,int &TX)函數(shù)中增加:case TIMESBECOMES: GetSym(); Form1-printfs(運算符:*= ); break; case SLASHBECOMES: GetSym(); Form1-printfs(運算符: /= ); break; case ANDS

21、YM: GetSym(); Form1-printfs(運算符:& ); break; case ORSYM: GetSym(); Form1-printfs(運算符:| ); break; case NOTSYM: GetSym(); Form1-printfs(運算符:! ); break;1.3保留字的個數(shù)原保留字個數(shù)是14,故const NORW = 14; /* # OF RESERVED WORDS */因為新增加保留字5個,故應(yīng)改為:const NORW = 19; /* # OF RESERVED WORDS */1.4單詞總數(shù)原單詞總數(shù)是33,故所有“i33” (i實際上是指

22、單詞總數(shù))因為新增加單詞10個,故應(yīng)改為“i43”。為了方便以后新增加單詞,特加入了常量const WNUM = 43;然后把所有的43替換成了WNUM,以后要增加單詞,就可以直接修改該值,不必再重新把所有的值找出來做替換。2.修改單詞:不等號# 改為 (1) 把源代碼中的程序段 SSYM#=NEQ; 刪除或注釋消去。 (2)在GetSym()過程中把分析到的定義為不等號,從“”切入修改。else /* THE FOLLOWING TWO CHECK WERE ADDED BECAUSE ASCII DOES NOT HAVE A SINGLE CHARACTER FOR = */ if (C

23、H=) SYM=NEQ; GetCh(); /更改不等號為“” else SYM=LSS;3.增加條件語句的ELSE子句,要求:寫出相關(guān)文法,語法圖,語義規(guī)則。(1)相關(guān)文法 G(S): Sif S else S | if S | a(2)語法圖(3) 語義規(guī)則產(chǎn)生式語 義 規(guī) 則Sif B then M S1 backpatch(E.truelist, M.quad );S.nextlist:=merge(E.falselist, S1.nextlist) M M.quad := nextquad ; N N.nextlist:=makelist(nextquad);Gen( j , , ,

24、 0 ) Sif B then M1 S1 N else M2 S2 backpatch(E.truelist, M1.quad );backpatch(E.falselist, M2.quad );S.nextlist:=merge(S1.nextlist, N.nextlist, S2.nextlist) (4) 代碼修改在void STATEMENT(SYMSET FSYS,int LEV,int &TX)中加入ELSE的實現(xiàn)語句case IFSYM: GetSym(); /* 條件語句*/CONDITION(SymSetUnion(SymSetNew(THENSYM,DOSYM),FS

25、YS),LEV,TX);if (SYM=THENSYM) GetSym();else Error(16); CX1=CX; GEN(JPC,0,0); STATEMENT(FSYS,LEV,TX); if (SYM=ELSESYM) /* 如果THAN后面跟ELSE,ELSE可有可無,不影響IF語句 */ GetSym(); CX2=CX; GEN(JMP,0,0);/*無條件跳轉(zhuǎn)語句*/ CODECX1.A=CX; /*cx即為else語句的位置,回填之前的JPC語句跳轉(zhuǎn)的語句*/ STATEMENT(FSYS,LEV,TX); /*else中的語句體*/ CODECX2.A=CX; /*執(zhí)行完ELSE中的語句體后的地址,把它回填JMP中的跳轉(zhuǎn)地址*/ else /*如果than語句后面沒有發(fā)現(xiàn)else*/ CODECX1.A=CX; /*執(zhí)行JPC語句

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論