編譯原理課程設(shè)計報告-詞法分析器_第1頁
編譯原理課程設(shè)計報告-詞法分析器_第2頁
編譯原理課程設(shè)計報告-詞法分析器_第3頁
編譯原理課程設(shè)計報告-詞法分析器_第4頁
編譯原理課程設(shè)計報告-詞法分析器_第5頁
已閱讀5頁,還剩21頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、編譯原理課程設(shè)計報告目錄 一、 目的和要求3二、運行平臺3三、結(jié)構(gòu)設(shè)計說明:31、概述32、各功能模塊描述4四、主要成分描述51.符號表52.運行時存儲組織和管理53.語法分析方法64.中間代碼表示6五、測試用例7測試+=的用例為:7測試-=的用例為:9測試for donwto的用例為:2測試for to do的用例為:10測試+的用例為:11測試的用例為:11測試char的用例為:14測試不等號用例為:14測試else用例為:14六、開發(fā)過程和完成情況161.總述162.具體添加的代碼17七、學(xué)習(xí)體會26八、關(guān)于這次課程設(shè)計的自我評價:271、自我評分:272、下面說一下我這次做這次pl0的

2、收獲:27一、 目的和要求基本內(nèi)容:(1)增加單詞:保留字 else,for,to, downto;運算符+=,-= ,+,-(2)修改單詞:不等號# 改為 (3)增加條件語句的else子句(4)擴充賦值運算:+= 和 -=(5)擴充語句(pascal的for語句):for := to do for := downto do 其中,語句的循環(huán)變量的步長為1,語句的循環(huán)變量的步長為-1。選做內(nèi)容:(1)增加運算:+ 和 -。(2)增加類型: 字符類型; 實數(shù)類型。(3)擴充函數(shù): 有返回值和返回語句; 有參數(shù)函數(shù)。(4)增加一維數(shù)組類型(可增加指令)。二、運行平臺編譯器實現(xiàn)工具和運行平臺程序用c

3、+語言編寫,在c+ builder平臺下運行。三、結(jié)構(gòu)設(shè)計說明:1、概述pl/0語言是pascal語言的一個子集,這里分析的pl/0的編譯程序包括了對pl/0語言源程序進(jìn)行分析處理、編譯生成類pcode代碼,并在虛擬機上解釋運行生成的類pcode代碼的功能。pl/0語言編譯程序采用以語法分析為核心、一遍掃描的編譯方法。詞法分析和代碼生成作為獨立的子程序供語法分析程序調(diào)用。語法分析的同時,提供了出錯報告和出錯恢復(fù)的功能。在源程序沒有錯誤編譯通過的情況下,調(diào)用類pcode解釋程序解釋執(zhí)行生成的類pcode代碼。pl/0的編譯過程采用一趟掃描方式,以語法分析為核心,詞法分析程序和代碼生成程序都作為一

4、個獨立的過程,當(dāng)語法分析需要讀入單詞時就調(diào)用詞法分析程序,而當(dāng)語法分析正確需生成相應(yīng)的目標(biāo)代碼時,則調(diào)用代碼生成程序。此外,用表格管理程序建立變量、常量和過程標(biāo)識符的說明與引用之間的信息聯(lián)系。用出錯處理程序?qū)υ~法和語法分析遇到的錯誤給出在源程序中出錯的位置和錯誤性質(zhì)。當(dāng)源程序編譯正確時,pl/0編譯程序自動調(diào)用解釋執(zhí)行程序,對目標(biāo)代碼進(jìn)行解釋執(zhí)行,并按用戶程序的要求輸入數(shù)據(jù)和輸出運行結(jié)果。2、各功能模塊描述詞法分析詞法分析是編譯的第一個階段,它的主要任務(wù)是從左向右逐個字符地對源程序進(jìn)行掃描,產(chǎn)生一個個單詞序列用于語法分析。pl/0詞法分析程序getsym的功能是為語法分析提供單詞用的,是語法分

