




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、課 程 設(shè) 計 課程名稱 編譯原理 題目名稱 PL/0編譯器的擴充 學(xué)生學(xué)院 計算機學(xué)院 專業(yè)班級 計算機科學(xué)與技術(shù)12(4)學(xué) 號 3112005901 學(xué)生姓名 柏石先 指導(dǎo)教師 李楊 程序功能完成情況測試用例全面程度學(xué)生對所編程序熟悉程度報告格式是否與要求相符報告內(nèi)容是否準確、全面2014 年 12 月 28日一、 實驗?zāi)康呐c要求基本內(nèi)容(成績范圍:“中”、“及格”或“不及格”)(1)擴充賦值運算:*= 和 /=(2)擴充語句(Pascal的FOR語句): FOR :=STEP UNTILDo選做內(nèi)容(成績評定范圍擴大到:“優(yōu)”和“良”)(1)增加類型: 字符類型; 實數(shù)類型。(2)增加
2、 注釋; 注釋由/*和*/包含;(3)擴充函數(shù): 有返回值和返回語句; 有參數(shù)函數(shù)。(4)增加一維數(shù)組類型(可增加指令)。(5)其他典型語言設(shè)施。二、 實驗環(huán)境與工具1、源語言:PL/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編譯系統(tǒng)的結(jié)構(gòu)框架出錯處理函數(shù)表格管理函數(shù)PL/0 源程序目標代碼生成程序程序目標代碼生成程序程序目標代碼生成程序程序目標代碼生成程序
3、程序目標代碼生成程序程序源語言:源語言是基于C語言寫的PL/0編譯程序PL0語言(可 以看成 Pascal語言的子集)目標語言:假想的棧式計算機計算語言,即類指令代碼。指令格式如下:其中f代表功能碼,l表示層次差,a的含意對不同的指令有所區(qū)別。具體的指令功能表:LIT 0 a將常數(shù)值取到棧頂,a為常數(shù)值LOD l a將變量值取到棧頂,a為偏移量,l為層差STO l a將棧頂內(nèi)容送入某變量單元中,a為偏移量,l為層差CAL l a調(diào)用過程,a為過程地址,l為層差I(lǐng)NT 0 a在運行棧中為被調(diào)用的過程開辟a個單元的數(shù)據(jù)區(qū)JMP 0 a無條件跳轉(zhuǎn)至a地址JPC 0 a條件跳轉(zhuǎn),當(dāng)棧頂布爾值非真則跳轉(zhuǎn)
4、至a地址,否則順序執(zhí)行OPR 0 0過程調(diào)用結(jié)束后,返回調(diào)用點并退棧OPR 0 1棧頂元素取反OPR 0 2次棧頂與棧頂相加,退兩個棧元素,結(jié)果值進棧OPR 0 3次棧頂減去棧頂,退兩個棧元素,結(jié)果值進棧OPR 0 4次棧頂乘以棧頂,退兩個棧元素,結(jié)果值進棧OPR 0 5次棧頂除以棧頂,退兩個棧元素,結(jié)果值進棧OPR 0 6棧頂元素的奇偶判斷,結(jié)果值在棧頂OPR 0 7OPR 0 8次棧頂與棧頂是否相等,退兩個棧元素,結(jié)果值進棧OPR 0 9次棧頂與棧頂是否不等,退兩個棧元素,結(jié)果值進棧OPR 0 10次棧頂是否小于棧頂,退兩個棧元素,結(jié)果值進棧OPR 0 11次棧頂是否大于等于棧頂,退兩個棧
5、元素,結(jié)果值進棧OPR 0 12次棧頂是否大于棧頂,退兩個棧元素,結(jié)果值進棧OPR 0 13次棧頂是否小于等于棧頂,退兩個棧元素,結(jié)果值進棧OPR 0 14棧頂值輸出至屏幕OPR 0 15屏幕輸出換行OPR 0 16從命令行讀入一個輸入置于棧頂四、 設(shè)計分析(一) 擴充賦值運算:*= 和 /=需要增加2個運算符*= 和 /=,用下面表格定義的SYM代替運算符*=/=SYM表示TIMESBECOMESSLASHBECOMES*= 和 /=的語法描述圖:(二) 擴充語句(Pascal的FOR語句)因為在Pascal中的FOR語句描述為:FOR := STEP UNTIL DO 所以增加FOR,ST
6、EP,UNTIL,DOFOR語句語法描述圖為:五、 程序設(shè)計1) 增加所需要的保留字和運算符,實現(xiàn)*=和/=,以及FOR語句,應(yīng)該增加TIMESBECOMES,SLASHBECOMES,F(xiàn)OR,STEP,UNTIL,DO。注:因為要求課設(shè)和之前實驗的內(nèi)容合并在一起,所以保留了課程實驗已經(jīng)添加的保留字和運算符,之前的已經(jīng)添加了的不再贅述。具體實現(xiàn)的語句如下所示:typedef enum NUL, IDENT, NUMBER, PLUS, MINUS, TIMES, SLASH, ODDSYM, EQL, NEQ, LSS, LEQ, GTR, GEQ, LPAREN, RPAREN, COMMA
7、, SEMICOLON, PERIOD, BECOMES, BEGINSYM, ENDSYM, IFSYM, THENSYM, WHILESYM, WRITESYM, READSYM, DOSYM, CALLSYM, CONSTSYM, VARSYM, PROCSYM, PROGSYM,ELSESYM, FORSYM,STEPSYM,UNTILSYM,RETURNSYM, TIMESBECOMES,SLASHBECOMES,ANDSYM,ORSYM,NOTSYM SYMBOL;這里需要考慮需要增加保留字的個數(shù),以及如何命名,再將新增的保留字添加對應(yīng)的保留字的集合中。具體實現(xiàn)的語句如下所示:ch
8、ar *SYMOUT = 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, VARSYM, PROCSYM, PROGSYM ,ELSESYM,FORSYM,STEPSYM,UNTILSYM,RETU
9、RNSYM,TIMESBECOMES, SLASHBECOMES, ANDSYM, ORSYM, NOTSYM;2) 將新增的保留字按照字母表升序的方式添加,運算符參照已有的運算符來進行添加,注意好符號與SYM的對應(yīng)。具體實現(xiàn)的語句如下所示:特別注意點:此處一定要考慮到PLO編譯器采用了折半查找算法來進行操作,如果新增的保留字沒有按照既定的升序規(guī)則來插入,會造成在編譯過程中,編譯器無法識別某些保留字。strcpy(KWORD 1,BEGIN); strcpy(KWORD 2,CALL); strcpy(KWORD 3,CONST); strcpy(KWORD 4,DO); strcpy(KWO
10、RD 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(KWORD13,RETURN); strcpy(KWORD14,STEP); strcpy(KWORD15,THEN); strcpy(KWORD16,UNTIL); strcpy(KWORD17,VAR); strcpy(KWORD18,WH
11、ILE); strcpy(KWORD19,WRITE); WSYM 1=BEGINSYM; WSYM 2=CALLSYM; WSYM 3=CONSTSYM; WSYM 4=DOSYM; WSYM 5=ELSESYM; WSYM 6=ENDSYM; WSYM 7=FORSYM; WSYM 8=IFSYM; WSYM 9=ODDSYM; WSYM 10=PROCSYM; WSYM 11=PROGSYM; WSYM12=READSYM; WSYM13=RETURNSYM; WSYM14=STEPSYM; WSYM15=THENSYM; WSYM16=UNTILSYM; WSYM17=VARSYM;
12、WSYM18=WHILESYM; WSYM19=WRITESYM; SSYM+=PLUS; SSYM-=MINUS; SSYM*=TIMES; SSYM/=SLASH; SSYM(=LPAREN; SSYM)=RPAREN; SSYM=EQL; SSYM,=COMMA; SSYM.=PERIOD; SSYM;=SEMICOLON; SSYM&=ANDSYM; SSYM|=ORSYM; SSYM!=NOTSYM;3) 特別需要注意的兩點,這個是很容易被忽略的地方,就是在完成保留字和運算符的增加以后,一定要對PLO編譯器對保留字個數(shù)已經(jīng)單詞總數(shù)定義進行相應(yīng)的修改。保留字總數(shù)比如說在不添加任何保留字
13、的情況下,PL0編譯器的原保留字應(yīng)該是14個,所以在Unit1.CPP中有定義const NORW = 14; /* # OF RESERVED WORDS */而在實驗中因為新增加保留字5個,故此處應(yīng)改為:const NORW = 19; /* # OF RESERVED WORDS */單詞總數(shù)與保留字總數(shù)一樣,我們增加完保留字和運算符以后,要修改單詞總是,比如原單詞總數(shù)是33,因為原編譯器中并未定義一個常量來進行統(tǒng)一管理,所以需要對所有“i33”的地方進行修改。因為實驗中新增加單詞10個,故應(yīng)改為“i43”。如下面代碼所示舉例: SYMSET SymSetUnion(SYMSET S1,
14、 SYMSET S2) SYMSET S=(SYMSET)malloc(sizeof(int)*43); for (int i=0; i43; i+)if (S1i | S2i) Si=1;else Si=0; return S;特別是這個地方也要更改數(shù)目為43,不然會發(fā)生異常信息。 DECLBEGSYS=(int*)malloc(sizeof(int)*43); STATBEGSYS=(int*)malloc(sizeof(int)*43); FACBEGSYS =(int*)malloc(sizeof(int)*43); for(int j=0; j43; j+) DECLBEGSYSj=
15、0; STATBEGSYSj=0; FACBEGSYSj =0; 體會:在這里的細節(jié)導(dǎo)致出現(xiàn)了很多意料不到的問題,很多時候調(diào)試了很久才發(fā)現(xiàn),有些地方漏改了,其實可以考慮設(shè)置一個全局變量,進行統(tǒng)一修改,不過考慮到對編譯器增加全局變量不是很好的一種方式,難免會發(fā)生出現(xiàn)可能的篡改,而且不夠直觀,故只是在原來基礎(chǔ)上做出修改。4) 新增的運算符需要被編譯器識別,必須滿足編譯器做詞法分析時,能夠正確得到對應(yīng)的SYM,因此在GetSym()函數(shù)中在相應(yīng)位置增加相應(yīng)的運算符分析判斷,具體實現(xiàn)如下面所示的語句: else if(CH=*) GetCh(); if(CH=) SYM=TIMESBECOMES; G
16、etCh(); else SYM=TIMES; else if(CH=/) GetCh(); if(CH=)SYM=SLASHBECOMES; GetCh(); else SYM=SLASH;體會:這里是雙字符判斷,需要注意判別的連貫性,處理不同情況下對于的SYM或者報錯方式。5) 完成*=和/=的語法分析以后,需要考慮其語義的實現(xiàn),也就是考慮如何實現(xiàn)語句的處理,這里根據(jù)前面設(shè)計的語法描述圖來進行相應(yīng)的語句分析。依據(jù)語法描述圖,首選找到STATEMENT函數(shù)中IDENT語句體,即case IDENT:語句中加入對*=和/=的語句描述。注意這里有三種情況,要考慮到相互不能影響。表達式的分析采用E
17、XPRESSION(FSYS,LEV,TX);語句就行。從指令功能表可知:OPR,0,4代表次棧頂乘以棧頂,退兩個棧元素,結(jié)果值進棧OPR,0,5代表次棧頂除以棧頂,退兩個棧元素,結(jié)果值進棧一定要注意是次棧頂對棧頂?shù)牟僮?,所以要注意被除?shù)(被乘數(shù))和除數(shù)(乘數(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();if (SYM=BECOMES|TIM
18、ESBECOMES|SLASHBECOMES) OPSYM=SYM; if (SYM=TIMESBECOMES) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /取值到棧頂 else if (SYM=SLASHBECOMES) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /取值到棧頂 GetSym(); else Error(13); EXPRESSION(FSYS,LEV,TX); if (OPSYM = TIMESBECOMES) GEN(OPR,0,4); / OPR,0,4代表次棧頂乘以棧頂,退兩個棧
19、元素,結(jié)果值進棧 else if (OPSYM = SLASHBECOMES) GEN(OPR,0,5); / OPR,0,5代表次棧頂除以棧頂,退兩個棧元素,結(jié)果值進棧 if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); break;體會:這里在調(diào)試過程中發(fā)現(xiàn)了編譯程序中的一個BUG:當(dāng)我測試除等運算時,發(fā)現(xiàn)目標代碼的生成沒有問題,可是結(jié)果變成了取余運算,調(diào)試許久以后,才發(fā)現(xiàn)原來在編譯器源碼中Interpret()函數(shù)的語句中的除運算變成了取余運算。也就造成了OPR 0,5語句本來應(yīng)該是表示除運算指令,變成了取余運算指令。所以把該語句修
20、改為:case 5: T-; ST=ST / ST+1; break;結(jié)果就可以正常輸出。所以面對這種BUG,還好老師提醒一下,才發(fā)現(xiàn)是這個原因。6) 在增加了所有FOR循環(huán)需要的保留字以后,根據(jù)FOR循環(huán)的語法描述進行語義分析。因為在Pascal中的FOR語句描述為:FOR := STEP UNTIL DO 。所以按照這個語義,進行相應(yīng)的語句處理。case FORSYM: GetSym(); if (SYM!=IDENT) Error(13);/是否為 變量符號 else i=POSITION(ID,TX); if (i=0) Error(11); else if (TABLEi.KIND!
21、=VARIABLE) /賦值語句中,賦值左部標識符是變量 Error(12); i=0; GetSym(); if(SYM!=BECOMES) Error(13); else GetSym(); /*處理賦值語句右部的表達式*/ EXPRESSION(SymSetUnion(SymSetNew(UNTILSYM,STEPSYM,DOSYM),FSYS),LEV,TX); if(i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /保持初始值 CX1=CX;/如果是賦值語句,跳轉(zhuǎn)到untilsym執(zhí)行 GEN(JMP,0,0); CX2=CX; /
22、保持循環(huán)開始點 if(SYM!=STEPSYM) Error(19); else GetSym(); EXPRESSION(SymSetUnion(SymSetNew(UNTILSYM,STEPSYM,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)變量 /GetSym(); if(SYM!=UNTILSYM) Error(19); else CODECX1.
23、A=CX; /如果是賦值語句,跳轉(zhuǎn)到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進棧 CX3=CX; GEN(JPC,0,0);/ 棧頂布爾值非0則轉(zhuǎn)移 if(SYM=DOSYM) GetSym(); STATEMENT(FSYS,LEV,TX); GEN(JMP,0,CX2);/跳回step CO
24、DECX3.A=CX; else Error(19); /跳出for循環(huán) break;體會:這里的語句分析的次序應(yīng)該是按照語句出現(xiàn)的先后,而不是語義的先后,不然邏輯很難處理,而且根據(jù)循環(huán)的方式,進行相應(yīng)的跳轉(zhuǎn)回填操作比較多,因為要求是對表達式進行操作,所以EXPRESSION()語句的處理也比較多。六、 測試用例因為這個整合了前面課程實驗和課程設(shè)計的全部內(nèi)容,因此對代碼的檢測也寫了很多的測試用例。下面是相關(guān)說明:七、 運行結(jié)果1. 測試/=運算(結(jié)果截圖,測試用例E05.PL0)運行代碼截圖:結(jié)果輸出截圖:測試*=運算(結(jié)果截圖,測試用例E06.PL0)結(jié)果輸出截圖:15 / 15文檔可自由編輯打印目標代碼生成: 0 JMP 0 1 1 INI 0 7 2 LIT 0 4 3 STO 0 5 4 OPR 0 16 5 STO 0 3 6 OPR 0 16 7 STO 0 4 8 LOD 0 3 9
溫馨提示
- 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)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 氫能裝備施工方案
- 惠州市匯科源科技有限公司電源適配器的生產(chǎn)建設(shè)項目環(huán)評報告表
- 昌江縣公益性公墓及殯儀館建設(shè)工程(一期)項目環(huán)評報告表
- 甘肅巨化新材料有限公司股東全部權(quán)益價值項目資產(chǎn)評估報告
- 玻璃更換施工方案施工方案
- 2024-2025學(xué)年下學(xué)期高一語文第一單元A卷
- 東江大壩隧道施工方案
- 《雷雨》教案-高一下學(xué)期語文統(tǒng)編版
- 2025年中國碑石行業(yè)供需態(tài)勢、市場現(xiàn)狀及發(fā)展前景預(yù)測報告
- 提高女性、老年人及殘疾人就業(yè)率的策略及實施路徑
- 2025年春新人教PEP版英語三年級下冊課件 Unit 1 Part C 第8課時 Reading time
- 固定矯治器粘接的護理流程
- 《疼痛治療》課件
- GB/T 45032-2024智慧城市面向城市治理的知識可信賴評估框架
- 2025年安全員B證理論考試900題及答案
- 《畢業(yè)生就業(yè)協(xié)議書》(空白)原件
- 9.3溶質(zhì)的質(zhì)量分數(shù)(第1課時溶質(zhì)的質(zhì)量分數(shù))+教學(xué)設(shè)計-2024-2025學(xué)年九年級化學(xué)人教版(2024)下冊
- 《胰島素和C肽》課件
- 開題報告:家庭教育投入視角下的中小學(xué)生減負政策效果研究
- 大學(xué)圖書館發(fā)展規(guī)劃
- 【MOOC】跨文化交際-蘇州大學(xué) 中國大學(xué)慕課MOOC答案
評論
0/150
提交評論