編譯原理課程方案設(shè)計(jì)書-PLO_第1頁
編譯原理課程方案設(shè)計(jì)書-PLO_第2頁
編譯原理課程方案設(shè)計(jì)書-PLO_第3頁
已閱讀5頁,還剩20頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、課程設(shè)計(jì)課程名稱編譯原理題目名稱編譯原理課程設(shè)計(jì).學(xué)生學(xué)院計(jì)算機(jī)學(xué)院專業(yè)班級計(jì)算機(jī)科學(xué)與技術(shù)_學(xué) 號學(xué)生姓名指導(dǎo)教師201 年1月7日實(shí)驗(yàn)?zāi)康呐c要求課內(nèi)實(shí)驗(yàn)(考試前交報(bào)告)對 PL/0 作以下修改擴(kuò)充:(1)增加單詞:保留字 ELSE, FOR ,STEP,UNTIL , RETURN 運(yùn)算符 +=, -= , +, -, A,V,n(2)修改單詞:不等號 # 改為 (3)增加條件語句的 ELSE 子句,要求:寫出相關(guān)文法,語法圖,語義規(guī)則。課程設(shè)計(jì)基本內(nèi)容(成績范圍: “中”、“及格”或“不及格” )(1)擴(kuò)充賦值運(yùn)算: += 和 -=(2)擴(kuò)充語句(Pascal的FOR語句):FOR 變量

2、 := 表達(dá)式 STEP 表達(dá)式UNTIL 表達(dá)式 DO 語句(3)增加運(yùn)算: + 和 -。選做內(nèi)容(成績評定范圍擴(kuò)大到: “優(yōu)”和“良” )(1) 增加類型: 字符類型;實(shí)數(shù)類型。(2)擴(kuò)充函數(shù): 有返回值和返回語句; 有參數(shù)函數(shù)。( 3)增加一維數(shù)組類型(可增加指令)。( 4)其他典型語言設(shè)施。二、 實(shí)驗(yàn)環(huán)境與工具(1)計(jì)算機(jī)及操作系統(tǒng): PC 機(jī), Windows 7( 2)程序設(shè)計(jì)語言:C 語言( 3 )教學(xué)型編譯程序:PL/0三、設(shè)計(jì)方案( 1)概述課程設(shè)計(jì)的目標(biāo)是做一個(gè)編譯器 ,用的是 PL/0 語言 ,該語言功能簡單、結(jié)構(gòu)清晰、可讀性強(qiáng)、 又具備了一般高級語言的必須部分 . PL

3、/0 語言的語句類型豐富 ,能適應(yīng)各種可能性的程序結(jié) 構(gòu).最基本的語句是賦值語句.組合結(jié)構(gòu)語句有語句串、條件語句和循環(huán)語句.數(shù)據(jù)類型只有整數(shù)類型一種 .PL/0 允許在一個(gè)過程范圍內(nèi)說明常數(shù)、變量和過程.也允許遞歸調(diào)用 ,既可以間接遞歸 ,也可以直接遞歸 .因而 PL/0 語言編譯器是一個(gè)非常合適的小型編譯程序的教學(xué)模 型矚慫潤厲釤瘞睞櫪廡賴。PL/0 的目標(biāo)程序?yàn)榧傧霔J降挠?jì)算機(jī)的匯編語言,與具體計(jì)算機(jī)無關(guān) ,可稱為類 PCODE 指令代碼 ,其指令集極為簡單 ,指令格式也很單純 .聞創(chuàng)溝燴鐺險(xiǎn)愛氌譴凈。本PL/O編譯器是在 C+Builder集成環(huán)境下,用C語言實(shí)現(xiàn),在Window 7平臺

4、下運(yùn)行 通過的.殘騖樓諍錈瀨濟(jì)溆塹籟。(2)編譯和解釋執(zhí)行的結(jié)構(gòu)圖:目標(biāo)程序PL/0語言編譯過程采用一趟掃描方式,以語法分析程序?yàn)楹诵?,詞法分析程序和代碼生成程 序都作為一個(gè)獨(dú)立的過程,當(dāng)語法分析需要讀單詞時(shí)就調(diào)用詞法分析程序,而當(dāng)語法分析正確需生成相應(yīng)的目標(biāo)代碼時(shí),則調(diào)用代碼生成程序.此外,用表格管理程序建立變量、常量和過程標(biāo)識符的說明與引用之間的信息聯(lián)系.用出錯(cuò)處理程序?qū)υ~法和語法分析研究遇到的錯(cuò)誤給出在源程序中出錯(cuò)的位置和錯(cuò)誤性質(zhì).當(dāng)源程序編譯正確時(shí),PL/0編譯程序自動調(diào)用解釋執(zhí)行,并按用戶程序要求輸入數(shù)據(jù)和輸出運(yùn)行結(jié)果.釅錒極額閉鎮(zhèn)檜豬訣錐。(3) 各功能模塊描述程序總體流程圖詞法分

