編譯原理課程設(shè)計(jì)pl0編輯器擴(kuò)充_第1頁(yè)
編譯原理課程設(shè)計(jì)pl0編輯器擴(kuò)充_第2頁(yè)
編譯原理課程設(shè)計(jì)pl0編輯器擴(kuò)充_第3頁(yè)
編譯原理課程設(shè)計(jì)pl0編輯器擴(kuò)充_第4頁(yè)
編譯原理課程設(shè)計(jì)pl0編輯器擴(kuò)充_第5頁(yè)
已閱讀5頁(yè),還剩12頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、編譯原理課程設(shè)計(jì) 題 目 _ _PL0編輯器擴(kuò)充_ _學(xué) 院 計(jì)算機(jī)學(xué)院 專(zhuān) 業(yè) 軟件工程 年級(jí)班別 10級(jí)4班 學(xué) 號(hào) 3110006379 學(xué)生姓名 陳泳鑫 指導(dǎo)教師 楊勁濤 答辯程序設(shè)計(jì)報(bào)告撰寫(xiě)平時(shí)總成績(jī)2013 年 1 月 4 日課程設(shè)計(jì)目的與要求 1、課程設(shè)計(jì)目的:在分析理解一個(gè)教學(xué)型編譯程序(如PL/0)的基礎(chǔ)上,對(duì)其詞法分析程序、語(yǔ)法分析程序和語(yǔ)義處理程序進(jìn)行部分修改擴(kuò)充。達(dá)到進(jìn)一步了解程序編譯過(guò)程的基本原理和基本實(shí)現(xiàn)方法的目的。2、課程設(shè)計(jì)要求:基本內(nèi)容(成績(jī)范圍:“中”、“及格”或“不及格”)(1)擴(kuò)充賦值運(yùn)算:*= 和 /=擴(kuò)充語(yǔ)句(Pascal的FOR語(yǔ)句):FOR :=

2、 TO DO FOR := DOWNTO DO 其中,語(yǔ)句的循環(huán)變量的步長(zhǎng)為2,語(yǔ)句的循環(huán)變量的步長(zhǎng)為-2。(3)增加運(yùn)算:+ 和 -。選做內(nèi)容(成績(jī)?cè)u(píng)定范圍擴(kuò)大到:“優(yōu)”和“良”)(1)增加類(lèi)型: 字符類(lèi)型; 實(shí)數(shù)類(lèi)型。(2)擴(kuò)充函數(shù): 有返回值和返回語(yǔ)句; 有參數(shù)函數(shù)。(3)增加一維數(shù)組類(lèi)型(可增加指令)。(4)其他典型語(yǔ)言設(shè)施。二、結(jié)構(gòu)設(shè)計(jì)方案 結(jié)構(gòu)設(shè)計(jì)說(shuō)明: PL/0的編譯程序以語(yǔ)法分析程序?yàn)楹诵?,詞法分析程序和代碼生成程序都作為一個(gè)獨(dú)立的過(guò)程,當(dāng)語(yǔ)法分析需要讀單詞時(shí)就用詞法分析程序,而當(dāng)語(yǔ)法分析正確需生成相應(yīng)的目標(biāo)代碼時(shí),則調(diào)用代碼生成程序。此外,用表格管理程序建立變量,常量和過(guò)程標(biāo)