5、析的基礎(chǔ),把輸入的字符串形式的源程序分割成一個個單詞符號。經(jīng)過詞法分析程序分析出來的單詞,對語言固有的單詞只給出類別存放在全程變量sym中,而對用戶定義的單詞(標(biāo)識符或常數(shù))既給出類別又給值,其類別放在sym中,值放在全程變量id或全程變量num中,全部單詞種類由編譯程序定義的純量類型symbol給出,稱為語法詞匯表。詞法分析器的分析過程:調(diào)用getsym時,它通過getch過程從源程序中獲得一個字符。如果這個字符是字母,則繼續(xù)獲取字符或數(shù)字,最終可以拼成一個單詞,查保留字表,如果查到為保留字,則把sym變量賦成相應(yīng)的保留字類型值;如果沒有查到,則這個單詞應(yīng)是一個用戶自定義的標(biāo)識符(可能是變量

6、名、常量名或是過程的名字),把sym置為ident,把這個單詞存入id變量。查保留字表時使用了二分法查找以提高效率。如果getch獲得的字符是數(shù)字,則繼續(xù)用getch獲取數(shù)字,并把它們拼成一個整數(shù)或?qū)崝?shù),然后把sym置為 integer,并把拼成的數(shù)值放入num變量。如果識別出其它合法的符號(比如:賦值號、大于號、小于等于號等),則把sym則成相應(yīng)的類型。如果遇到不合法的字符,把sym置成nul。詞法分析程序getsym將完成下列任務(wù):(1)濾空格 (2)識別保留字 (3)識別標(biāo)識符(4)拼數(shù) (5)拼復(fù)合詞 (6)輸出源程序 語法分析pl/0編譯程序的語法分析采用了自頂向下的遞歸的子程序法。

7、語法分析同時也根據(jù)程序的語義生成相應(yīng)三元代碼,并提供了出錯處理的機制。語法分析主要由分程序分析過程(block)、常量定義分析過程(constdeclaration)、變量定義分析過程(vardeclaration)、語句分析過程(statement)、表達(dá)式處理過程(expression)、項處理過程(term)、因子處理過程(factor)和條件處理過程(condition)構(gòu)成。這些過程在結(jié)構(gòu)上構(gòu)成一個嵌套的層次結(jié)構(gòu)。除此之外,還有出錯報告過程(error)、代碼生成過程(gen)、測試單詞合法性及出錯恢復(fù)過程(test)、登錄名字表過程(enter)、查詢名字表函數(shù)(position)

8、以及列出類 pcode代碼過程(listcode)作過語法分析的輔助過程。由pl/0的語法圖可知:一個完整的pl/0程序是由分程序和句號構(gòu)成的。因此,本編譯程序在運行的時候,通過主程序中調(diào)用分程序處理過程block來分析分程序部分(分程序分析過程中還可能會遞歸調(diào)用block過程),然后,判斷最后讀入的符號是否為句號。如果是句號且分程序分析中未出錯,則是一個合法的pl/0程序,可以運行生成的代碼,否則就說明源pl/0程序是不合法的,輸出出錯提示即可。. 語義分析pl/0 的語義分析主要進(jìn)行以下檢查:(1) 是否存在標(biāo)識符先引用未聲明的情況;(2) 是否存在己聲明的標(biāo)識符的錯誤引用;(3) 是否存

9、在一般標(biāo)識符的多重聲明。語法錯誤處理pl/0編譯程序?qū)φZ法錯誤的處理采用兩種辦法:(1)對于一些易于校正的錯誤,如丟了逗號、分號等,指出出錯的位置,加以校正,繼續(xù)進(jìn)行分析。 (2)對于難于校正的錯誤,給出錯誤的位置與性質(zhì),跳過后面一些單詞,直到下一個可以進(jìn)行正常語法分析的語法單位。解釋執(zhí)行這個過程模擬了一臺可以運行類pcode指令的棧式計算機。解釋程序過程中的base函數(shù)的功能,就是用于沿著靜態(tài)鏈,向前查找相差指定層數(shù)的局部數(shù)據(jù)段基址。這在使用sto、lod等訪問局部變量的指令中會經(jīng)常用到。類pcode代碼解釋執(zhí)行的部分通過循環(huán)和簡單的case判斷不同的指令,做出相應(yīng)的動作。當(dāng)遇到主程序中的返