5、析子程序分析:YG E T C HCC:=CC+1ch:=lineEccJC返回二)取字符過程GETCH詞法分箭過程GETSTIGetSym ()GetSym ()函數(shù)實(shí)現(xiàn)詞法分析的功能,它的作用是從文件中讀取一個(gè)單詞。在函數(shù)中調(diào)用了 GetCh ()。其中,GetCh ()函數(shù)實(shí)現(xiàn)了從文件中讀取一個(gè)字符的功能,同 時(shí)在讀取過程中忽略了空格,和回車,和制表符。其主要操作見流程圖。彈貿(mào)攝爾霽斃攬磚鹵廡。2、語法分析子程序分析:語法分析子程序采用了自頂向下的遞歸子程序法,語法分析同時(shí)也根據(jù)程序的語義生成相 應(yīng)三元代碼,并提供了出錯(cuò)處理的機(jī)制。謀蕎摶篋飆鐸懟類蔣薔。語法分析主要由:分程序分析過程BL

6、OCK常量疋義分析過程ConstDeclaration(int LEV,int &TX,int &DX)變量疋義分析過程:VarDeclaration(int LEV,int &TX,int &DX)語句分析程STATEMENT(SYMSET FSYS,i nt LEV,i nt & TX)表達(dá)式處理過程EXPRESSION(SYMSET FSYS, i nt LEV, i nt &TX)項(xiàng)處理過程TERM(SYMSET FSYS, i nt LEV, i nt &TX)因子處理過程FACTOR(SYMSET FSYS, i nt LEV

7、, i nt &TX)條件處理過程CONDITION(SYMSET FSYS,i nt LEV,i nt &TX)構(gòu)成。這些過程在結(jié)構(gòu)上構(gòu)成一個(gè)嵌套的層次結(jié)構(gòu)。除此之外,還有出錯(cuò)報(bào)告過程Error(i nt n)代碼生成過程Gen測試單詞合法性及出錯(cuò)恢復(fù)過程TEST(SYMSET S1, SYMSET S2, i nt N)登錄名字表過程ENTER(OBJECTS K, int LEV , int &TX, int &DX)查詢名字表函數(shù)POSITION(ALFA ID, i nt TX)列出類PCODE代碼過程ListCode(int CX0)作過語法分析的輔

8、助過程。語法分析開始后,首先調(diào)用分程序處理過程(Block )處理分程序。過程入口參數(shù)置為:0層、符號表位置 0、出錯(cuò)恢復(fù)單詞集合為句號、聲明符或語句開始符。進(jìn)入Block過程后,首先把局部數(shù)據(jù)段分配指針設(shè)為3,準(zhǔn)備分配 3個(gè)單元供運(yùn)行期存放靜態(tài)鏈SL、動態(tài)鏈DL和返回地址 RA。然后用Tx0記錄下當(dāng)前符號表位置并產(chǎn)生一條Jmp指令,準(zhǔn)備跳轉(zhuǎn)到主程序的開始位置,由于當(dāng)前還沒有知到主程序究竟在何處開始,所以Jmp的目標(biāo)暫時(shí)填為0,稍后再改。同時(shí)在符號表的當(dāng)前位置記錄下這個(gè)Jmp指令在代碼段中的位置。在判斷了嵌套層數(shù)沒有超過規(guī)定的層數(shù)后,開始分析源程序。首先判斷是否遇到了常量聲明, 如果遇到則開始

9、常量定義,把常量存入符號表。分析完成后,生成操作數(shù)為0的OPR指令,用于從分程序返回(對于 0層的主程序來說,就是程序運(yùn)行完成,退出)。廈礴懇蹣駢時(shí)盡繼價(jià)騷。常量定義過程:逐個(gè)字母讀取單詞,反復(fù)獲得標(biāo)識符和對應(yīng)的值,存入符號表。符號表中記錄下標(biāo)識符的名字和它對應(yīng)的值。變量定義過程:逐個(gè)字母讀取單詞,存入符號表。符號表中記錄下標(biāo)識符的名字、它所在的層及它在所在 層中的偏移地址。語句處理過程:在語句處理過程中,可以處理包括 += 語句、 -=語句、 if-else-then 語句、 while 語句、 For 語 句等的語句。在編譯過程中,如果有 begin 和 end 語句時(shí),就會遞歸調(diào)用子程序