3、識(shí)符的說(shuō)明與引用之間的信息聯(lián)系。用出錯(cuò)處理程序?qū)υ~法和語(yǔ)法分析遇到的錯(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變量說(shuō)明處理11ListCode列出目標(biāo)代碼清單12FACTOR因子處理13TERM項(xiàng)處理14

4、EXPRESSION表達(dá)式處理15CONDITION條件處理16STATEMENT語(yǔ)句部分處理17Block分程序分析處理過(guò)程18BASE通過(guò)靜態(tài)鏈求出數(shù)據(jù)區(qū)的基地址19Interpret對(duì)目標(biāo)代碼的解釋執(zhí)行程序3. 符號(hào)名字表結(jié)構(gòu):struct tablestruct char nameal; /*名字*/ enum object kind; /*類(lèi)型: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í)符枚舉類(lèi)型:enum object constant, /*常量*/ variable, /*變量*/ procedur, /*過(guò)程*/;6. 運(yùn)行時(shí)存儲(chǔ)組織和管理對(duì)于源程序的每一個(gè)過(guò)程(包括主程序),在被調(diào)用時(shí),首先在數(shù)據(jù)段中開(kāi)辟三個(gè)空間,存放靜態(tài)鏈SL、動(dòng)態(tài)鏈DL和返回地址RA。靜態(tài)鏈記錄了定義該過(guò)程的直接外過(guò)程(或主程序)運(yùn)行時(shí)最新數(shù)據(jù)段的基地址。動(dòng)態(tài)鏈記錄調(diào)用該過(guò)程前正在運(yùn)行的過(guò)程的數(shù)據(jù)段基址。返回地址記錄了調(diào)用該過(guò)程時(shí)程序運(yùn)行的

7、斷點(diǎn)位置。對(duì)于主程序來(lái)說(shuō),SL、DL和RA的值均置為0。靜態(tài)鏈的功能是在一個(gè)子過(guò)程要引用它的直接或間接父過(guò)程(這里的父過(guò)程是按定義過(guò)程時(shí)的嵌套情況來(lái)定的,而不是按執(zhí)行時(shí)的調(diào)用順序定的)的變量時(shí),可以通過(guò)靜態(tài)鏈,跳過(guò)個(gè)數(shù)為層差的數(shù)據(jù)段,找到包含要引用的變量所在的數(shù)據(jù)段基址,然后通過(guò)偏移地址訪問(wèn)它。在過(guò)程返回時(shí),解釋程序通過(guò)返回地址恢復(fù)指令指針的值到調(diào)用前的地址,通過(guò)當(dāng)前段基址恢復(fù)數(shù)據(jù)段分配指針,通過(guò)動(dòng)態(tài)鏈恢復(fù)局部段基址指針。實(shí)現(xiàn)子過(guò)程的返回。對(duì)于主程序來(lái)說(shuō),解釋程序會(huì)遇到返回地址為0的情況,這時(shí)就認(rèn)為程序運(yùn)行結(jié)束。解釋程序過(guò)程中的base函數(shù)的功能,就是用于沿著靜態(tài)鏈,向前查找相差指定層數(shù)的局部

8、數(shù)據(jù)段基址。這在使用sto、lod、stoArr、lodArr等訪問(wèn)局部變量的指令中會(huì)經(jīng)常用到。類(lèi)PCODE代碼解釋執(zhí)行的部分通過(guò)循環(huán)和簡(jiǎ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 表示為:賦值語(yǔ)句:= += | -= (1)擴(kuò)充的語(yǔ)法描述見(jiàn)結(jié)構(gòu)設(shè)計(jì)中的 PL/0 分程序和主要語(yǔ)句的語(yǔ)法描述中的描述圖;(2)分析區(qū)別賦值運(yùn)算符采用:讀標(biāo)識(shí)符后再讀一個(gè)字符,后

9、根據(jù)讀到的字符轉(zhuǎn)去不同的賦值語(yǔ)句執(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、把類(lèi)x+=3的x的地址取出來(lái)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); /把類(lèi)x-=3的x的地址取

11、出來(lái)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ò)充語(yǔ)句(Pascal的FOR語(yǔ)句):FOR := TO DO FOR := DOWNTO DO 其中,語(yǔ)句的循環(huán)變量的步長(zhǎng)為2,語(yǔ)句的循環(huán)變量

12、的步長(zhǎng)為-2For i:= E1 to E2 do S1 循環(huán)語(yǔ)句ALGOL等價(jià)于: i:= E1; goto OVER;AGAIN :i:= i+2OVER : if iE2 then Begin S1;goto again end;注意程序中基礎(chǔ)用到循環(huán)控制變量i,因此 entry(i)必須被保存下來(lái),而Pascal這樣的語(yǔ)言中,循環(huán)變量在循環(huán)外也是可見(jiàn)的,本次擴(kuò)充約定循環(huán)步長(zhǎng)為 2或者-2。具體需要在程序staement()添加for的句法判斷:else if(sym=forsym) /檢測(cè)到for語(yǔ)句getsymdo;if(sym=ident)i=position(id,*ptx);i

13、f(i=0) error(11);elseif(tablei.kind!=variable) /賦值語(yǔ)句中,賦值號(hào)左部標(biāo)識(shí)符屬性應(yīng)是變量error(12);i=0;elsegetsymdo;if(sym!=becomes) error(13); /賦值語(yǔ)句左部標(biāo)識(shí)符后應(yīng)是賦值號(hào):=else getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum); nxtlevtosym=true; /后跟符to和downtonxtlevdowntosym=true;expressiondo(nxtlev,ptx,lev); /處理賦值語(yǔ)句右部的表達(dá)式E1gendo(s

14、to,lev-tablei.level,tablei.adr); /保存初值switch(sym)case tosym: /步長(zhǎng)為的向上增加getsymdo;cx1=cx; /保存循環(huán)開(kāi)始點(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)變量步長(zhǎng)為 /將循環(huán)變量取出放在棧頂gendo(lod,lev-tablei.level,tablei.adr); gendo(lit,0,1); /將步長(zhǎng)取到棧頂gendo(opr,0,2); /循環(huán)變量加步長(zhǎng)/將棧頂?shù)闹荡嫒胙h(huán)變量gendo(sto,lev-tablei.level,tablei.adr); gendo(jmp,0,cx1); /無(wú)條件跳轉(zhuǎn)到循環(huán)開(kāi)始點(diǎn)code