10、回指令時,指令指針會指到0位置,把這樣一個條件作為終至循環(huán)的條件,保證程序運行可以正常的結(jié)束。生產(chǎn)目標(biāo)代碼后,程序調(diào)用interpret程序解釋執(zhí)行,程序定義的一個數(shù)據(jù)區(qū)s,三個寄存器t棧頂寄存器,b基址寄存器和p程序地址寄存器用于運行程序。四、主要成分描述1.符號表 在編譯過程中常用到的表格包括常量表、變量表(標(biāo)識符表)、保留字表、數(shù)組表和過程信息表等。統(tǒng)稱為符號表,又稱為單詞屬性字表;符號表可以用來收集符號屬性、是上下文語義的合法性檢查的依據(jù)、也作為目標(biāo)代碼生成階段地址分配的依據(jù)。從編譯系統(tǒng)的造表過程來區(qū)分,符號表可分為靜態(tài)表(是事先構(gòu)造好表,編譯程序需要使用時直接查找。如:保留字、標(biāo)準(zhǔn)函

11、數(shù)名表等)和動態(tài)表(編譯程序在編譯過程中根據(jù)需要構(gòu)造的表。如:標(biāo)識符表、符號表、循環(huán)表、數(shù)組信息表和過程表等)。符號表在編譯過程的重要作用主要表現(xiàn)在兩個方面:輔助語義的正確性和檢查輔助目標(biāo)代碼的生成。符號表有若干個表項組成,每個表項有單詞的名字域和屬性域兩部分。符號表應(yīng)包括符號的所有屬性,這樣可以有助于編譯程序的語義檢查和生成可運行的目標(biāo)代碼,其主要內(nèi)容包括:符號的名字、符號的類型、地址碼、符號的類型、地址碼、數(shù)組的維數(shù)、下標(biāo)的類型或過程參數(shù)等等。符號表的組織可分為符號表的總統(tǒng)組織、符號表項的排列、關(guān)鍵字域的組織、其它域的組織和下推鏈組織;符號表的管理包括符號表的初始化、符號的登錄、符號的查找

12、、符號表中分程序結(jié)構(gòu)層次分管理。2.運行時存儲組織和管理 程序運行時的存儲區(qū)常常劃分成:目標(biāo)區(qū)、靜態(tài)數(shù)據(jù)區(qū)、棧區(qū)和堆區(qū)。數(shù)據(jù)空間的使用和管理方法分成三種:靜態(tài)存儲分配、棧式動態(tài)存儲分配和堆式動態(tài)存儲分配。在簡單棧式存儲分配的實現(xiàn)中常常使用兩個指針指示棧最頂端的數(shù)據(jù)區(qū),一個是sp(總是指向現(xiàn)行過程活動記錄的起點),另一個是top(始終指向已占用的棧頂單元),嵌套過程語言的棧式實現(xiàn)只是增加了非局部變量的存取,其方法有在過程活動記錄中增設(shè)存取鏈和在每進(jìn)入一個過程后,在建立它的活動記錄的同時建立一張嵌套層次顯示表display。在分程序結(jié)構(gòu)的存儲管理中要注意分清楚各過程體的活動記錄和sp及top指針的

13、始末位置。在過程調(diào)用過程中有可能有參數(shù)的傳遞,其路徑有:傳值,傳地址,傳名及宏擴展等。3.語法分析方法 語法分析是編譯程序的核心部分。語法分析的作用是識別由詞法分析給出的單詞符號序列是否是給的文法的正確句子(程序),目前語法分析常用的方法由自頂向下分析和自底向上分析兩大類。自頂向下分析包括確定分析和不確定分析,自底向上分析包括算符優(yōu)先分析和lr分析。自頂向下的不確定分析方法是帶回溯的分析方法,實際上是一種窮舉的試探方法,因此效率低。代價高。確定的自頂向下分析方法,是從文法的開始符號出發(fā),考慮如何根據(jù)當(dāng)前的輸入符號(單詞符號)惟一地確定選用哪個產(chǎn)生式替換相應(yīng)非終結(jié)符以往下推導(dǎo),或如何構(gòu)造一棵相應(yīng)