10、,然后通 過子程序進(jìn)行處理。 煢楨廣鰳鯡選塊網(wǎng)羈淚。賦值語句的處理: 賦值語句首先查找賦值符號左邊的標(biāo)志符,查找符號表,看看這個(gè)標(biāo)志符是否為變量名。 然后查找賦值符號后面的數(shù)字,然后通過堆棧完成賦值操作。 鵝婭盡損鵪慘歷蘢鴛賴。read 語句的處理:確定 read 語句語法合理的前提下(否則報(bào)錯(cuò)) ,由變量的類型生成相應(yīng)的指令: 對于整型,第一條是 16號操作的 opr 指令,實(shí)現(xiàn)從標(biāo)準(zhǔn)輸入設(shè)備上讀一個(gè)整數(shù)值,放在數(shù) 據(jù)棧頂。如果讀入是實(shí)數(shù)就報(bào)錯(cuò),第二條是 sto 指令,把棧頂?shù)闹荡嫒?read 語句括號中的 變量所在的單元。 籟叢媽羥為贍僨蟶練淨(jìng)。對于實(shí)型,第一條是 15號操作的 opr 指

11、令,實(shí)現(xiàn)從標(biāo)準(zhǔn)輸入設(shè)備上讀一個(gè)實(shí)數(shù)值,放在數(shù) 據(jù)棧頂。第二條是 sto 指令,把棧頂?shù)闹荡嫒?read 語句括號中的變量所在的單元。 預(yù)頌圣鉉 儐歲齦訝驊糴。對于字符型,第一條是 20 號操作的 opr 指令,實(shí)現(xiàn)從標(biāo)準(zhǔn)輸入設(shè)備上讀一個(gè)字符值,第二 條是sto指令,把棧頂?shù)闹荡嫒雛ead語句括號中的變量所在的單元。滲釤嗆儼勻諤鱉調(diào)硯錦。write 語句的處理:與 read 語句相似。在語法正確的前提下,生成指令:通過循環(huán)調(diào)用表達(dá)式處理過程分析write 語句括號中的每一個(gè)表達(dá)式,生成相應(yīng)指令保證把表達(dá)式的值算出并放到數(shù)據(jù)棧頂并14號操作的opr指令,如果是字符類if 語句的條件,把相應(yīng)的真假值