16、cx2.a=cx; else error(29); /for語(yǔ)句中少了do break;case downtosym: /步長(zhǎng)為的向下減少getsymdo;cx1=cx; /保存循環(huán)開(kāi)始點(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)變量步長(zhǎng)為/將循環(huán)變量取出放在棧頂gendo(lod,lev-tablei.level,tablei.adr); gendo(lit,0,1); /將步長(zhǎng)取到棧頂gendo(opr,0,3); /循環(huán)變量加步長(zhǎng)/將棧頂?shù)闹荡嫒胙h(huán)變量gendo(sto,lev-tablei.level,tablei.adr); gendo(jmp,0,cx1); /無(wú)條件跳轉(zhuǎn)到循環(huán)開(kāi)始點(diǎn)codec

18、x2.a=cx;else error(29);/for語(yǔ)句中少了dobreak;else error(19); /for語(yǔ)句后跟賦值語(yǔ)句,賦值語(yǔ)句左部是變量,缺少變量11. 增加運(yùn)算:+ 和 - :對(duì)于+和-運(yùn)算符,擴(kuò)充時(shí)要注意存在+,-有兩個(gè)情況:1、作為語(yǔ)句的時(shí)候;2、作為表達(dá)式中的因子的時(shí)候.(1) 作為語(yǔ)句的時(shí)候,有四種情況: A+ +A A- -A文法的 EBNF 表示形式為::= + | - | + | - (2) 作為因子的時(shí)候,有兩種情況 a+和 a-作為因子,比如:b:=a+*a-;語(yǔ)句+a 和-a 作為因子,比如:b:= -a+2*+a;語(yǔ)句文法的 EBNF 表示形式為::

19、=. + | - | + | - .其中的.表示前后都可以有其他的項(xiàng)或因子(1)作為語(yǔ)句 + - 符號(hào)分為以下兩種情況考慮:情況1對(duì)于自增自減符號(hào)置后的只需要在判斷+= -=后面添加句法分析即可:/*后置自增符號(hào) a+ a-類(lèi)型添加代碼*/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ì)于+ -前置的需要添加因子開(kāi)始符號(hào): facbegsysplusplus=true; /*增加符號(hào)+開(kāi)始因子plusplus*/facbegsysminusminus=true; /*增加符號(hào)-開(kāi)始因子minusminu

21、s*/*前置自增符號(hào) +a - -a類(lèi)型添加代碼*/if(sym=plusplus)getsymdo;if(sym=ident) /后面跟的是變量i=position(id,*ptx);if(i=0)error(11);elseif(tablei.kind!=variable) /+后沒(méi)跟變量,出錯(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) /-后沒(méi)跟變量,出錯(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-類(lèi)型的處理*/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ò)充語(yǔ)句(Pascal的FOR語(yǔ)句):測(cè)試文件“test2”:運(yùn)行結(jié)果:結(jié)果

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論