14、的語法樹。確定的自頂向下分析方法只適合于ll(1)文法,一個文法需經(jīng)過計算它的first、follow、select集合來判斷其是否為ll(1)文法,有些文法也可以通過踢去左公因子和消除左遞歸來轉(zhuǎn)換成ll(1)文法。確定的自頂向下分析方法有遞歸子程序法(對應(yīng)文法中每個非終結(jié)符編寫一個遞歸過程)和預(yù)測分析方法(由預(yù)測分析程序、先進(jìn)后出棧和預(yù)測分析表組成)。簡單優(yōu)先分析法的基本思想是對一個文法按一定原則求出該文法所有符號即包括終結(jié)符和非終結(jié)符之間的優(yōu)先關(guān)系,按照這種關(guān)系確定歸約過程中的句柄,它的歸約過程實際上是一種規(guī)范歸約;其關(guān)鍵是構(gòu)造優(yōu)先關(guān)系表的構(gòu)造。自底向上分析法的關(guān)鍵問題是在分析過程中如何確

15、定句柄,lr分析法正是給出一種能根據(jù)當(dāng)前分析棧中的符號串(通常以狀態(tài)表示)和向右順序查看輸入串的k個(k=0)符號就可惟一確定分析器的動作是移進(jìn)還是歸約和用哪個產(chǎn)生式歸約,因而也就能惟一地確定句柄。lr分析法的歸約過程是規(guī)范推導(dǎo)的逆過程,所以lr分析過程是一種規(guī)范歸約過程。一個lr分析器是由總控程序、分析表或分析函數(shù)和分析棧三部分組成的,lr分析過程主要是對文法的產(chǎn)生式進(jìn)行排序、計算各非終結(jié)符的first和follow集、構(gòu)造文法關(guān)于lr(k)的項目集族(若有沖突的話要用相關(guān)的辦法解決)、根據(jù)項目集族構(gòu)造相應(yīng)的lr(k) 分析表、對輸入的字符串進(jìn)行分析,看是屬于接受態(tài)還是出錯。4.中間代碼表示

16、 中間代碼長見的形式有逆波蘭記號(后綴式)、三元式、四元式和樹形表示。逆波蘭記號式最簡單的一種中間代碼表示形式,這種表示法將運算對象寫在前面,把運算符號寫在后面,其最大的優(yōu)點是易于計算機處理表達(dá)式。利用一個棧,自左至右掃描算術(shù)表達(dá)式(后綴表示)。每碰到運算對象,就把它推進(jìn)棧;碰到運算符,若該運算符是二目的,則對棧頂部的兩個運算對象實施該運算,并將運算結(jié)構(gòu)代替這兩個運算對象而進(jìn)棧。若是一目運算符,則對棧頂元素執(zhí)行該運算,并以運算結(jié)果代替該元素進(jìn)棧。最后的結(jié)果留在棧頂。每個三元式3個組成部分式:算符op,第1運算對象arg1,和第2運算對象arg2。對于一目算符op,只需算用一個算符對象,多目算符

17、可用若干個相繼的三元式表示。樹形表示是三元式表示的翻版。四元式的四個組成成分式:算符op,第一和第二運算對象arg1和arg2及運算結(jié)果result。運算對象和運算結(jié)果有時指用戶自己定義的變量,有時指編譯程序引進(jìn)的臨時變量。四元式之間的聯(lián)系式銅鼓臨時變量實現(xiàn)的。五、測試用例測試+=的用例為:用例1:11program test;var a,b,c;begin a:=10; read(b); c:=b*4+a; write(c); c += a ; write(c);end.編譯代碼為:= compile pl0 = 0 program test; 0 var a,b,c; 1 begin 2

18、a:=10; 4 read(b); 6 c:=b*4+a; 12 write(c); 15 c += a ; 19 write(c); 22 end. 0 jmp 0 1 1 ini 0 6 2 lit 0 10 3 sto 0 3 4 opr 0 16 5 sto 0 4 6 lod 0 4 7 lit 0 4 8 opr 0 4 9 lod 0 3 10 opr 0 2 11 sto 0 5 12 lod 0 5 13 opr 0 14 14 opr 0 15 15 lod 0 5 16 lod 0 3 17 opr 0 2 18 sto 0 5 19 lod 0 5 20 opr 0 1

19、4 21 opr 0 15 22 opr 0 0運行結(jié)果:用例2:program test;vara:integer;begina:=10;a+=5;write( a );end.編譯代碼及運行結(jié)果:測試-=的用例為:program test;var a;begina:=9;a-=4;write( a );end.編譯代碼為:* pl/0 compiler demo *= compile pl0 = 0 program test; 0 var a; 1 begin 2 a:=9; 4 a-=4; 8 write( a ); 11 end. 0 jmp 0 1 1 ini 0 4 2 lit 0