12、放到j(luò)pc 指令的位置) ,然后生成條件生成指令,輸出表達(dá)式的值,如果是數(shù)字類型則生成型則生成19號操作的opr指令。鐃誅臥瀉噦圣騁貺頂廡。if-then-else 語句的處理:按 if 語句的語法,首先調(diào)用邏輯表達(dá)式處理過程處理 數(shù)據(jù)棧頂。接下去記錄下代碼段分配位置(即下面生成的 轉(zhuǎn)移 jpc 指令(遇 0 或遇假轉(zhuǎn)移) ,轉(zhuǎn)移地址未知暫時(shí)填 0。然后調(diào)用語句處理過程處理then語句后面的語句或語句塊。then后的語句處理完后,如果遇到else,就調(diào)用語句處理過程處理 else 語句后面的語句或語句塊,這時(shí)當(dāng)前代碼段分配指針的位置就應(yīng)該是上面的jpc 指令的轉(zhuǎn)移位置。通過前面記錄下的 jpc

13、 指令的位置,把它的跳轉(zhuǎn)位置改成當(dāng)前的代碼 段指針位置,否則沒遇到 else,那么此時(shí)的當(dāng)前代碼段分配指針的位置也是上面jpc指令的轉(zhuǎn)移位置,也是通過前面記錄下的 jpc 位置指令的位置,把它的跳轉(zhuǎn)到當(dāng)前的代碼段指針 位置。 擁締鳳襪備訊顎輪爛薔。begin/end語句的處理:通過循環(huán)遍歷 begin/end 語句塊中的每一個(gè)語句,通過遞歸調(diào)用語句分析過程分析并生成相 應(yīng)代碼。while 語句的處理:while 語句中首先用 cx1 變量記下當(dāng)前代碼段分配位置,作為循環(huán)的開始位置。然后處理的條件表達(dá)式生成相應(yīng)代碼把結(jié)果放在數(shù)據(jù)棧頂,再用 cx2 變量記下當(dāng)前位置,生成條件 轉(zhuǎn)移指令,轉(zhuǎn)移位置未

14、知,填 0。通過遞歸調(diào)用語句分析過程分析 do 語句后的語句或語句 塊并生成相應(yīng)代碼。最后生成一條無條件跳轉(zhuǎn)指令jmp ,跳轉(zhuǎn)到 cx1 所指位置,并把 cx2所指的條件跳轉(zhuǎn)指令的跳轉(zhuǎn)位置改成當(dāng)前代碼段分配位置。 贓熱俁閫歲匱閶鄴鎵騷。For 語句的處理:按 For 語句的語法,首先對 For 后面的一個(gè)標(biāo)識符進(jìn)行初值的賦值過程(類似賦值語句處 理),生成相應(yīng)的代碼。之后遇到 TO 或 DOWNTO 保留字,如果未對應(yīng)則出錯(cuò)。用 CX1 變 量記下當(dāng)前代碼段分配的位置,作為以后 JMP 循環(huán)的開始位置。對上面識別的標(biāo)識符變量 進(jìn)行存取(值在棧頂) ,讓 TO 或 DOWNTO 后面的表達(dá)式(值

15、在次棧頂)與之比較,生成 比較指令( TO 為 11、DOWNTO 為 13),再用 CX2 變量記下當(dāng)前代碼段分配的位置,生成 JPC 指令,跳轉(zhuǎn)地址未知,之后可用 CX2 記錄下的位置進(jìn)行回填。然后處理 DO 保留字后 的循環(huán)體,第一步遞歸調(diào)用語句分析過程,第二步將原先 For 后的標(biāo)識符變量進(jìn)行自加處 理,生成相應(yīng)代碼,然后生成無條件跳轉(zhuǎn)語句JMP跳轉(zhuǎn)代碼為CX1。最后將此時(shí)的代碼段位置回填到JPC跳轉(zhuǎn)指令上壇搏鄉(xiāng)囂懺蔞鍥鈴氈淚。4、代碼生成PL/0 處理機(jī)的指令集根據(jù) PL/0 語言的要求而設(shè)計(jì),它包括以下的指令:(1)LIT /* 將常數(shù)置于棧頂 */(2)LOD /* 將變量值置于

16、棧頂 */(3)STO /* 將棧頂?shù)闹蒂x與某變量 */(4)CAL /* 用于過程調(diào)用的指令 */(5)INT /* 在數(shù)據(jù)棧中分配存儲空間 */(6)OPR /* 一組算術(shù)或邏輯運(yùn)算指令 */(7)JMP, JPC /* 用于 if, while 語句的條件或無條件控制轉(zhuǎn)移指令 */5、代碼執(zhí)行相關(guān)過程:base(), interpret()。其中base()的功能是根據(jù)層次差并從當(dāng)前數(shù)據(jù)區(qū)沿 著靜態(tài)鏈查找,以便獲取變量實(shí)際所在的數(shù)據(jù)區(qū)其地址;interpret()則完成各種指令的執(zhí)行工作。 蠟變黲癟報(bào)倀鉉錨鈰贅。6、錯(cuò)誤診斷處理一個(gè)編譯程序,在多數(shù)情況下,所接受的源程序正文都是有錯(cuò)誤的。

17、發(fā)現(xiàn)錯(cuò)誤,并 給出合適的診斷信息且繼續(xù)編譯下去從而發(fā)現(xiàn)更多的錯(cuò)誤,對于編譯程序而言是完全必要 的。 買鯛鴯譖曇膚遙閆擷凄。相關(guān)過程: test(), inset(), createset, uniteset(), error() 。 綾鏑鯛駕櫬鶘蹤韋轔糴。7、符號表管理為了組成一條指令,編譯程序必須知道其操作碼及其參數(shù)(數(shù)或地址)。這些值是由編譯程序本身聯(lián)系到相應(yīng)標(biāo)識符上去的。這種聯(lián)系是在處理常數(shù)、變量和過程說明完成的。為此,標(biāo)識符表應(yīng)包含每一標(biāo)識符所聯(lián)系的屬性;如果標(biāo)識符被說明為常數(shù),其屬性 值為常數(shù)值;若被說明成變量,其屬性就是由層次和偏移量組成的地址;若被說明為過程, 其屬性就是過程的入

18、口地址及層次。常數(shù)的值由程序正文提供,編譯的任務(wù)就是確定存放 該值的地址。我們選擇順序分配變量和代碼的方法;每遇到一個(gè)變量說明,就將數(shù)據(jù)單元 的下標(biāo)加一(PL/O機(jī)中,每個(gè)變量占一個(gè)存貯單元)。開始編譯一個(gè)過程時(shí),要對數(shù)據(jù)單元的下標(biāo)dx賦初值,表示新開辟一個(gè)數(shù)據(jù)區(qū)。dx的初值為3,因?yàn)槊總€(gè)數(shù)據(jù)區(qū)包含三個(gè)內(nèi)部變量 RA,DL和SL。驅(qū)躓髏彥浹綏譎飴憂錦。相關(guān)過程:en ter(),該函數(shù)用于向符號表添加新的符號,并確定標(biāo)識符的有關(guān)屬性。四、主要成分描述:符號表:符號表實(shí)現(xiàn)了收集符號屬性,上下文語義的合法性檢查的依據(jù),作為目標(biāo)代碼生成階段地 址分配的依據(jù)等功能。符號表是全程量一維數(shù)組 TABLE。

