版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、課 程 設(shè) 計 課程名稱_編譯原理_ _題目名稱_PL/0編譯器的擴(kuò)充 _學(xué)生學(xué)院_計算機(jī)學(xué)院_ _專業(yè)班級_ 計算機(jī)科學(xué)與技術(shù)13(9)學(xué) 號 學(xué)生姓名 指導(dǎo)教師_林志毅_2016 年 1 月 2 日一、 已完成的內(nèi)容:(1) 擴(kuò)充賦值運(yùn)算:*= 和 /=(2) 擴(kuò)充語句(Pascal的FOR語句)FOR :=STEP UNTILDo(3) 增加類型: 字符類型; 實數(shù)類型。(4) 增加注釋; 多行注釋由/*和*/包含,單行注釋為/ 二、 實驗環(huán)境與工具(1)計算機(jī)及操作系統(tǒng):PC機(jī),Windows7(2)程序設(shè)計語言:C+(3)使用軟件Borland C+ Builder 6.0(4)教學(xué)
2、型編譯程序:PL/0三、 具體實現(xiàn):1. 擴(kuò)充賦值運(yùn)算:*= 和 /=(1) 語法樹表達(dá)式*=(/=,-=,+=)變量(2) 修改GetSym()方法(寫出修改的代碼) else if(CH=*) GetCh(); if(CH=) SYM=TIMESBECOMES; GetCh(); else SYM=TIMES; else if(CH=/) GetCh(); if(CH=) SYM=SLASHBECOMES; GetCh(); (3) 修改STATEMENT()方法(寫出修改的代碼)case IDENT:i=POSITION(ID,TX);if (i=0) Error(11);else if
3、 (TABLEi.KIND=VARIABLE | TABLEi.KIND=FLOATTYPE) /*ASSIGNMENT TO NON-VARIABLE*/ GetSym(); if (SYM=BECOMES| SYM=TIMESBECOMES | SYM=SLASHBECOMES|SYM=PLUSBECOMES|SYM=MINUSBECOMES) RELOP=SYM; if(SYM!=BECOMES) /若為除等于(或其他類似符號)則先把符號左邊的變量值放入棧中 GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GetSym(); else Error(
4、13); EXPRESSION(FSYS,LEV,TX); if(RELOP=TIMESBECOMES) GEN(OPR,0,4); else if(RELOP=SLASHBECOMES) GEN(OPR,0,5); else if(RELOP=PLUSBECOMES) GEN(OPR,0,2); else if(RELOP=MINUSBECOMES) GEN(OPR,0,3); GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); (4) 運(yùn)行測試(測試的PL0源碼擴(kuò)充單詞的測試并貼運(yùn)行結(jié)果截圖)PL0源碼:PROGRAM EX01;VAR A,B,C,D;
5、BEGIN A:=16; A/=2; WRITE(A); /結(jié)果為8 B:=4; B*=2; WRITE(B); /結(jié)果為8 C:=6; C+=2; WRITE(C); /結(jié)果為8 D:=10; D-=2; WRITE(D); /結(jié)果為8END.(5) 運(yùn)行結(jié)果:(6) 出現(xiàn)的問題及解決開始時在實現(xiàn)/=和*=操作時,*=的實現(xiàn)很順利,而/=卻一直沒有得到理想的結(jié)果,通過與同學(xué)的討論得知代碼中除號指令的解析中,其實為除余操作,于是將%改為/,但是結(jié)果還是錯誤,經(jīng)過調(diào)試發(fā)現(xiàn)是兩個相除的數(shù)在棧中的位置相反了,正確的狀態(tài)應(yīng)該是除數(shù)位于次棧頂,而被除數(shù)位于棧頂。解決:在調(diào)用EXPRESSION函數(shù)解析/
6、=右邊表達(dá)式前,先將其左邊變量的值放入棧中。2. 擴(kuò)充語句(Pascal的FOR語句)FOR :=STEP UNTILDo(1) 語法圖(2) 修改GetSym()方法(寫出修改的代碼)此處無修改,F(xiàn)OR、STEP、UNTIL及DO等關(guān)鍵字已放置關(guān)鍵字?jǐn)?shù)組中,通過該數(shù)組便可識別。(3) 修改STATEMENT()方法(寫出修改的代碼)case FORSYM: GetSym(); STATEMENT(SymSetUnion(SymSetNew(STEPSYM),FSYS),LEV,TX); /處理for后面的賦值語句 CX3=CX; GEN(JMP,0,0); /用于第一次執(zhí)行for語句時跳過s
7、tep語句 CX1=CX; /記錄step后語句的代碼位置 if(SYM=STEPSYM) GetSym(); STATEMENT(SymSetUnion(SymSetNew(UNTILSYM),FSYS),LEV,TX); /處理step后面的表達(dá)式 else Error(8); if(SYM=UNTILSYM) CODECX3.A=CX; /回填第一次進(jìn)入for循環(huán)時的直接跳轉(zhuǎn)地址 GetSym(); else Error(8); CONDITION(SymSetAdd(DOSYM, FSYS),LEV,TX); /處理條件語句 if(SYM=DOSYM) GetSym(); else E
8、rror(8); CX2=CX; GEN(JPC,0,0); /條件跳轉(zhuǎn),棧頂若為非真,則跳轉(zhuǎn)到參數(shù)三位置,該位置待回填 STATEMENT(FSYS,LEV,TX); /處理do后面內(nèi)容 GEN(JMP,0,CX1); /執(zhí)行完for語句內(nèi)的語句則重新跳回step處 CODECX2.A=CX; /回填條件跳轉(zhuǎn) break;(4) 運(yùn)行測試PL0源碼:PROGRAM EX01;VAR A,SUM;BEGIN SUM:=0; FOR A:=1 STEP A+=1 UNTIL A=0 & CH=0 & CH=0 & CH=9) /以下獲取小數(shù)點(diǎn)后的值 J=0; M=(CH-0)*0.1; whil
9、e(JLMAX) Error(30); /LMAX為小數(shù)點(diǎn)后數(shù)字最大度 fprintf(FOUT,%f, NUM); (2) 修改Block中的方法運(yùn)行測試if (SYM=CHARSYM) GetSym(); do CharDeclaration(LEV,TX,DX); while (SYM=COMMA) GetSym(); CharDeclaration(LEV,TX,DX); if (SYM=SEMICOLON) GetSym(); else Error(5); while(SYM=IDENT);if (SYM=FLOATSYM) GetSym(); do FloatDeclaration
10、(LEV,TX,DX); while (SYM=COMMA) GetSym(); DoubleDeclaration(LEV,TX,DX); if (SYM=SEMICOLON) GetSym(); else Error(5); while(SYM=IDENT); (3) 修改STATEMENT中的方法case IDENT: GetSym();i=POSITION(ID,TX);if (i=0) Error(11);else if (TABLEi.KIND=CHARTYPE | TABLEi.KIND=VARIABLE | TABLEi.KIND=FLOATTYPE) /*ASSIGNMENT
11、 TO NON-VARIABLE*/if (SYM=BECOMES | SYM=TIMESBECOMES | SYM=SLASHBECOMES | SYM=PLUSBECOMES| SYM=MINUSBECOMES) RELOP=SYM; if(SYM!=BECOMES) /若為除等于(或其他類似)。則先把符號左邊的變量值放入棧中 GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GetSym(); else Error(13); EXPRESSION(FSYS,LEV,TX); if(RELOP=TIMESBECOMES) GEN(OPR,0,4); e
12、lse if(RELOP=SLASHBECOMES) GEN(OPR,0,5); else if(RELOP=PLUSBECOMES) GEN(OPR,0,2); else if(RELOP=MINUSBECOMES) GEN(OPR,0,3); GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); else Error(12); i=0; break;case WRITESYM:/根據(jù)不同類型進(jìn)行相應(yīng)輸出GetSym();if (SYM=LPAREN) do GetSym();EXPRESSION(SymSetUnion(SymSetNew(RPAREN,C
13、OMMA),FSYS),LEV,TX); i=POSITION(ID,TX); switch (TABLEi.KIND) case CHARTYPE:GEN(OPR,0,17); break; case FLOATTYPE:GEN(OPR,0,18); break; default:GEN(OPR,0,14); while(SYM=COMMA); if (SYM!=RPAREN) Error(SBNUM); else GetSym();GEN(OPR,0,15);break; /*WRITESYM*/(4) 修改FACTOR中的方法(包含字符的識別處理)while (SymIn(SYM,FAC
14、BEGSYS) if (SYM=IDENT) i=POSITION(ID,TX); if (i=0) Error(11); elseswitch (TABLEi.KIND) case CONSTANT: GEN(LIT,0,TABLEi.VAL); break; case VARIABLE: GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); break; case PROCEDUR: Error(21); break; case FLOATTYPE: GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); break; ca
15、se CHARTYPE: GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); break; GetSym(); else if (SYM=NUMBER) if (NUMAMAX) Error(31); NUM=0; GEN(LIT,0,NUM); GetSym(); /將表達(dá)式中的數(shù)字置于棧頂 else if (SYM=LPAREN) /左 括 號 GetSym(); EXPRESSION(SymSetAdd(RPAREN,FSYS),LEV,TX);if (SYM=RPAREN) GetSym();else Error(22); else if (SYM=
16、CHARACTER) GEN(LIT,0,NUM); /將字符放入棧頂 GetSym(); (5) 修改ENTER中的方法case CHARTYPE: TABLETX.vp.LEVEL=LEV; TABLETX.vp.ADR=DX; DX+; break; case FLOATTYPE: TABLETX.vp.LEVEL=LEV; TABLETX.vp.ADR=DX; DX+; break;(6) 在Interpret指令OPR中增加字符輸出和實數(shù)輸出case 17: Form1-printcs(ST); fprintf(FOUT,%cn,ST); T-; /增加字符輸出 break;case
17、 18: Form1-printrs(,ST); fprintf(FOUT,%dn,ST); T-; /增加實數(shù)型輸出 break;(7) 其它修改1) 增加相應(yīng)的關(guān)鍵字char和float;2) 由于增加實型,因此將模擬棧的數(shù)組類型改為double型;另目標(biāo)指令結(jié)構(gòu)體INSTRUCTION中的A,及全局變量NUM也改為double型(8) 運(yùn)行測試:PL0源碼:PROGRAM EX01;CHAR A,B;FLOAT C,D,SUM;BEGIN A:=A; B:=B+2; WRITE(A); WRITE(B); WRITE(B+2); C:=123.321; D:=321.123; SUM:=
18、C+D+0.0004; WRITE(SUM); END.(9) 運(yùn)行結(jié)果:(10) 出現(xiàn)的問題及解決字符型的實現(xiàn)主要問題是在賦值、字符表達(dá)式的處理及輸出三個方面。賦值剛開始沒有思路,之后借鑒VAR型的賦值,才清楚需要使用到棧這個媒介進(jìn)入賦值:先把字符值放入棧中,在將棧頂值傳給字符型變量。而字符表達(dá)式的處理在Factor里進(jìn)行識別處理。關(guān)于輸出則需要在WRITESYM的識別處理中進(jìn)行類型判斷采取不同輸出方式,并需新建一條指令專門用于字符輸出實數(shù)型的實現(xiàn)主要問題為:1、數(shù)據(jù)獲取:小數(shù)點(diǎn)后的值的獲取需要用到循環(huán)幫助實現(xiàn);2、變量更改:在沒有引入實數(shù)型前,用來模擬棧的數(shù)組類型為int型,而引入后,則需
19、要將其更改為實數(shù)型,在程序中與棧值有關(guān)的那些變量類型也同樣改為實數(shù)型。4. 增加注釋; 多行注釋由/*和*/包含,單行注釋為/ (1) 修改GetSym()方法(寫出修改的代碼)else if(CH=/) GetCh(); if(CH=) SYM=SLASHBECOMES; GetCh(); else if(CH=*) GetCh(); i=CH; while(i!=* | CH!=/) i=CH; GetCh(); / Form1-printcs(CH); if(i!=*&CH!=/) Error(19); else GetCh();/不能忽略,為下一次調(diào)用GetSym提供第一個字符,用于switch語句 GetSym(); else if(CH=/) /單行注釋功能 i=CX;/記錄當(dāng)前行 while(CC!=LL) GetCh(); /CC為當(dāng)前字符在行中位置,LL為當(dāng)前行的字?jǐn)?shù) GetSym(); /濾去注釋后繼續(xù)獲取后面的字符串 else SYM=SLASH; (2) 運(yùn)行測試PL0源碼:PROGRAM EX01;VAR A,SUM;BEGIN /*下面代碼求解1到100的之間 每個整數(shù)的相加之和*/ SUM:=0; FOR A:=1 STEP A+=1 UNTIL A=100 DO /求1100的和SUM+=A; WRITE(SUM); END.(3) 運(yùn)行結(jié)
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 氧化鎢制備工崗前設(shè)備維護(hù)考核試卷含答案
- 白酒發(fā)酵工崗前個人技能考核試卷含答案
- 硝酸銨結(jié)晶造粒工安全防護(hù)模擬考核試卷含答案
- 水平定向鉆機(jī)司機(jī)沖突管理模擬考核試卷含答案
- 2025年上海立信會計金融學(xué)院馬克思主義基本原理概論期末考試模擬題附答案
- 2025年云南外事外語職業(yè)學(xué)院單招職業(yè)技能考試題庫附答案
- 2024年閩北職業(yè)技術(shù)學(xué)院馬克思主義基本原理概論期末考試題附答案
- 2024年社旗縣幼兒園教師招教考試備考題庫附答案
- 2024年鄭州經(jīng)貿(mào)學(xué)院輔導(dǎo)員考試筆試真題匯編附答案
- 2025年《公共基礎(chǔ)知識》考試題庫及答案一套
- 2026年社區(qū)活動組織服務(wù)合同
- 兒童呼吸道感染用藥指導(dǎo)
- 防意外傷害安全班會課件
- 2025年國家基本公共衛(wèi)生服務(wù)考試試題(附答案)
- 2025年醫(yī)院社區(qū)衛(wèi)生服務(wù)中心工作總結(jié)及2026年工作計劃
- 2025-2026學(xué)年北師大版七年級生物上冊知識點(diǎn)清單
- 委托作品協(xié)議書
- 食品加工廠乳制品設(shè)備安裝方案
- 2025至2030中國芳綸纖維行業(yè)發(fā)展分析及市場發(fā)展趨勢分析與未來投資戰(zhàn)略咨詢研究報告
- 尾牙宴活動策劃方案(3篇)
- 魯教版(2024)五四制英語七年級上冊全冊綜合復(fù)習(xí)默寫 (含答案)
評論
0/150
提交評論