20、 9 3 sto 0 3 4 lod 0 3 5 lit 0 4 6 opr 0 3 7 sto 0 3 8 lod 0 3 9 opr 0 14 10 opr 0 15 11 opr 0 0- run pl0 - 5- end pl0 -測試for donwto的用例為:program test;var a,c;begin for a:=5 downto 1 do c+=a; write(c);end.編譯代碼為:= compile pl0 = 0 program test; 0 var a,c; 1 begin 2 for a:=5 downto 1 do 8 c+=a; 17 write

21、(c); 20end. 0 jmp 0 1 1 ini 0 5 2 lit 0 5 3 sto 0 3 4 lod 0 3 5 lit 0 1 6 opr 0 11 7 jpc 0 17 8 lod 0 4 9 lod 0 3 10 opr 0 2 11 sto 0 4 12 lod 0 3 13 lit 0 1 14 opr 0 3 15 sto 0 3 16 jmp 0 4 17 lod 0 4 18 opr 0 14 19 opr 0 15 20 opr 0 0- run pl0 - 15- end pl0 -測試for to do的用例為:program test;var a;begi

22、nfor a:=3 to 8 dowrite(a);end.編譯代碼為:= compile pl0 = 0 program test; 0 var a; 1 begin 2 for a:=3 to 8 do 8 write(a); 16 end. 0 jmp 0 1 1 ini 0 4 2 lit 0 3 3 sto 0 3 4 lod 0 3 5 lit 0 8 6 opr 0 13 7 jpc 0 16 8 lod 0 3 9 opr 0 14 10 opr 0 15 11 lod 0 3 12 lit 0 1 13 opr 0 2 14 sto 0 3 15 jmp 0 4 16 opr

23、 0 0- run pl0 - 345678- end pl0 -測試+的用例為:program test;var a;begin a:=20; +a; write(a);end.編譯代碼為:= compile pl0 = 0 program test; 0 var a; 1 begin 2 a:=20; 4 +a; 8 8 write(a); 11 end. 0 jmp 0 1 1 ini 0 4 2 lit 0 20 3 sto 0 3 4 lod 0 3 5 lit 0 1 6 opr 0 2 7 sto 0 3 8 lod 0 3 9 opr 0 14 10 opr 0 15 11 o

24、pr 0 0- run pl0 - 21- end pl0 -測試的用例為:program test;var a;begin a:=20; -a; write(a);end.編譯代碼為:= compile pl0 = 0 program test; 0 var a; 1 begin 2 a:=20; 4 -a; 8 8 write(a); 11 end. 0 jmp 0 1 1 ini 0 4 2 lit 0 20 3 sto 0 3 4 lod 0 3 5 lit 0 1 6 opr 0 3 7 sto 0 3 8 lod 0 3 9 opr 0 14 10 opr 0 15 11 opr

25、0 0- run pl0 - 19- end pl0 -25測試char的用例為:program ex01;char a;begina:=w;write(a);end.運行結(jié)果:- run pl0 - 87- end pl0 - 測試不等號用例為:program test;var a,b,c;begin a:=88; read(b); if abthen begin a-=2; write(a); endend.運行結(jié)果:- run pl0 - ? 3686- end pl0 測試else用例為:program ex01;var a,b,c;begin a:=88; read(b); c:=a

26、+b*(3+b); c -= a ; write(c); if ab then begin write(a); end else begin write(a); end;end.編譯代碼為:= compile pl0 = 0 program ex01; 0 var a,b,c; 1 begin 2 a:=88; 4 read(b); 6 c:=a+b*(3+b); 14 c -= a ; 18 write(c); 21 if ab then 24 begin 25 write(a); 28 end 28 else 29 begin 29 write(a); 32 end; 32 end. 0

27、jmp 0 1 1 ini 0 6 2 lit 0 88 3 sto 0 3 4 opr 0 16 5 sto 0 4 6 lod 0 3 7 lod 0 4 8 lit 0 3 9 lod 0 4 10 opr 0 2 11 opr 0 4 12 opr 0 2 13 sto 0 5 14 lod 0 5 15 lod 0 3 16 opr 0 3 17 sto 0 5 18 lod 0 5 19 opr 0 14 20 opr 0 15 21 lod 0 3 22 lod 0 4 23 opr 0 9 24 jpc 0 29 25 lod 0 3 26 opr 0 14 27 opr 0