19、TX為索引表的指針,表中的每個(gè)元素為記錄型數(shù)據(jù)。 表中的LEV表示層次,DX表示給本層局部變量分配的相對存貯位置,沒說明完一個(gè)變量 后DX加1。TABLE表中的NAME 表示元素名; KIND 表示元素的類型(常量、變量、過 程);VAL/LEVEL 在元素為常量時(shí)表示常量的值,在元素為變量或過程時(shí)表示層次;ADR在元素為變量時(shí)為變量的存貯位置,在元素為過程時(shí)為過程體的目標(biāo)代碼生成時(shí)反填過程 體的入口地址;SIZE是記錄過程所需的數(shù)據(jù)空間。貓蠆驢繪燈鮒誅髏貺廡。運(yùn)行時(shí)存儲組織和管理:該編譯程序使用的是棧式存儲分配的存儲組織管理方法。當(dāng)編譯結(jié)束后,存儲區(qū)只需以數(shù)組CODE存放的只讀程序和運(yùn)行式的

20、數(shù)據(jù)區(qū)S(由解釋程序定義的一維整形數(shù)組)。解釋執(zhí)行時(shí)的數(shù)據(jù)空間 S為棧式計(jì)算機(jī)的存儲空間。遵循后進(jìn)先出規(guī)則,對每個(gè)過程(包括主程序)當(dāng)被調(diào)用時(shí),才分配數(shù)據(jù)空間,退出過程時(shí),所分配的數(shù)據(jù)空間被釋放。鍬籟饗逕瑣筆襖鷗婭薔。解釋程序定義了 4個(gè)寄存器:I指令寄存器存放當(dāng)前正在解釋的一條目標(biāo)指令P程序地址寄存器指向下一條要執(zhí)行的目標(biāo)程序的地址T棧頂寄存器指向當(dāng)前棧中最新分配的單兀B基址寄存器指向每個(gè)過程被調(diào)用時(shí),在數(shù)據(jù)區(qū)S中給該過程分配的數(shù)據(jù)斷起始地址為了實(shí)現(xiàn)過程被調(diào)用時(shí)給它分配數(shù)據(jù)段,過程運(yùn)行結(jié)束后釋放數(shù)據(jù)段以及嵌套過程之間對標(biāo)識符引用的尋址問題,當(dāng)過程被調(diào)用時(shí),在棧頂分配三個(gè)聯(lián)系單 元,這三個(gè)單元

21、存放的內(nèi)容分別如下:構(gòu)氽頑黌碩飩薺齦話騖。SL靜態(tài)鏈:指向定義該過程的直接外過程(主程序)運(yùn)行時(shí)最新數(shù)據(jù)斷的基地址DL動態(tài)鏈:指向調(diào)用該過程前正在運(yùn)行過程的數(shù)據(jù)段基地址RA返回地址:記錄調(diào)用該過程時(shí)目標(biāo)程序的斷點(diǎn),即當(dāng)時(shí)的程序地址寄存器P的值語法分析方法:自頂向下遞歸子程序方法:從讀入第一個(gè)單詞開始,由非終結(jié)符程序 (即開始符)出發(fā),沿語法描述圖箭頭所指出的方向進(jìn)行分析。當(dāng)遇到非終結(jié)符時(shí),則調(diào)用相應(yīng)的處理過程, 從語法描述圖看,也就進(jìn)入了一個(gè)語法單元,再沿當(dāng)前所進(jìn)入的語法單元所指箭頭方向繼 續(xù)進(jìn)行分析。當(dāng)遇到描述圖中是終結(jié)符時(shí),則判斷當(dāng)前讀入的單詞是否與圖中的終結(jié)符相 匹配,若匹配,再讀取下一

