




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、編譯原理課程設(shè)計(jì) 題 目 _ _PL0編輯器擴(kuò)充_ _學(xué) 院 計(jì)算機(jī)學(xué)院 專 業(yè) 軟件工程 年級(jí)班別 10級(jí)4班 學(xué) 號(hào) 3110006379 學(xué)生姓名 陳泳鑫 指導(dǎo)教師 楊勁濤 答辯程序設(shè)計(jì)報(bào)告撰寫平時(shí)總成績2013 年 1 月 4 日課程設(shè)計(jì)目的與要求 1、課程設(shè)計(jì)目的:在分析理解一個(gè)教學(xué)型編譯程序(如PL/0)的基礎(chǔ)上,對(duì)其詞法分析程序、語法分析程序和語義處理程序進(jìn)行部分修改擴(kuò)充。達(dá)到進(jìn)一步了解程序編譯過程的基本原理和基本實(shí)現(xiàn)方法的目的。2、課程設(shè)計(jì)要求:基本內(nèi)容(成績范圍:“中”、“及格”或“不及格”)(1)擴(kuò)充賦值運(yùn)算:*= 和 /=擴(kuò)充語句(Pascal的FOR語句):FOR :=
2、 TO DO FOR := DOWNTO DO 其中,語句的循環(huán)變量的步長為2,語句的循環(huán)變量的步長為-2。(3)增加運(yùn)算:+ 和 -。選做內(nèi)容(成績?cè)u(píng)定范圍擴(kuò)大到:“優(yōu)”和“良”)(1)增加類型: 字符類型; 實(shí)數(shù)類型。(2)擴(kuò)充函數(shù): 有返回值和返回語句; 有參數(shù)函數(shù)。(3)增加一維數(shù)組類型(可增加指令)。(4)其他典型語言設(shè)施。二、結(jié)構(gòu)設(shè)計(jì)方案 結(jié)構(gòu)設(shè)計(jì)說明: PL/0的編譯程序以語法分析程序?yàn)楹诵?,詞法分析程序和代碼生成程序都作為一個(gè)獨(dú)立的過程,當(dāng)語法分析需要讀單詞時(shí)就用詞法分析程序,而當(dāng)語法分析正確需生成相應(yīng)的目標(biāo)代碼時(shí),則調(diào)用代碼生成程序。此外,用表格管理程序建立變量,常量和過程標(biāo)
3、識(shí)符的說明與引用之間的信息聯(lián)系。用出錯(cuò)處理程序?qū)υ~法和語法分析遇到的錯(cuò)誤給出在源程序中出錯(cuò)的位置和錯(cuò)誤性質(zhì)。各功能模塊圖示:3. 各功能模塊作用表:1PL0主程序2Error出錯(cuò)處理,打印出錯(cuò)位置和錯(cuò)誤編碼 3GetCh漏掉空格,讀取一個(gè)字符 4GetSym詞法分析,讀取一個(gè)單詞 5Gen生成目標(biāo)代碼,并送入目標(biāo)程序區(qū) 6TEST測(cè)試當(dāng)前單詞符號(hào)是否合法 7ENTER登錄名字表 8POSITION查找標(biāo)識(shí)符在名字表中的位置 9ConstDeclaration常量定義處理10VarDeclaration變量說明處理11ListCode列出目標(biāo)代碼清單12FACTOR因子處理13TERM項(xiàng)處理14
4、EXPRESSION表達(dá)式處理15CONDITION條件處理16STATEMENT語句部分處理17Block分程序分析處理過程18BASE通過靜態(tài)鏈求出數(shù)據(jù)區(qū)的基地址19Interpret對(duì)目標(biāo)代碼的解釋執(zhí)行程序3. 符號(hào)名字表結(jié)構(gòu):struct tablestruct char nameal; /*名字*/ enum object kind; /*類型:const,var,array or procedure*/ int val; /*數(shù)值,僅const使用*/ int level; /*所處層,僅const不使用*/ int adr; /*地址,僅const不使用*/ int size;
5、/*需要分配的數(shù)據(jù)區(qū)空間,僅procedure使用*/;4. 保留關(guān)鍵字枚舉結(jié)構(gòu):enum symbolnul, 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, elsesym, forsym
6、, tosym,downtosym, returnsym, pluseql, minuseql, plusplus,minusminus, ;5.名字表中標(biāo)識(shí)符枚舉類型:enum object constant, /*常量*/ variable, /*變量*/ procedur, /*過程*/;6. 運(yùn)行時(shí)存儲(chǔ)組織和管理對(duì)于源程序的每一個(gè)過程(包括主程序),在被調(diào)用時(shí),首先在數(shù)據(jù)段中開辟三個(gè)空間,存放靜態(tài)鏈SL、動(dòng)態(tài)鏈DL和返回地址RA。靜態(tài)鏈記錄了定義該過程的直接外過程(或主程序)運(yùn)行時(shí)最新數(shù)據(jù)段的基地址。動(dòng)態(tài)鏈記錄調(diào)用該過程前正在運(yùn)行的過程的數(shù)據(jù)段基址。返回地址記錄了調(diào)用該過程時(shí)程序運(yùn)行的
7、斷點(diǎn)位置。對(duì)于主程序來說,SL、DL和RA的值均置為0。靜態(tài)鏈的功能是在一個(gè)子過程要引用它的直接或間接父過程(這里的父過程是按定義過程時(shí)的嵌套情況來定的,而不是按執(zhí)行時(shí)的調(diào)用順序定的)的變量時(shí),可以通過靜態(tài)鏈,跳過個(gè)數(shù)為層差的數(shù)據(jù)段,找到包含要引用的變量所在的數(shù)據(jù)段基址,然后通過偏移地址訪問它。在過程返回時(shí),解釋程序通過返回地址恢復(fù)指令指針的值到調(diào)用前的地址,通過當(dāng)前段基址恢復(fù)數(shù)據(jù)段分配指針,通過動(dòng)態(tài)鏈恢復(fù)局部段基址指針。實(shí)現(xiàn)子過程的返回。對(duì)于主程序來說,解釋程序會(huì)遇到返回地址為0的情況,這時(shí)就認(rèn)為程序運(yùn)行結(jié)束。解釋程序過程中的base函數(shù)的功能,就是用于沿著靜態(tài)鏈,向前查找相差指定層數(shù)的局部
8、數(shù)據(jù)段基址。這在使用sto、lod、stoArr、lodArr等訪問局部變量的指令中會(huì)經(jīng)常用到。類PCODE代碼解釋執(zhí)行的部分通過循環(huán)和簡單的case判斷不同的指令,做出相應(yīng)的動(dòng)作。當(dāng)遇到主程序中的返回指令時(shí),指令指針會(huì)指到0位置,把這樣一個(gè)條件作為終至循環(huán)的條件,保證程序運(yùn)行可以正常的結(jié)束。7. 擴(kuò)充賦值運(yùn)算:+= 和 -= 設(shè)計(jì):對(duì)于+=、-=、*=和/=賦值運(yùn)算符,在程序中出現(xiàn)的情況只有如下一種,文法的EBNF 表示為:賦值語句:= += | -= (1)擴(kuò)充的語法描述見結(jié)構(gòu)設(shè)計(jì)中的 PL/0 分程序和主要語句的語法描述中的描述圖;(2)分析區(qū)別賦值運(yùn)算符采用:讀標(biāo)識(shí)符后再讀一個(gè)字符,后
9、根據(jù)讀到的字符轉(zhuǎn)去不同的賦值語句執(zhí)行。(3)中間代碼生成情況:+=運(yùn)算符,其他賦值運(yùn)算符架構(gòu)是一樣的,只是執(zhí)行加法改為相應(yīng)的算數(shù)運(yùn)算。讀到+=運(yùn)算符單詞求+=運(yùn)算符后的表達(dá)式expressiondo(nxtlev,ptx,lev);取+=左部的標(biāo)識(shí)符的值到棧頂gendo(lod,lev-tablei.level,tablei.adr);執(zhí)行加法gendo(opr,lev-tablei.level,2);保存賦值后的結(jié)果gendo(sto,lev-tablei.level,tablei.adr);else if(sym=pluseql) /檢測(cè)到+符號(hào)i=position(id,*ptx); /
10、把類x+=3的x的地址取出來gendo(lod,lev-tablei.level,tablei.adr); /*找到變量地址并將其值入棧*/getsymdo;if(sym=semicolon)getsymdo;memcpy(nxtlev,fsys,sizeof(bool)* symnum);expressiondo(nxtlev,ptx,lev);gendo(opr,0,2);if(i!=0)gendo(sto,lev-tablei.level,tablei.adr);else if(sym=minuseql) /檢測(cè)到-符號(hào)i=position(id,*ptx); /把類x-=3的x的地址取
11、出來gendo(lod,lev-tablei.level,tablei.adr); /*找到變量地址并將其值入棧*/getsymdo;if(sym=semicolon)getsymdo;memcpy(nxtlev,fsys,sizeof(bool)* symnum);expressiondo(nxtlev,ptx,lev);gendo(opr,0,3);if(i!=0)gendo(sto,lev-tablei.level,tablei.adr); 8.擴(kuò)充語句(Pascal的FOR語句):FOR := TO DO FOR := DOWNTO DO 其中,語句的循環(huán)變量的步長為2,語句的循環(huán)變量
12、的步長為-2For i:= E1 to E2 do S1 循環(huán)語句ALGOL等價(jià)于: i:= E1; goto OVER;AGAIN :i:= i+2OVER : if iE2 then Begin S1;goto again end;注意程序中基礎(chǔ)用到循環(huán)控制變量i,因此 entry(i)必須被保存下來,而Pascal這樣的語言中,循環(huán)變量在循環(huán)外也是可見的,本次擴(kuò)充約定循環(huán)步長為 2或者-2。具體需要在程序staement()添加for的句法判斷:else if(sym=forsym) /檢測(cè)到for語句getsymdo;if(sym=ident)i=position(id,*ptx);i
13、f(i=0) error(11);elseif(tablei.kind!=variable) /賦值語句中,賦值號(hào)左部標(biāo)識(shí)符屬性應(yīng)是變量error(12);i=0;elsegetsymdo;if(sym!=becomes) error(13); /賦值語句左部標(biāo)識(shí)符后應(yīng)是賦值號(hào):=else getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlevtosym=true; /后跟符to和downtonxtlevdowntosym=true;expressiondo(nxtlev,ptx,lev); /處理賦值語句右部的表達(dá)式E1gendo(s
14、to,lev-tablei.level,tablei.adr); /保存初值switch(sym)case tosym: /步長為的向上增加getsymdo;cx1=cx; /保存循環(huán)開始點(diǎn) /將循環(huán)判斷變量取出放到棧頂gendo(lod,lev-tablei.level,tablei.adr); memcpy(nxtlev,fsys,sizeof(bool)*symnum); /處理表達(dá)式E2nxtlevdosym=true; /后跟符doexpressiondo(nxtlev,ptx,lev);gendo(opr,0,13); /生成比較指令,i是否小于等于E2的值cx2=cx; /保存循
15、環(huán)結(jié)束點(diǎn)/生成條件跳轉(zhuǎn)指令,跳出循環(huán),跳出的地址未知gendo(jpc,0,0);if(sym=dosym) /處理循環(huán)體Sgetsymdo;statement(fsys,ptx,lev); /循環(huán)體處理 /增加循環(huán)變量步長為 /將循環(huán)變量取出放在棧頂gendo(lod,lev-tablei.level,tablei.adr); gendo(lit,0,1); /將步長取到棧頂gendo(opr,0,2); /循環(huán)變量加步長/將棧頂?shù)闹荡嫒胙h(huán)變量gendo(sto,lev-tablei.level,tablei.adr); gendo(jmp,0,cx1); /無條件跳轉(zhuǎn)到循環(huán)開始點(diǎn)code
16、cx2.a=cx; else error(29); /for語句中少了do break;case downtosym: /步長為的向下減少getsymdo;cx1=cx; /保存循環(huán)開始點(diǎn)/將循環(huán)判斷變量取出放到棧頂gendo(lod,lev-tablei.level,tablei.adr); memcpy(nxtlev,fsys,sizeof(bool)*symnum); /處理表達(dá)式E2nxtlevdosym=true; /后跟符doexpressiondo(nxtlev,ptx,lev); gendo(opr,0,11); /生成比較指令,i是否大于等于E2的值cx2=cx; /保存循環(huán)
17、結(jié)束點(diǎn)/生成條件跳轉(zhuǎn)指令,跳出循環(huán),跳出的地址未知gendo(jpc,0,0); if(sym=dosym) /處理循環(huán)體Sgetsymdo;statement(fsys,ptx,lev); /循環(huán)體處理 /增加循環(huán)變量步長為/將循環(huán)變量取出放在棧頂gendo(lod,lev-tablei.level,tablei.adr); gendo(lit,0,1); /將步長取到棧頂gendo(opr,0,3); /循環(huán)變量加步長/將棧頂?shù)闹荡嫒胙h(huán)變量gendo(sto,lev-tablei.level,tablei.adr); gendo(jmp,0,cx1); /無條件跳轉(zhuǎn)到循環(huán)開始點(diǎn)codec
18、x2.a=cx;else error(29);/for語句中少了dobreak;else error(19); /for語句后跟賦值語句,賦值語句左部是變量,缺少變量11. 增加運(yùn)算:+ 和 - :對(duì)于+和-運(yùn)算符,擴(kuò)充時(shí)要注意存在+,-有兩個(gè)情況:1、作為語句的時(shí)候;2、作為表達(dá)式中的因子的時(shí)候.(1) 作為語句的時(shí)候,有四種情況: A+ +A A- -A文法的 EBNF 表示形式為::= + | - | + | - (2) 作為因子的時(shí)候,有兩種情況 a+和 a-作為因子,比如:b:=a+*a-;語句+a 和-a 作為因子,比如:b:= -a+2*+a;語句文法的 EBNF 表示形式為::
19、=. + | - | + | - .其中的.表示前后都可以有其他的項(xiàng)或因子(1)作為語句 + - 符號(hào)分為以下兩種情況考慮:情況1對(duì)于自增自減符號(hào)置后的只需要在判斷+= -=后面添加句法分析即可:/*后置自增符號(hào) a+ a-類型添加代碼*/else if(sym=plusplus) /檢測(cè)到后置+符號(hào)gendo(lit,0,1);gendo(lod,lev-tablei.level,tablei.adr); /*找到變量地址并將其值入棧*/gendo(opr,0,2); /執(zhí)行加操作,if(i!=0) gendo(sto,lev-tablei.level,tablei.adr);getsymd
20、o;else if(sym=minusminus) /檢測(cè)到后置-符號(hào)gendo(lod,lev-tablei.level,tablei.adr); /*找到變量地址并將其值入棧*/gendo(lit,0,1);gendo(opr,0,3); /執(zhí)行減操作,if(i!=0) gendo(sto,lev-tablei.level,tablei.adr);getsymdo;情況2對(duì)于+ -前置的需要添加因子開始符號(hào): facbegsysplusplus=true; /*增加符號(hào)+開始因子plusplus*/facbegsysminusminus=true; /*增加符號(hào)-開始因子minusminu
21、s*/*前置自增符號(hào) +a - -a類型添加代碼*/if(sym=plusplus)getsymdo;if(sym=ident) /后面跟的是變量i=position(id,*ptx);if(i=0)error(11);elseif(tablei.kind!=variable) /+后沒跟變量,出錯(cuò)error(12);i=0;else /+后跟變量,處理生成中間代碼if(tablei.kind=variable)gendo(lod,lev-tablei.level,tablei.adr);/先取值到棧頂gendo(lit,0,1); /將值為入棧gendo(opr,0,2); /加法,即+1,
22、棧頂加次棧頂gendo(sto,lev-tablei.level,tablei.adr);/出棧取值到內(nèi)存getsymdo;else if(sym=minusminus)getsymdo;if(sym=ident) /后面跟的是變量i=position(id,*ptx);if(i=0)error(11);elseif(tablei.kind!=variable) /-后沒跟變量,出錯(cuò)error(12);i=0;else /-后跟變量,處理生成中間代碼if(tablei.kind=variable) /后跟變量gendo(lod,lev-tablei.level,tablei.adr);/先取值
23、到棧頂gendo(lit,0,1); /將值為入棧gendo(opr,0,3); /加法,即-1,棧頂減次棧頂gendo(sto,lev-tablei.level,tablei.adr);/出棧取值到內(nèi)存getsymdo;(2)作為因子的時(shí)候也有兩種情形考慮: 添加int factor(bool*fsys,int *ptx,int lev)函數(shù)如下:/*如果因子可能出現(xiàn)b:=a+或b:=a-類型的處理*/if(sym=plusplus)gendo(lit,lev-tablei.level,1); /將值為入棧gendo(opr,lev-tablei.level,2); /加法,即+1,棧頂加次
24、棧頂gendo(sto,lev-tablei.level,tablei.adr); /出棧取值到內(nèi)存gendo(lod,lev-tablei.level,tablei.adr); /取值到棧頂gendo(lit,0,1);gendo(opr,0,3); /棧頂值減getsymdo;else if(sym=minusminus)gendo(lit,lev-tablei.level,1); /將值為入棧gendo(opr,lev-tablei.level,3); /減法,即-1,棧頂減次棧頂gendo(sto,lev-tablei.level,tablei.adr); /出棧取值到內(nèi)存gendo(
25、lod,lev-tablei.level,tablei.adr);gendo(lit,0,1);gendo(opr,0,2); /棧頂值加getsymdo; /*/*如果因子是表達(dá)式的時(shí)候,則有可能是包含+a或者-a,如b:=+a或b:=-a */ else if(sym=plusplus)getsymdo;if(sym=ident)getsymdo;i=position(id,*ptx);if(i=0)error(11);elseif(tablei.kind=variable) /變量 /先加后再用agendo(lod,lev-tablei.level,tablei.adr);/先取值到棧頂
26、gendo(lit,0,1);/將值為入棧gendo(opr,0,2);/加法,即+1,棧頂加次棧頂gendo(sto,lev-tablei.level,tablei.adr);/出棧取值到內(nèi)存gendo(lod,lev-tablei.level,tablei.adr); /取值到棧頂else if(sym=minusminus)getsymdo;if(sym=ident)getsymdo;i=position(id,*ptx);if(i=0)error(11);elseif(tablei.kind=variable) /變量 /先減后再用agendo(lod,lev-tablei.level
27、,tablei.adr);/先取值到棧頂gendo(lit,0,1); /將值為入棧gendo(opr,0,3); /減法,即-1,棧頂減次棧頂gendo(sto,lev-tablei.level,tablei.adr);/出棧取值到內(nèi)存gendo(lod,lev-tablei.level,tablei.adr); /取值到棧頂testdo(fsys,facbegsys,23); /*因子后有非法符號(hào)*/程序測(cè)試擴(kuò)充賦值運(yùn)算:*= 和 /= 測(cè)試文件 “test1”: 運(yùn)行結(jié)果: 結(jié)果分析: a = 5 ,b = 48 , a*=3 結(jié)果為15正確,b/=6結(jié)果為8正確,擴(kuò)充成功! 擴(kuò)充語句(Pascal的FOR語句):測(cè)試文件“test2”:運(yùn)行結(jié)果:結(jié)果
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年廣東中考試題數(shù)學(xué)及答案
- 2025年國際組織筆試試題及答案
- 2025年三單元聲音測(cè)試題及答案
- 2025年凈空管理考試題及答案
- 2025年人工肛門考試試題及答案
- 2025年藥物化學(xué)試題及答案電大
- 2025年ue4面試題及答案
- 2025年體育生日常測(cè)試題及答案
- 2025年卒中中心考試試題及答案
- 2025年防控人員面試題及答案
- 安全管理知識(shí)培訓(xùn)課件
- 人工智能賦能教師數(shù)字素養(yǎng)提升
- 建筑力學(xué) 與結(jié)構(gòu)-筒體結(jié)構(gòu)體系的 類型及應(yīng)12課件講解
- 妊娠合并胃腸炎護(hù)理
- 【超星學(xué)習(xí)通】馬克思主義基本原理(南開大學(xué))爾雅章節(jié)測(cè)試網(wǎng)課答案
- 《勞動(dòng)工具的改進(jìn)設(shè)計(jì)》六年級(jí)綜合實(shí)踐課件
- TDT1055-2019第三次全國國土調(diào)查技術(shù)規(guī)程
- 【MOOC】電工學(xué)-中原工學(xué)院 中國大學(xué)慕課MOOC答案
- 濫用抗生素現(xiàn)狀及危害課件
- 2021年河南公務(wù)員行測(cè)考試真題及答案
- 廣告安裝施工及方案
評(píng)論
0/150
提交評(píng)論