28、15 28 jmp 0 32 29 lod 0 3 30 opr 0 14 31 opr 0 15 32 opr 0 0- run pl0 - ? 44206888- end pl0 -六、開發(fā)過程和完成情況1.總述設(shè)計最后完成情況是完成了基本要求和選做要求的增加運算:+ 和 以及增加類型中的字符類型的添加。下面將對開發(fā)的過程的思路和方法說明一下。設(shè)計過程中添加保留字、運算符號都要對全局變量進(jìn)行相關(guān)的修改。(修改部分用粗體字標(biāo)識出來)設(shè)計增加了的4個保留字,因而const norw = 19; 接下來添加修改語法詞匯表:typedef enum procsym, progsym,elsesym

29、,forsym, tosym,downtosym,plusbecomes,minusbecomes,quot,doubleplus,doubleminus,charsym, symbol;char *symout=procsym, progsym ,elsesym,forsym,tosym,downtosym,plusbecomes,minusbecoms,doubleplus,”doubleminus”,”charsym”,”quot”;相應(yīng)的與字符表個數(shù)有關(guān)的所有程序都要修改,一共加了6個單詞,例如:symset symsetnull() symset s; int i,n,k; s=(s

30、ymset)malloc(sizeof(int)* numofsybol); for (i=0; i numofsybol; i+) si=0; return s;其余symsetunion ,symsetadd, symsetnew ,symsetnull都要相應(yīng)修改其中,numofsybol43 執(zhí)行編譯按鈕程序也要相應(yīng)的修改,添加如下:strcpy(kword 1,begin); strcpy(kword 2,call); strcpy(kword 3,char); strcpy(kword 4,const); strcpy(kword 5,do); strcpy(kword 6,dow

31、nto); strcpy(kword 7,else); strcpy(kword 8,end); strcpy(kword 9,for); strcpy(kword10,if); strcpy(kword11,odd); strcpy(kword12,procedure);strcpy(kword13,program); strcpy(kword14,read); strcpy(kword15,then); strcpy(kword16,to); strcpy(kword17,var); strcpy(kword18,while); strcpy(kword19,write); /查保留字用的

32、是二分法,所以保留必須按順序添加 wsym 1=beginsym; wsym 2=callsym; wsym 3=charsym; wsym 4=constsym; wsym 5=dosym; wsym 6=downtosym; wsym 7=elsesym; wsym 8=endsym; wsym 9=forsym; wsym10=ifsym; wsym11=oddsym; wsym12=procsym; wsym13=progsym; wsym14=readsym; wsym15=thensym; wsym16=tosym; wsym17=varsym; wsym18=whilesym;

33、wsym19=writesym;/保留字內(nèi)碼表示也應(yīng)該按順序添加 把ssym+=plus; ssym-=minus; ssym#=neq;刪掉 declbegsys=(int*)malloc(sizeof(int)* numofsybol); statbegsys=(int*)malloc(sizeof(int)* numofsybol); facbegsys =(int*)malloc(sizeof(int)* numofsybol); for(int j=0; jnumofsybol; j+) declbegsysj=0; statbegsysj=0; facbegsysj =0; 2.具

34、體添加的代碼把不等號的形式”#”改成”首先將“#”的內(nèi)碼表示ssym#=neq刪除,然后在getsym添加識別的“”的程序段就可以了。添加如下:void getsym() else if (ch=) sym=neq; getch(); /不等于由改為 else sym=lss; /*getsym()*/ 增加保留字else然后語法分析圖如下:賦值表達(dá)式語句else語句thenif語句 其跳轉(zhuǎn)圖修改的地方如下:(a)添加else到詞匯表作為保留字,再上面介紹了。(b)在語句處理子程序void statement(symset fsys,int lev,int &tx) 里修改。void stat