22、個(gè)單詞繼續(xù)分析。遇到分支點(diǎn)時(shí),將當(dāng)前的單詞與分支點(diǎn)上多 個(gè)終結(jié)符逐個(gè)相比較,若都不匹配時(shí)可能是進(jìn)入下一個(gè)非終結(jié)符語法單位或是出錯(cuò)。輒嶧陽檉籪癤網(wǎng)儂號澩。中間代碼表示:PL/O編譯程序中間代碼稱為類 PCODE指令代碼,其指令格式如下:f1a其中f代表功能碼,I表示層次差(引用變量或過程的分程序與說明該變量或過程的分程序 之間的層次差)。a的含義對不同的指令有所區(qū)別。堯側(cè)閆繭絳闕絢勵(lì)蜆贅。五、完成的情況完成的功能如下:1. 課內(nèi)實(shí)驗(yàn)(考試前交報(bào)告)對PL/0作以下修改擴(kuò)充:(1) 增加單詞:保留字 ELSE , FOR , STEP , UNTIL , RETURN運(yùn)算符 +=, -=, +,

23、-, A,V,n(2) 修改單詞:不等號 #改為v(3) 增加條件語句的 ELSE子句,要求:寫出相關(guān)文法,語法圖,語義規(guī)則。2. 課程設(shè)計(jì)基本內(nèi)容(成績范圍:“中”、“及格”或“不及格”)(1 )擴(kuò)充賦值運(yùn)算:+=和-=(2) 擴(kuò)充語句(PascaI的FOR語句):FOR 變量 := 表達(dá)式 STEP 表達(dá)式UNTIL 表達(dá)式 DO 語句(3) 增加運(yùn)算:+和-。選做內(nèi)容(成績評定范圍擴(kuò)大到:“優(yōu)”和“良”)(1) 增加類型: 字符類型;實(shí)數(shù)類型。(2) 擴(kuò)充函數(shù): 有返回值和返回語句; 有參數(shù)函數(shù)。(3) 增加一維數(shù)組類型(可增加指令)。(4) 其他典型語言設(shè)施。增加單詞:保留字 ELSE

24、 , FOR , TO, STEP , UNTIL,RETURN. 運(yùn)算符 += , -=, +,-,先在 SYMBOL 中增加 ELSESYM, FORSYM, TOSYM,MINUSEQL ;然后 在 識饒鎂錕縊灩筧嚌儼淒。CHARACTER FOR <=TOSYM,UNTILSYM,RETURNSYM,INC,DEC,PLUSEQL, 保留字表中增加 ELSE,FOR,TO,STEP,UNTIL,RETURN.在詞法分析程序里增加下面的程序段:else if (CH='+') GetCh();if (CH='=') SYM=PLUSEQL; GetC

25、h(); else if(CH='+') SYM=INC; GetCh(); else SYM=PLUS;else if (CH='-') GetCh();if (CH='=') SYM=MINUSEQL; GetCh(); else if(CH='-') SYM=DEC; GetCh(); else SYM=MINUS;else if (CH='&') GetCh();if (CH='&') SYM=YU; GetCh(); else SYM=NUL;else if (CH=

26、9;|') GetCh();if (CH='|') SYM=HUO; GetCh(); else SYM=NUL;else if (CH=':') GetCh();if (CH='=') SYM=BECOMES; GetCh(); else SYM=NUL;else /* THE FOLLOWING TWO CHECK WERE ADDED BECAUSE ASCII DOES NOT HAVE A SINGLE OR >= */ 凍鈹鋨勞臘鍇癇婦脛糴。if (CH='<') GetCh();if (CH=&#

27、39;=') SYM=LEQ; GetCh(); else if (CH='>') SYM=NEQ; GetCh(); else SYM=LSS;else if (CH='>') GetCh();if (CH='=') SYM=GEQ; GetCh(); else SYM=GTR;else SYM=SSYMCH; GetCh(); (2)增加條件語句的 ELSE 子句 ,此功能擴(kuò)充只需在語句分析里面進(jìn)行增加如下代碼: case IFSYM:GetSym();CONDITION(SymSetUnion(SymSetNew(THE

28、NSYM,DOSYM,ELSESYM),FSYS), LEV ,TX); 恥諤銪滅縈歡煬鞏鶩錦。if (SYM=THENSYM) GetSym();else Error(16); CX1=CX;GEN(JPC,0,0);STATEMENT(SymSetUnion(SymSetNew(IDENT,ELSESYM,SEMICOLON),FSYS) ,LEV ,TX); 鯊腎鑰詘褳鉀溈懼統(tǒng)庫。if(SYM!=SEMICOLON) Form1->printls(" 錯(cuò)誤 IF",300); else GetSym();if(SYM=ELSESYM) GetSym();CX2=

