版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p><b> 編譯原理課程設(shè)計(jì)</b></p><p> 題 目 __ _PL0編輯器擴(kuò)充__ __</p><p> 學(xué) 院 計(jì)算機(jī)學(xué)院 </p><p> 專(zhuān) 業(yè) 軟件工程 </p><p> 2013 年 1 月 4
2、日</p><p><b> 課程設(shè)計(jì)目的與要求</b></p><p><b> 1、課程設(shè)計(jì)目的:</b></p><p> 在分析理解一個(gè)教學(xué)型編譯程序(如PL/0)的基礎(chǔ)上,對(duì)其詞法分析程序、語(yǔ)法分析程序和語(yǔ)義處理程序進(jìn)行部分修改擴(kuò)充。達(dá)到進(jìn)一步了解程序編譯過(guò)程的基本原理和基本實(shí)現(xiàn)方法的目的。</p&g
3、t;<p><b> 2、課程設(shè)計(jì)要求:</b></p><p> 基本內(nèi)容(成績(jī)范圍:“中”、“及格”或“不及格”)</p><p> ?。?)擴(kuò)充賦值運(yùn)算:*= 和 /=</p><p> 擴(kuò)充語(yǔ)句(Pascal的FOR語(yǔ)句):</p><p> ①FOR <變量>:=<表達(dá)式
4、> TO <表達(dá)式> DO <語(yǔ)句></p><p> ?、贔OR <變量>:=<表達(dá)式> DOWNTO <表達(dá)式> DO <語(yǔ)句></p><p> 其中,語(yǔ)句①的循環(huán)變量的步長(zhǎng)為2,</p><p> 語(yǔ)句②的循環(huán)變量的步長(zhǎng)為-2。</p><p> (3
5、)增加運(yùn)算:++ 和 --。</p><p> 選做內(nèi)容(成績(jī)?cè)u(píng)定范圍擴(kuò)大到:“優(yōu)”和“良”)</p><p> ?。?)增加類(lèi)型:① 字符類(lèi)型; ② 實(shí)數(shù)類(lèi)型。</p><p> ?。?)擴(kuò)充函數(shù):① 有返回值和返回語(yǔ)句;② 有參數(shù)函數(shù)。</p><p> (3)增加一維數(shù)組類(lèi)型(可增加指令)。</p>
6、<p> ?。?)其他典型語(yǔ)言設(shè)施。</p><p><b> 二、結(jié)構(gòu)設(shè)計(jì)方案 </b></p><p><b> 結(jié)構(gòu)設(shè)計(jì)說(shuō)明:</b></p><p> PL/0的編譯程序以語(yǔ)法分析程序?yàn)楹诵?,詞法分析程序和代碼生成程序都作為一個(gè)獨(dú)立的過(guò)程,當(dāng)語(yǔ)法分析需要讀單詞時(shí)就用詞法分析程序,而當(dāng)語(yǔ)法分析正確需生
7、成相應(yīng)的目標(biāo)代碼時(shí),則調(diào)用代碼生成程序。此外,用表格管理程序建立變量,常量和過(guò)程標(biāo)識(shí)符的說(shuō)明與引用之間的信息聯(lián)系。用出錯(cuò)處理程序?qū)υ~法和語(yǔ)法分析遇到的錯(cuò)誤給出在源程序中出錯(cuò)的位置和錯(cuò)誤性質(zhì)。</p><p><b> 各功能模塊圖示:</b></p><p> 3. 各功能模塊作用表:</p><p> 3. 符號(hào)名字表結(jié)構(gòu):</p
8、><p> struct tablestruct</p><p><b> {</b></p><p> char name[al]; /*名字*/</p><p> enum object kind; /*類(lèi)型:const,var,array or procedure*/</p>&
9、lt;p> int val; /*數(shù)值,僅const使用*/</p><p> int level; /*所處層,僅const不使用*/</p><p> int adr; /*地址,僅const不使用*/</p><p> int size; /*需要分配的數(shù)據(jù)
10、區(qū)空間,僅procedure使用*/</p><p><b> };</b></p><p> 4. 保留關(guān)鍵字枚舉結(jié)構(gòu):</p><p> enum symbol{</p><p> nul, ident, number, plus,minus,</p><p> t
11、imes, slash, oddsym, eql, neq,</p><p> lss, leq, gtr, geq,lparen,</p><p> rparen, comma, semicolon, period, becomes,</p><p> beginsym, endsym,if
12、sym, thensym, whilesym,</p><p> writesym, readsym, dosym, callsym, constsym,</p><p> varsym, procsym, elsesym, forsym, tosym,</p><p> downtosym, returnsym,
13、 pluseql, minuseql, plusplus,</p><p> minusminus, </p><p><b> };</b></p><p> 5.名字表中標(biāo)識(shí)符枚舉類(lèi)型:</p><p>
14、 enum object{</p><p> constant, /*常量*/</p><p> variable, /*變量*/</p><p> procedur, /*過(guò)程*/</p><p><b> };</b></p><p>
15、 6. 運(yùn)行時(shí)存儲(chǔ)組織和管理</p><p> 對(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)行的斷點(diǎn)位置。對(duì)于主程序來(lái)說(shuō),SL、DL和RA的值均置為0。靜態(tài)鏈的功能是在一個(gè)子過(guò)程要引
16、用它的直接或間接父過(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é)束。
17、 解釋程序過(guò)程中的base函數(shù)的功能,就是用于沿著靜態(tài)鏈,向前查找相差指定層數(shù)的局部數(shù)據(jù)段基址。這在使用sto、lod、stoArr、lodArr等訪問(wèn)局部變量的指令中會(huì)經(jīng)常用到。 類(lèi)PCO</p><p> 7. 擴(kuò)充賦值運(yùn)算:+= 和 -= 設(shè)計(jì):</p><p> 對(duì)于+=、-=、*=和/=賦值運(yùn)算符,在程序中出現(xiàn)的情況只有如下一種,文法的EBNF 表示為:</p&g
18、t;<p> 賦值語(yǔ)句::= <標(biāo)識(shí)符> [ += | -= ] <表達(dá)式></p><p> ?。?)擴(kuò)充的語(yǔ)法描述見(jiàn)結(jié)構(gòu)設(shè)計(jì)中的 PL/0 分程序和主要語(yǔ)句的語(yǔ)法描述中的描述圖;</p><p> (2)分析區(qū)別賦值運(yùn)算符采用:讀標(biāo)識(shí)符后再讀一個(gè)字符,后根據(jù)讀到的字符轉(zhuǎn)去不同的賦值語(yǔ)句執(zhí)行。</p><p> ?。?
19、)中間代碼生成情況:+=運(yùn)算符,其他賦值運(yùn)算符架構(gòu)是一樣的,只是執(zhí)行加法改為相應(yīng)的算數(shù)運(yùn)算。</p><p> else if(sym==pluseql) //檢測(cè)到+=符號(hào)</p><p><b> {</b></p><p> i=position(id,*ptx);
20、 //把類(lèi)x+=3的x的地址取出來(lái)</p><p> gendo(lod,lev-table[i].level,table[i].adr); /*找到變量地址并將其值入棧*/</p><p><b> getsymdo;</b></p><p> if(sym==semicolon)</p>
21、;<p><b> {</b></p><p><b> getsymdo;</b></p><p><b> }</b></p><p> memcpy(nxtlev,fsys,sizeof(bool)* symnum);</p><p> expre
22、ssiondo(nxtlev,ptx,lev);</p><p> gendo(opr,0,2);</p><p><b> if(i!=0)</b></p><p><b> {</b></p><p> gendo(sto,lev-table[i].level,table[i].adr)
23、;</p><p><b> }</b></p><p><b> }</b></p><p> else if(sym==minuseql) //檢測(cè)到-=符號(hào)</p><p><b> {</b></p&
24、gt;<p> i=position(id,*ptx); //把類(lèi)x-=3的x的地址取出來(lái)</p><p> gendo(lod,lev-table[i].level,table[i].adr); /*找到變量地址并將其值入棧*/</p><p><b> getsymdo;</b>&l
25、t;/p><p> if(sym==semicolon)</p><p><b> {</b></p><p><b> getsymdo;</b></p><p><b> }</b></p><p> memcpy(nxtlev,fsys,si
26、zeof(bool)* symnum);</p><p> expressiondo(nxtlev,ptx,lev);</p><p> gendo(opr,0,3);</p><p><b> if(i!=0)</b></p><p><b> {</b></p><p
27、> gendo(sto,lev-table[i].level,table[i].adr);</p><p><b> }</b></p><p><b> }</b></p><p> 8.擴(kuò)充語(yǔ)句(Pascal的FOR語(yǔ)句):</p><p> ?、貴OR <變量&g
28、t;:=<表達(dá)式> TO <表達(dá)式> DO <語(yǔ)句></p><p> ?、贔OR <變量>:=<表達(dá)式> DOWNTO <表達(dá)式> DO <語(yǔ)句></p><p> 其中,語(yǔ)句①的循環(huán)變量的步長(zhǎng)為2,</p><p> 語(yǔ)句②的循環(huán)變量的步長(zhǎng)為-2</p><
29、;p> For i:= E1 to E2 do S1 循環(huán)語(yǔ)句ALGOL等價(jià)于:</p><p><b> i:= E1;</b></p><p> goto OVER;</p><p> AGAIN :i:= i+2</p><p> OVER : if i<E2 then </p>
30、;<p><b> Begin S1;</b></p><p> goto again end;</p><p> 注意程序中基礎(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的句法判斷:</p&
31、gt;<p> else if(sym==forsym) //檢測(cè)到for語(yǔ)句</p><p><b> {</b></p><p><b> getsymdo;</b></p><p> if(sym==ident)</p><p><b> {<
32、/b></p><p> i=position(id,*ptx);</p><p> if(i==0) error(11);</p><p><b> else</b></p><p><b> {</b></p><p> if(table[i].kind!
33、=variable) //賦值語(yǔ)句中,賦值號(hào)左部標(biāo)識(shí)符屬性應(yīng)是變量</p><p><b> {</b></p><p> error(12);i=0;</p><p><b> }</b></p><p><b> else</b></p><p&
34、gt;<b> {</b></p><p><b> getsymdo;</b></p><p> if(sym!=becomes) error(13); //賦值語(yǔ)句左部標(biāo)識(shí)符后應(yīng)是賦值號(hào):=</p><p> else getsymdo;</p><p> me
35、mcpy(nxtlev,fsys,sizeof(bool)*symnum); </p><p> nxtlev[tosym]=true; //后跟符to和downto</p><p> nxtlev[downtosym]=true;</p><p> expressiondo(nxtlev,ptx,lev);
36、 //處理賦值語(yǔ)句右部的表達(dá)式E1</p><p> gendo(sto,lev-table[i].level,table[i].adr); //保存初值</p><p> switch(sym)</p><p><b> {</b></p><p> case tosym: //步長(zhǎng)
37、為的向上增加</p><p><b> getsymdo;</b></p><p> cx1=cx; //保存循環(huán)開(kāi)始點(diǎn)</p><p> //將循環(huán)判斷變量取出放到棧頂</p><p> gendo(lod,lev-table[i].level,table[i].adr);
38、 memcpy(nxtlev,fsys,sizeof(bool)*symnum); //處理表達(dá)式E2</p><p> nxtlev[dosym]=true; //后跟符do</p><p> expressiondo(nxtlev,ptx,lev);</p><p> gendo
39、(opr,0,13); //生成比較指令,i是否小于等于E2的值</p><p> cx2=cx; //保存循環(huán)結(jié)束點(diǎn)</p><p> //生成條件跳轉(zhuǎn)指令,跳出循環(huán),跳出的地址未知</p><p> gendo(jpc,0,0);</p><p> if
40、(sym==dosym) //處理循環(huán)體S</p><p><b> {</b></p><p><b> getsymdo;</b></p><p> statement(fsys,ptx,lev); //循環(huán)體處理</p><p> //增加循環(huán)變量步長(zhǎng)為&
41、lt;/p><p> //將循環(huán)變量取出放在棧頂</p><p> gendo(lod,lev-table[i].level,table[i].adr); gendo(lit,0,1); //將步長(zhǎng)取到棧頂</p><p> gendo(opr,0,2);
42、 //循環(huán)變量加步長(zhǎng)</p><p> //將棧頂?shù)闹荡嫒胙h(huán)變量</p><p> gendo(sto,lev-table[i].level,table[i].adr); </p><p> gendo(jmp,0,cx1); //無(wú)條件跳轉(zhuǎn)到循環(huán)開(kāi)始點(diǎn)</p><p&
43、gt; code[cx2].a=cx;</p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> error(29); //for語(yǔ)句中少了do</p>&
44、lt;p><b> }</b></p><p><b> break;</b></p><p> case downtosym: //步長(zhǎng)為的向下減少</p><p><b> getsymdo;</b></p><p> cx1=cx;
45、 //保存循環(huán)開(kāi)始點(diǎn)</p><p> //將循環(huán)判斷變量取出放到棧頂</p><p> gendo(lod,lev-table[i].level,table[i].adr); memcpy(nxtlev,fsys,sizeof(bool)*symnum); //處理表達(dá)式E2</p>
46、;<p> nxtlev[dosym]=true; //后跟符do</p><p> expressiondo(nxtlev,ptx,lev);</p><p> gendo(opr,0,11); //生成比較指令,i是否大于等于E2的值</p><p> cx2=cx;
47、 //保存循環(huán)結(jié)束點(diǎn)</p><p> //生成條件跳轉(zhuǎn)指令,跳出循環(huán),跳出的地址未知</p><p> gendo(jpc,0,0); </p><p> if(sym==dosym) //處理循環(huán)體S</p><p><b> {</b></p><p&g
48、t;<b> getsymdo;</b></p><p> statement(fsys,ptx,lev); //循環(huán)體處理</p><p> //增加循環(huán)變量步長(zhǎng)為</p><p> //將循環(huán)變量取出放在棧頂</p><p> gendo(lod,lev-table[i].level,table[i].
49、adr); gendo(lit,0,1); //將步長(zhǎng)取到棧頂</p><p> gendo(opr,0,3); //循環(huán)變量加步長(zhǎng)</p><p> //將棧頂?shù)闹荡嫒胙h(huán)變量</p><p> gendo(sto,lev
50、-table[i].level,table[i].adr); gendo(jmp,0,cx1); //無(wú)條件跳轉(zhuǎn)到循環(huán)開(kāi)始點(diǎn)</p><p> code[cx2].a=cx;</p><p><b> }</b></p><p><b> else </b>
51、</p><p><b> {</b></p><p> error(29);//for語(yǔ)句中少了do</p><p><b> }</b></p><p><b> break;</b></p><p><b> }</b&g
52、t;</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> else </b></p><p><b> {</b>
53、;</p><p> error(19); //for語(yǔ)句后跟賦值語(yǔ)句,賦值語(yǔ)句左部是變量,缺少變量</p><p><b> }</b></p><p><b> }</b></p><p> 11. 增加運(yùn)算:++ 和 -- :</p><p>
54、 對(duì)于++和--運(yùn)算符,擴(kuò)充時(shí)要注意存在++,--有兩個(gè)情況:1、作為語(yǔ)句的時(shí)候;2、作為表達(dá)式中的因子的時(shí)候.</p><p> (1) 作為語(yǔ)句的時(shí)候,有四種情況:</p><p> A++ ++A A-- --A</p><p> 文法的 EBNF 表示形式為:</p><p> <自增自減語(yǔ)句>::=&l
55、t;標(biāo)識(shí)符>[ ++ | -- ] | [ ++ | -- ]<標(biāo)識(shí)符></p><p> (2) 作為因子的時(shí)候,有兩種情況</p><p> a++和 a--作為因子,比如:b:=a++*a--;語(yǔ)句</p><p> ++a 和--a 作為因子,比如:b:= --a+2*++a;語(yǔ)句</p><p> 文法的
56、EBNF 表示形式為:</p><p> <表達(dá)式>::=...[ ++ | -- ]<標(biāo)識(shí)符>|<標(biāo)識(shí)符>[ ++ | -- ]...</p><p> 其中的...表示前后都可以有其他的項(xiàng)或因子</p><p> (1)作為語(yǔ)句 ++ -- 符號(hào)分為以下兩種情況考慮:</p><p> 情況1對(duì)
57、于自增自減符號(hào)置后的只需要在判斷+= -=后面添加句法分析即可:</p><p> /*************后置自增符號(hào) a++ a--類(lèi)型添加代碼****************************/</p><p> else if(sym==plusplus) //檢測(cè)到后置++符號(hào)</p><p>&
58、lt;b> {</b></p><p> gendo(lit,0,1);</p><p> gendo(lod,lev-table[i].level,table[i].adr); /*找到變量地址并將其值入棧*/</p><p> gendo(opr,0,2); //執(zhí)行加操作,</p>
59、<p><b> if(i!=0)</b></p><p><b> {</b></p><p> gendo(sto,lev-table[i].level,table[i].adr);</p><p><b> }</b></p><p><b&g
60、t; getsymdo;</b></p><p><b> }</b></p><p> else if(sym==minusminus) //檢測(cè)到后置--符號(hào)</p><p><b> {</b></p><p> gendo
61、(lod,lev-table[i].level,table[i].adr); /*找到變量地址并將其值入棧*/</p><p> gendo(lit,0,1);</p><p> gendo(opr,0,3); //執(zhí)行減操作,</p><p><b> if(i!=0)</b>&
62、lt;/p><p><b> {</b></p><p> gendo(sto,lev-table[i].level,table[i].adr);</p><p><b> }</b></p><p> getsymdo;</p><p><b>
63、}</b></p><p> 情況2對(duì)于++ --前置的需要添加因子開(kāi)始符號(hào):</p><p> facbegsys[plusplus]=true; /***增加符號(hào)++開(kāi)始因子plusplus***/</p><p> facbegsys[minusminus]=true; /***增加符號(hào)--開(kāi)始因子minusminu
64、s***/</p><p> /***************前置自增符號(hào) ++a - -a類(lèi)型添加代碼****************************/</p><p> if(sym==plusplus)</p><p><b> {</b></p><p><b> getsymdo;&l
65、t;/b></p><p> if(sym==ident) //后面跟的是變量</p><p><b> {</b></p><p> i=position(id,*ptx);</p><p><b> if
66、(i==0)</b></p><p><b> {</b></p><p> error(11);</p><p><b> }</b></p><p><b> else</b></p><p><b> {</b
67、></p><p> if(table[i].kind!=variable) //++后沒(méi)跟變量,出錯(cuò)</p><p><b> {</b></p><p> error(12);</p><p><b> i=0;</b></p&
68、gt;<p><b> }</b></p><p> else //++后跟變量,處理生成中間代碼</p><p><b> {</b></p><p> if(table[i].kind==variable)&l
69、t;/p><p><b> {</b></p><p> gendo(lod,lev-table[i].level,table[i].adr);//先取值到棧頂</p><p> gendo(lit,0,1); //將值為入棧</p><p> gendo(opr
70、,0,2); //加法,即+1,棧頂加次棧頂</p><p> gendo(sto,lev-table[i].level,table[i].adr);//出棧取值到內(nèi)存</p><p><b> getsymdo;</b></p><p><b> }</b>&l
71、t;/p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> else if(sym==minusminus)<
72、;/p><p><b> {</b></p><p><b> getsymdo;</b></p><p> if(sym==ident) //后面跟的是變量</p><p><b> {</
73、b></p><p> i=position(id,*ptx);</p><p><b> if(i==0)</b></p><p><b> {</b></p><p> error(11);</p><p><b> }</b><
74、;/p><p><b> else</b></p><p><b> {</b></p><p> if(table[i].kind!=variable) //--后沒(méi)跟變量,出錯(cuò)</p><p><b> {</b></
75、p><p> error(12);</p><p><b> i=0;</b></p><p><b> }</b></p><p> else //--后跟變量,處理生成中間代碼</p>&l
76、t;p><b> {</b></p><p> if(table[i].kind==variable) //后跟變量</p><p><b> {</b></p><p> gendo(lod,lev-table[i].level,table[i].adr);//先取值到
77、棧頂</p><p> gendo(lit,0,1); //將值為入棧</p><p> gendo(opr,0,3); //加法,即-1,棧頂減次棧頂</p><p> gendo(sto,lev-table[i].level,table[i].adr
78、);//出棧取值到內(nèi)存</p><p><b> getsymdo;</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b>
79、; }</b></p><p><b> }</b></p><p> ?。?)作為因子的時(shí)候也有兩種情形考慮:</p><p> 添加int factor(bool*fsys,int *ptx,int lev)函數(shù)如下:</p><p> /********************如果因子可能出現(xiàn)b
80、:=a++或b:=a--類(lèi)型的處理******************/if(sym==plusplus)</p><p><b> {</b></p><p> gendo(lit,lev-table[i].level,1); //將值為入棧</p><p> gendo(opr,lev-table[i].le
81、vel,2); //加法,即+1,棧頂加次棧頂</p><p> gendo(sto,lev-table[i].level,table[i].adr); //出棧取值到內(nèi)存</p><p> gendo(lod,lev-table[i].level,table[i].adr); //取值到棧頂</p><p> gendo(lit,0,1
82、);</p><p> gendo(opr,0,3); //棧頂值減</p><p><b> getsymdo;</b></p><p><b> }</b></p><p> else if(sym==minusminus)<
83、/p><p><b> {</b></p><p> gendo(lit,lev-table[i].level,1); //將值為入棧</p><p> gendo(opr,lev-table[i].level,3); //減法,即-1,棧頂減次棧頂</p><p> ge
84、ndo(sto,lev-table[i].level,table[i].adr); //出棧取值到內(nèi)存</p><p> gendo(lod,lev-table[i].level,table[i].adr);</p><p> gendo(lit,0,1);</p><p> gendo(opr,0,2);
85、 //棧頂值加</p><p><b> getsymdo;</b></p><p> } /********************************************************************************/</p><p> /************如果因子是表達(dá)式的時(shí)候,則有可能是包
86、含++a或者--a,如b:=++a或b:=--a ********/</p><p> else if(sym==plusplus)</p><p><b> {</b></p><p><b> getsymdo;</b></p><p> if(sym==ident)</p>
87、<p><b> {</b></p><p><b> getsymdo;</b></p><p> i=position(id,*ptx);</p><p><b> if(i==0)</b></p><p><b> {</b>
88、</p><p> error(11);</p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> if(table[i].kind==variable) //變
89、量</p><p><b> {</b></p><p><b> //先加后再用a</b></p><p> gendo(lod,lev-table[i].level,table[i].adr);//先取值到棧頂</p><p> gendo(lit,0,1);//將值為入棧</p&
90、gt;<p> gendo(opr,0,2);//加法,即+1,棧頂加次棧頂</p><p> gendo(sto,lev-table[i].level,table[i].adr);//出棧取值到內(nèi)存</p><p> gendo(lod,lev-table[i].level,table[i].adr); //取值到棧頂}</p><p&g
91、t;<b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> else if(sym==minusminus)</p><p><b> {</b></p><p>
92、;<b> getsymdo;</b></p><p> if(sym==ident)</p><p><b> {</b></p><p><b> getsymdo;</b></p><p> i=position(id,*ptx);</p><
93、;p><b> if(i==0)</b></p><p><b> {</b></p><p> error(11);</p><p><b> }</b></p><p><b> else</b></p><p>
94、;<b> {</b></p><p> if(table[i].kind==variable) //變量</p><p><b> {</b></p><p><b> //先減后再用a</b></p><p> gendo(lod,lev-table[i].le
95、vel,table[i].adr);//先取值到棧頂</p><p> gendo(lit,0,1); //將值為入棧</p><p> gendo(opr,0,3); //減法,即-1,棧頂減次棧頂</p><p> gendo(sto,lev-table[i
96、].level,table[i].adr);//出棧取值到內(nèi)存</p><p> gendo(lod,lev-table[i].level,table[i].adr); //取值到棧頂}</p><p><b> }</b></p><p><b> }</b></p><p>
97、testdo(fsys,facbegsys,23); /*因子后有非法符號(hào)*/</p><p><b> }</b></p><p><b> 程序測(cè)試</b></p><p> 擴(kuò)充賦值運(yùn)算:*= 和 /=</p><p> 測(cè)試文件 “test1”:<
98、/p><p><b> 運(yùn)行結(jié)果:</b></p><p><b> 結(jié)果分析:</b></p><p> a = 5 ,b = 48 , a*=3 結(jié)果為15正確,b/=6結(jié)果為8正確,擴(kuò)充成功!</p><p> 擴(kuò)充語(yǔ)句(Pascal的FOR語(yǔ)句):</p><p>
99、; 測(cè)試文件“test2”:</p><p><b> 運(yùn)行結(jié)果:</b></p><p><b> 結(jié)果分析:</b></p><p> For i=1 to 4 do “write(i)” 結(jié)果i= 1,3,</p><p> For i=5 downto 1 do write(i)
100、 結(jié)果i= 5,3,1</p><p><b> 結(jié)果正確,</b></p><p> For循環(huán)功能擴(kuò)充成功!</p><p> 增加運(yùn)算:++ 和 --。</p><p> 測(cè)試文件“test3”:</p><p><b> 運(yùn)行結(jié)果:</b></p>
101、;<p><b> 結(jié)果分析:</b></p><p> a=5 ,b:=6, a--結(jié)果為4,b++結(jié)果為7,結(jié)果正確 </p><p> ++ ,--功能符號(hào)測(cè)試通過(guò)!</p><p><b> 實(shí)驗(yàn)總結(jié)</b></p><p> 本次課程設(shè)計(jì)主要是在讀懂課
102、本附帶的PL/0 編譯器程序C語(yǔ)言版本后進(jìn)行擴(kuò)展和修改相關(guān)程序功能。</p><p> 通過(guò)課程設(shè)計(jì),我對(duì)編譯器的工作原理和實(shí)現(xiàn)機(jī)制有了實(shí)際的了解和認(rèn)識(shí),進(jìn)一步培養(yǎng)的編譯技術(shù)的設(shè)計(jì)思想,仔細(xì)閱讀 PL/0 的編譯程序C語(yǔ)言版本代碼,對(duì)詞法分析,句法分析在編程技巧和實(shí)際意義有了深刻的理解,從枯燥的理論學(xué)習(xí)到現(xiàn)在實(shí)際應(yīng)用過(guò)程對(duì)于我自身知識(shí)面的提升是巨大的。語(yǔ)法分析、句法分析在編譯原理中處于核心的地位,如何正確有效的
103、對(duì)它們分析提取決定了編譯后期工作方向,當(dāng)然中間代碼的如何有效的生成在編譯中也是個(gè)不小的難題,特別是其中堆棧的運(yùn)用,當(dāng)然在理論上對(duì)于它們的理解程度大小也是決定設(shè)計(jì)調(diào)試</p><p><b> 難度的高低。</b></p><p> 擴(kuò)展 += -= 符號(hào)相對(duì)比較簡(jiǎn)單,只需要在語(yǔ)句分析模塊接著賦值符號(hào)的判斷添加就可以,對(duì)于for循環(huán)也是類(lèi)似,只需要在語(yǔ)句分析模塊添加
104、對(duì)于for關(guān)鍵字的判斷,當(dāng)然要注意后繼符號(hào)to 還是 downto的判斷以決定步長(zhǎng)遞增還是遞減。完成了基本功能擴(kuò)展,我嘗試了++ --符號(hào)的添加,這兩個(gè)符號(hào)添加比較復(fù)雜,大體講有兩個(gè)用途情況,一個(gè)就是用在用戶(hù)標(biāo)識(shí)符,另一個(gè)就是在因子上也可能用到該功能,需要添加因子的功能判斷,具體來(lái)講這兩個(gè)符號(hào)又有兩種實(shí)現(xiàn)形式,分別是后置符號(hào)和前置符號(hào),后置符號(hào)類(lèi)似前面的+= -= 直接添加判斷即可,前置符號(hào)則除了要添加++ --的開(kāi)始因子符號(hào)集外,還得
105、在語(yǔ)句分析模塊添加功能處理!</p><p> 總的來(lái)說(shuō),經(jīng)歷了數(shù)次的調(diào)試,功能擴(kuò)展算是完成了,這次課程設(shè)計(jì)使我受益匪淺,除了更深了解了編譯技術(shù),還培養(yǎng)了發(fā)現(xiàn)問(wèn)題、分析問(wèn)題、解決問(wèn)題的能力!</p><p><b> 附錄:</b></p><p> 源語(yǔ)言:PL/0語(yǔ)言 </p><p> 目標(biāo)語(yǔ)言:類(lèi)PCOD
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 編譯原理課程設(shè)計(jì)報(bào)告--pl0編譯器的擴(kuò)充
- 編譯原理課程設(shè)計(jì)-- pl0語(yǔ)言的擴(kuò)充
- 編譯原理課程設(shè)計(jì)--對(duì)pl0進(jìn)行擴(kuò)充和修改
- 編譯原理課程設(shè)計(jì)--對(duì)pl0進(jìn)行擴(kuò)充和修改
- 編譯原理課程設(shè)計(jì)--對(duì)PL0進(jìn)行擴(kuò)充和修改.doc
- 課程設(shè)計(jì)---pl0功能擴(kuò)充
- 課程設(shè)計(jì)---pl0功能擴(kuò)充
- pl0功能擴(kuò)充課程設(shè)計(jì)
- 編譯原理課程設(shè)計(jì)-pl_0編譯器及其擴(kuò)充
- 課程設(shè)計(jì)---PL0功能擴(kuò)充.doc
- PL0功能擴(kuò)充課程設(shè)計(jì).doc
- 編譯原理pl0課程設(shè)計(jì)報(bào)告
- 編譯原理課程設(shè)計(jì)報(bào)告---pl0編譯程序改進(jìn)及完善
- 編譯原理實(shí)驗(yàn)報(bào)告pl0
- pl0擴(kuò)展編譯器_設(shè)計(jì)文檔
- 微機(jī)原理課程設(shè)計(jì)—簡(jiǎn)易文本編輯器
- 文本編輯器課程設(shè)計(jì)
- vb編輯器課程設(shè)計(jì)報(bào)告
- 文本編輯器課程設(shè)計(jì)報(bào)告
- java課程設(shè)計(jì)---文本編輯器
評(píng)論
0/150
提交評(píng)論