35、ement(symset fsys,int lev,int &tx) int i,cx1,cx2,; switch (sym) case ifsym: getsym();condition(symsetunion(symsetnew(thensym,dosym),fsys),lev,tx);if (sym=thensym) getsym();else error(16);cx1=cx; gen(jpc,0,0);/條件不滿足跳出thenstatement(symsetunion(symsetnew(elsesym),fsys),lev,tx);/加入elsesym到符號集合,用于糾錯 if(s

36、ym!=elsesym)codecx1.a=cx;/無else語句 else /有else語句 getsym(); cx2=cx;gen(jmp,0,0);/else不滿足條件跳出 codecx1.a=cx;/回填jpc的跳轉(zhuǎn)地址 statement(fsys,lev,tx); codecx2.a=cx;/回填jmp的跳轉(zhuǎn)地址 break;. /*statement*/增加賦值運算符+=,-=以及+,-(a) 首先給這四個運算符命名,分別命為plusbecomes,minusbecomes,和doubleplus, doubleminus以便讀單詞時填寫符號表。分析+=、-=、+、-,當(dāng)遇到+

37、=時,根據(jù)table表中的c的地址把c的值放在棧頂,再把棧頂元素和次棧頂元素相加,然后保存c的值。 -=的原理與+=相同。當(dāng)遇到+時,根據(jù)table表中的c地址把c的值放在棧頂,再把棧頂元素和次棧頂元素相加,然后保存c的值。-的原理與+相同。 (b)在pl/0程序中的修改如下: 詞法分析getsym中添加:void getsym() else if(ch=+)/處理以+開頭的getch( );if (ch=) sym=plusbecomes; getch(); else if(ch=+) sym=doubleplus; getch(); else sym=plus; else if(ch=-)

38、/處理以-開頭的 getch(); if (ch=) sym=minusbecomes; getch(); else if(ch=-) sym=doubleminus; getch(); else sym=minus; else if(ch=)sym=quot;getch(); else sym=ssymch; getch(); /*getsym()*/語句分析statement中添加/以下擴展-=,+=,+,-, if(sym=becomes|sym=plusbecomes|sym=minusbecomes) if(sym=plusbecomes|sym=minusbecomes) if(i

39、!=0) gen(lod,lev-tablei.vp.level,tablei.vp.adr); sym1=sym; getsym(); if(sym=quot) getsym(); if(sym=ident) count=id0; if (i!=0) gen(lit,0,count);/將字符當(dāng)作整型來處理 gen(sto,lev-tablei.vp.level,tablei.vp.adr); /sto l a 將棧頂內(nèi)容送入某一變量單元中,a為偏移量,l為層差 getsym(); if(sym=quot) getsym(); else error(27); else expression(

40、fsys,lev,tx); if(sym1=plusbecomes) gen(opr,0,2);/+= else if(sym1=minusbecomes) gen(opr,0,3);/-= if(i!=0) gen(sto,lev-tablei.vp.level,tablei.vp.adr); else if(sym=doubleplus|sym=doubleminus) if(i!=0) gen(lod,lev-tablei.vp.level,tablei.vp.adr); gen(lit,0,1); if(sym=doubleplus) gen(opr,0,2); else if(sym

41、=doubleminus) gen(opr,0,3); gen(sto,lev-tablei.vp.level,tablei.vp.adr); getsym(); else error(13); break;/開始前+ .如+x,-x等等- case doubleplus: getsym(); i=position(id,tx); /tx:符號表的下標(biāo)變量,在符號表中返回符號id的位置 if (i=0) error(11); /標(biāo)識符未說明 else if (tablei.kind!=variable) /對比類型屬性是否為變量 error(12); i=0; /賦值語句中,賦值號左部標(biāo)識符屬

42、性應(yīng)是變量 if(i!=0) gen(lod,lev-tablei.vp.level,tablei.vp.adr); gen(lit,0,1); gen(opr,0,2); gen(sto,lev-tablei.vp.level,tablei.vp.adr); getsym(); break; case doubleminus: getsym(); i=position(id,tx); /tx:符號表的下標(biāo)變量,在符號表中返回符號id的位置 if (i=0) error(11); /標(biāo)識符未說明else if (tablei.kind!=variable) /對比類型屬性是否為變量 error(12); i=0; /賦值語句中,賦值號左部標(biāo)識符屬性應(yīng)是變量 if(i!=0) gen(lod,lev-tablei.vp.level,tabl

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論