29、CX;GEN(JMP,0,0); STATEMENT(FSYS,LEV ,TX);CODECX1.A=CX2+1;CODECX2.A=CX; else i=1;CODECX1.A=CX;return; break;(3)擴(kuò)充賦值運(yùn)算 :+=,- =. 此功能擴(kuò)充只需在語句分析里面進(jìn)行增加如下代碼:if(SYM=BECOMES|SYM=PLUSEQL|SYM=MINUSEQL)if (SYM=BECOMES)GetSym();EXPRESSION(FSYS,LEV ,TX);elseif(SYM=PLUSEQL|SYM=MINUSEQL) GEN(LOD,LEV-TABLEi.vp.LEVEL,

30、TABLEi.vp.ADR); if(SYM=PLUSEQL)GetSym();FACTOR(FSYS,LEV ,TX);GEN(OPR,0,2);elseif(SYM=MINUSEQL)GetSym();FACTOR(FSYS,LEV ,TX);GEN(OPR,0,3);if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);(4)擴(kuò)充 FOR TO 和 FOR DOWNTO 語句 ,此功能的關(guān)鍵是如何判斷條件是否成立,并如何進(jìn)行程序跳轉(zhuǎn) .在這里用到了幾條指令 ,和地址回填技術(shù) .擴(kuò)充代碼如下 : 碩癘鄴頏謅攆檸攜驤蘞。case FORSY

31、M:GetSym();if(SYM!=IDENT)Error(31); /FOR后面要標(biāo)識符i=POSITION(ID,TX);if (i=0) Error(11);elseif (TABLEi.KIND!=V ARIABLE) /*ASSIGNMENT TO NON- VARIABLE*/ 閿擻輳嬪諫遷擇楨秘騖。Error(12); / 變量GetSym(); if(SYM!=BECOMES) Error(13);GetSym();EXPRESSION(SymSetUnion(SymSetNew(TOSYM,DOWNTOSYM,DOSYM),FSYS),LEV ,T X);/ 表達(dá)式 氬嚕躑

32、竄貿(mào)懇彈瀘頷澩。if(SYM=DOWNTOSYM)CX1=CX;GetSym();GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);/保存結(jié)果至變量單元 釷鵒資贏車贖孫滅獅贅。GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);/重新調(diào)入棧頂 慫闡譜鯪逕導(dǎo)嘯畫長涼。EXPRESSION(SymSetAdd(DOSYM,FSYS),LEV ,TX);/ 表達(dá)式 GEN(OPR,0,11);/ 判斷運(yùn)算CX2=CX;GEN(JPC,0,0);/ 如果棧頂非真跳轉(zhuǎn)GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi

33、.vp.ADR);/ 重新調(diào)入棧頂 諺 辭調(diào)擔(dān)鈧諂動禪瀉類。GEN(LIT,0,1) ;/ 送 1 到棧頂GEN(OPR,0,3); / 減運(yùn)算 if(SYM=DOSYM) GetSym();STATEMENT(FSYS,LEV ,TX);GEN(JMP,0,CX1);CODECX2.A=CX;else if(SYM=TOSYM)CX1=CX;GetSym();GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);/ 保存結(jié)果至變量單元 嘰覲詿縲鐋囁偽純鉿錈。GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);/ 重新調(diào)入棧頂

34、熒紿譏鉦鏌觶鷹緇機(jī)庫。EXPRESSION(SymSetAdd(DOSYM,FSYS),LEV ,TX);/ 表達(dá)式分析GEN(OPR,0,13);/ 判斷運(yùn)算CX2=CX;GEN(JPC,0,0);/ 如果棧頂非真跳轉(zhuǎn)GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GEN(LIT,0,1);GEN(OPR,0,2);if(SYM=DOSYM)GetSym();STATEMENT(FSYS,LEV ,TX);GEN(JMP,0,CX1);CODECX2.A=CX;/ 回填地址else Error(35);break;(5)增加運(yùn)算 :+,-.這兩個(gè)運(yùn)算又分

35、為前加 ,后加,前減 ,后減.可以單獨(dú)做為一個(gè)語句 ,也可以 放在因子里 ,所以必須對語句分析程序和因子進(jìn)行擴(kuò)充.為了實(shí)現(xiàn)在因子里 +,- 運(yùn)算特別寫了兩個(gè)函數(shù) OPDOUBLE 和 DOUBLEOP 對因子進(jìn)行操作 :鶼漬螻偉閱劍鯫腎邏蘞。void DOUBLEOP()/ 前加 int i,TX;SYMBOL DOP;DOP=SYM;GetSym();if (SYM=IDENT) i=POSITION(ID,TX);if (i=0) Error(11);else if (TABLEi.KIND=V ARIABLE)GEN(LOD,TABLEi.vp.LEVEL,TABLEi.vp.ADR);

36、/ 將變量放到棧頂 紂憂蔣氳頑薟 驅(qū)藥憫騖。elseError(25); / 運(yùn)算符后必須是變量GEN(LIT,0,1); / 將 1 取到運(yùn)行棧頂 if(DOP=INC)GEN(OPR,0,2);elseGEN(OPR,0,3);GEN(STO,TABLEi.vp.LEVEL,TABLEi.vp.ADR);/ 存結(jié)果 GEN(LOD,TABLEi.vp.LEVEL,TABLEi.vp.ADR);/ 將變量放到棧頂 穎芻莖蛺餑億頓裊 賠瀧。GetSym();void OPDOUBLE(int i) / 后加if(i=0)Error(11);elseif (TABLEi.KIND=V ARIAB

37、LE)GEN(LOD,TABLEi.vp.LEVEL,TABLEi.vp.ADR);elseError(25);GEN(LIT,0,1);if(SYM=INC)GEN(OPR,0,2);elseGEN(OPR,0,3);GEN(STO,TABLEi.vp.LEVEL,TABLEi.vp.ADR);GetSym();六、測試用例1、后加測試用例: = COMPILE PL0 = 0 PROGRAM AA;0 VAR I,J;1 BEGIN2 I:=1;4 J:=100;6 I:=J+;12 WRITE(I);15 WRITE(J);18 END.0 JMP 0 11 INI 0 52 LIT 0

38、 13 STO 0 34 LIT 0 1005 STO 0 46 LOD 0 47 LOD 0 48 LIT 0 19 OPR 0 210 STO 0 411 STO 0 312 LOD 0 313 OPR 0 1414 OPR 0 1515 LOD 0 416 OPR 0 1417 OPR 0 1518 OPR 0 0RUN PL0 * 100 101END PL0* 2、前加測試用例:= COMPILE PL0 =0 PROGRAM MM;0 VAR A,B,C;1 BEGIN2 A:=10;4 B:=10;6 +A;10 -B;14 WRITE(A);17 WRITE(B);20 END

39、.0 JMP 0 11 INI 0 62 LIT 0 103 STO 0 34 LIT 0 105 STO 0 46 LOD 0 37 LIT 0 18 OPR 0 29 STO 0 310 LOD 0 411 LIT 0 112 OPR 0 313 STO 0 414 LOD 0 315 OPR 0 1416 OPR 0 1517 LOD 0 418 OPR 0 1419 OPR 0 1520 OPR 0 0RUN PL0 * 11END PL0* 3、 ELSE 語句測試用例 = COMPILE PL0 =0 PROGRAM EX01;0 VAR A,B,C;1 BEGIN2 A:=1;4

40、 B:=2;6 IF A>B THEN9 WRITE(A)12 ELSE14 WRITE(B);17 IF A<B THEN20 WRITE(A)23 ELSE25 WRITE(B);28 END.0 JMP 0 11 INI 0 62 LIT 0 13 STO 0 34 LIT 0 25 STO 0 46 LOD 0 37 LOD 0 48 OPR 0 129 JPC 0 1410 LOD 0 311 OPR 0 1412 OPR 0 1513 JMP 0 1714 LOD 0 415 OPR 0 1416 OPR 0 1517 LOD 0 318 LOD 0 419 OPR 0 1020 JPC 0 2521 LOD 0 322 OPR 0 1423 OPR 0 1524 JMP 0 2825 LOD 0 426 OPR

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論