編譯原理課程設(shè)計--編譯器_第1頁
已閱讀1頁,還剩22頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、<p>  編譯原理課程設(shè)計報告</p><p>  學(xué) 院: 計算機與信息工程學(xué)院 </p><p>  專業(yè)年級: 2008軟件工程 </p><p>  學(xué)生姓名: </p><p>  學(xué) 號:

2、 </p><p>  課程名稱: 編譯原理課程設(shè)計 </p><p>  指導(dǎo)教師: </p><p>  教研室負(fù)責(zé)人: </p><p>  完成日期:2011年4月</p><p>

3、;<b>  目錄</b></p><p><b>  1 問題的提出1</b></p><p><b>  2 報告主體1</b></p><p>  2.1 設(shè)計目的:1</p><p>  2.2設(shè)計內(nèi)容及要求:1</p><p>  2

4、.2.1 設(shè)計符號表1</p><p>  2.2.2 設(shè)計詞法分析器1</p><p>  2.2.3 語法分析與中間代碼產(chǎn)生器2</p><p>  2.2.4 優(yōu)化器(選做)2</p><p>  2.2.5目標(biāo)代碼生成器(選做)2</p><p>  2.2.6 測試范例:2</p>

5、<p>  2.3 實現(xiàn)原理3</p><p>  2.3.1 符號表的設(shè)計3</p><p>  2.3.2 詞法分析器的設(shè)計4</p><p>  2.3.3 語法/語義分析5</p><p>  2.5 測試數(shù)據(jù)17</p><p>  2.6結(jié)果輸出及分析19</p><

6、;p>  2.7 軟件運行環(huán)境及限制28</p><p>  2.8 心得體會29</p><p>  2.9參考文獻(xiàn)30</p><p><b>  3 結(jié)論30</b></p><p><b>  1 問題的提出</b></p><p>  在網(wǎng)絡(luò)世界中,我

7、們往往對功能強大的程序嘆為觀止。而這些強大程序的背后是編譯這些程序的編譯軟件,是這些編譯軟件承托起了這些功能強大的運行程序。我們有不少的同志致其自身于無盡的運行程序上。而只有很少的人搞編譯程序。這就是為什么中國的可運行程序滿天飛,而編譯程序卻很少。本課程設(shè)計就是在這方面的探索,為你解讀編譯程序的奧秘。</p><p>  課程設(shè)計題目選擇9個題目中的一個,要求根據(jù)自己的興趣和能力,選擇一個對自己意義甚大的題目。課

8、程設(shè)計基本原理是在實踐上,實現(xiàn)我們在課程上學(xué)習(xí)到的理論知識。通過理論聯(lián)系實踐,更好的掌握課本上的理論知識。</p><p><b>  2 報告主體</b></p><p>  2.1 設(shè)計目的:</p><p>  本次課程設(shè)計是作一個集詞法分析、語法分析、語義分析和中間代碼生成于一體的編譯器,它集中了《編譯原理》里的幾乎所有的思想。不但加

9、深了學(xué)生對編譯方法的理解,而且能對學(xué)生的編程能力起到進(jìn)一步提高的作用,培養(yǎng)學(xué)生的程序設(shè)計風(fēng)格。通過某種可視化編程語言的應(yīng)用,具備初步的Windows環(huán)境下的編程思想。</p><p>  2.2設(shè)計內(nèi)容及要求:</p><p>  2.2.1 設(shè)計符號表</p><p>  確定符號表的組織方式,一般應(yīng)包括名字欄和信息欄,其中名字欄作為關(guān)鍵字。要考慮能夠存儲有關(guān)名字

10、的信息,并可以高效地完成如下操作:</p><p>  1.查找:根據(jù)給定的名字,在符號表中查找其信息。如果該名字在符號表中不存在,則將其加入到符號表中,否則返回指向該名字的指針;</p><p>  2.刪除:從符號表中刪除給定名字的表項。</p><p>  2.2.2 設(shè)計詞法分析器</p><p>  設(shè)計各單詞的狀態(tài)轉(zhuǎn)換圖,并為不同

11、的單詞設(shè)計種別碼。將詞法分析器設(shè)計成供語法分析器調(diào)用的子程序。功能包括:</p><p>  1. 具備預(yù)處理功能。將不翻譯的注釋等符號先濾掉,只保留要翻譯的符號串,即要求設(shè)計一個供詞法分析調(diào)用的預(yù)處理子程序;</p><p>  2. 能夠拼出語言中的各個單詞;</p><p>  3. 將拼出的標(biāo)識符填入符號表;</p>

12、<p>  4. 返回(種別碼, 屬性值)。</p><p>  2.2.3 語法分析與中間代碼產(chǎn)生器</p><p>  要求用LL1 、遞歸下降、算符優(yōu)先分析法、SLR分析法等方法之一或若干方法,實現(xiàn)對表達(dá)式、各種說明語句、控制語句進(jìn)行語法分析。</p><p>  若語法正確,則用語法制導(dǎo)翻譯法進(jìn)行語義翻譯:對說明語句,要求將說明的各符

13、號記錄到相應(yīng)符號表中;對可執(zhí)行語句,應(yīng)產(chǎn)生出四元式中間代碼并填寫到三地址碼表中;</p><p>  若語法錯誤,要求指出出錯性質(zhì)和出錯位置(行號)。出錯處理應(yīng)設(shè)計成一個出錯處理子程序</p><p><b>  2.2.4 優(yōu)化器</b></p><p>  1. 局部優(yōu)化:設(shè)計出劃分基本塊的算法,在每一個基本塊中實現(xiàn):合并已知量、

14、刪除多余運算和刪除無用賦值三種局部優(yōu)化。設(shè)計構(gòu)造基本塊的DAG圖的算法,以及將DAG圖還原實現(xiàn)基本塊的優(yōu)化的算法。</p><p>  2. 循環(huán)優(yōu)化:只做一重循環(huán)優(yōu)化,完成代碼外提,強度削弱和刪除歸納變量等三種優(yōu)化。要求實現(xiàn)while循環(huán)和for循環(huán)語句的優(yōu)化。</p><p>  2.2.5目標(biāo)代碼生成器</p><p>  能完成指定寄存器個數(shù)的情況

15、下將一中間代碼程序段翻譯成匯編語言目標(biāo)代碼(匯編指令應(yīng)包括加、減、乘、除),要求指令條數(shù)最少的情況下,盡量使用寄存器,盡量少訪問內(nèi)存,這樣才能做到運行效率高。</p><p>  2.2.6 測試范例:</p><p>  procedure test;</p><p>  varb,c,i:integer;</p><p><b&g

16、t;  begin</b></p><p><b>  b:=1;</b></p><p>  if a>b then</p><p><b>  c:=a+b</b></p><p><b>  else</b></p><p>&l

17、t;b>  c:=a-b;</b></p><p>  for i:=0 to 3 do</p><p><b>  begin</b></p><p><b>  c:=i;</b></p><p><b>  end; </b></p>&l

18、t;p><b>  end;</b></p><p><b>  2.3 實現(xiàn)原理</b></p><p>  2.3.1 符號表的設(shè)計</p><p><b>  1.符號表的結(jié)構(gòu)</b></p><p>  class Symbol</p><p&

19、gt;<b>  { </b></p><p>  public WordName name;</p><p>  public StringBuffer type;</p><p>  public StringBuffer kind;</p><p>  public StringBuffer val;</

20、p><p>  public int addr;</p><p>  public Symbol()</p><p>  { name=new WordName();</p><p>  type=new StringBuffer();</p><p>  kind=new StringBuffer();</p&g

21、t;<p>  val= new StringBuffer();</p><p><b>  }</b></p><p><b>  }</b></p><p>  符號表的每一項是symbol類的一個對象,即符號表是symbol類的對象數(shù)組。其中WordName 又是一個類,它對應(yīng)名字欄,它有兩個屬性sta

22、rt和length,分別存放標(biāo)志符在字符串中的起始地址和長度。type、kind、val和addr分別對應(yīng)符號表中的其他四項,它們共同組成信息欄。</p><p>  class WordName</p><p><b>  {</b></p><p>  public int start;</p><p>  publ

23、ic int length;</p><p><b>  }</b></p><p><b>  2.查找</b></p><p>  當(dāng)前字符串的長度就是將要入字符串的標(biāo)志符的起始位置,即名字欄中的start,標(biāo)志符的長度對應(yīng)名字欄中的length,varCount是符號表的即將生成的符號表項的下標(biāo),碰到一個標(biāo)志符,如t

24、est,我們就在符號表中從頭到尾循環(huán),利用名字欄中的start和length從字符串(StringBuffer類型的一個對象alphabet)中取出其對應(yīng)得標(biāo)志符,看它是否為test,如果符號表中有test,就返回循環(huán)是所用的計數(shù)器i,沒有就返回-1;從字符串中取自字符串的方法是</p><p>  alphabet.substring(symbolList[i].name.start,symbolList[i]

25、.name.start+symbolList[i].name.length,用方法equals()來判斷其是否一樣。實現(xiàn)此功能的是wordExist()。</p><p>  程序中出現(xiàn)的數(shù)字,也要查符號表,看其是否在符號表中存在,在符號表中從頭到尾查找,如果start和length都為零,而且val值和當(dāng)前數(shù)字相同,就返回循環(huán)計數(shù)器i,如果沒有找到滿足條件的,就返回-1;實現(xiàn)此功能的方法(即函數(shù))是number

26、Exist().</p><p>  2.3.2 詞法分析器的設(shè)計</p><p>  1.處理標(biāo)志符或關(guān)鍵字:</p><p>  把剛才的字母保存在currentToken的name變量中,接著讀入下一個字符,這個字符如果是字母或下劃線,則將其繼續(xù)追加在name變量中,如此循環(huán)直到碰到其他字符。這樣就把程序中一個連續(xù)的字符串保存在一個變量中,接著判斷這個字符串是

27、不是關(guān)鍵字,依次與keyWord數(shù)組的關(guān)鍵字比較,循環(huán)計數(shù)器i就是keyWord[i]的種別碼。如果是關(guān)鍵字則將currentToken的code置為i,address置為-1。如果不是關(guān)鍵字,則查找符號表,如果wordExist()函數(shù)返回的是-1,則表示符號表中還沒有此標(biāo)志符,將address置為addrCount,否則將address置為wordExist()的返回值。然后調(diào)用outPut()函數(shù)。outPut()函數(shù)的功能是輸出

28、token串,并將token串填入數(shù)組,如果它在符號表中不存在,則還要將其填在符號表中。清空currentToken中各個屬性的值。</p><p><b>  2. 處理數(shù)字:</b></p><p>  用循環(huán)將數(shù)字保存在currentToken的name變量中,直到碰到小數(shù)點或其他字符,如果碰到了小數(shù)點,我們將標(biāo)志flag置成1,表明這可能是一個小數(shù)。這時需要判

29、斷下一個是否是字母,如果是字母,則丟棄接下來的字母和數(shù)字,只保留前面的數(shù)字。如果是小數(shù)點造成的循環(huán)結(jié)束,則再讀入一個字符,如果這個字符是數(shù)字,則將剛才的小數(shù)點保存起來,否則給出小數(shù)點后出錯的提示。在這個字符是數(shù)字的情況下,將這個數(shù)字以及后面的數(shù)字保存起來。循環(huán)結(jié)束后,我們將其編碼為36(實數(shù)),造成這次循環(huán)結(jié)束的仍然可能是小數(shù)點或字母,不管是哪一種情況,都要丟掉后面的字母和數(shù)字。如果第一次循環(huán)不是小數(shù)點造成的,我們將其編碼35(整數(shù))。

30、接下來考慮的入口地址,為了防止造成符號表的空間的浪費,我們從符號表中查找有沒有這個數(shù)字的記錄。如果有,返回的入口地址就是這個數(shù)字的屬性值。此時,這個數(shù)字的token串已經(jīng)完成。最后調(diào)用outPut()函數(shù)輸出并保存token串,并根據(jù)是否在已符號表中而填入符號表。</p><p>  3. 處理注釋和除號:</p><p>  在字符為 / 時,我們調(diào)用此程序。我們在讀入下一個字符,如果這

31、個字符是 * ,這表示后面是注釋,用循環(huán)讀入后面的字符,如果碰到 * ,表示注釋將要結(jié)束,下一個字符應(yīng)該是 / ,如果不是 / ,則注釋出錯。而如果 / 后面的字符不是 * ,則 / 當(dāng)作除號處理,將 / 保存到currentToken的name中,屬性值設(shè)置為48,調(diào)用outPut()函數(shù)。</p><p>  4. 處理字符常數(shù):</p><p>  在字符為 ‘ 時我們調(diào)用此程序,用

32、循環(huán)繼續(xù)讀入后面的字符,碰到 ’時結(jié)束。設(shè)置種別碼為37,查找符號表是否已經(jīng)有了該字符常數(shù)的記錄,如果有,將其屬性值設(shè)置為返回的入口地址。如果沒有,將其屬性值設(shè)置為addrCount(符號表的記錄的計數(shù)器),同時將addrCount加一。</p><p>  5. 處理其他字符:</p><p>  用switch()對每一種字符進(jìn)行匹配,不同的字符給于不同的編碼,入口地址均為 -1。調(diào)用

33、outPut()輸出和保存token串,然后獲得下一個字符。</p><p>  2.3.3 語法/語義分析</p><p>  此處是將語法分析和語義分析和在一起進(jìn)行的。由于詞法分析已經(jīng)將符號表和token串保存在數(shù)組中了,語法和語義分析時將tokenList數(shù)組中一個一個的調(diào)出token來分析,并根據(jù)需要修改存在symbolList數(shù)組的符號表。</p><p>

34、;  首先第一個token應(yīng)該是procedure(21,_)或program(22,_ ),第二個token應(yīng)該是標(biāo)志符(34,0),第三個token應(yīng)該是分號(52,_),此時應(yīng)該將行計數(shù)器lineOfPro加一,下一個token應(yīng)該是var(31,_),然后進(jìn)入說明語句分析的循環(huán),declare()方法(函數(shù))將會分析一行說明語句,因為說明語句可能多行,所以采用循環(huán)調(diào)用的declare()的方法。說明語句分析完,然后進(jìn)行可執(zhí)行語句

35、的分析,beginAnalyse()將完成此功能,遇到錯誤它將返回 –1。</p><p><b>  說明語句的分析:</b></p><p>  首先,將說明語句的符號按照出現(xiàn)的先后順序入棧,如 a,b,c:integer;將三個字母、兩個逗號、一個分號、integer和一個分號按照a、,、b、,、c、:、integer、;的順序壓入堆棧,然后從左向右掃描,碰到標(biāo)

36、識符跳過,碰到逗號跳過,碰到冒號表明說明語句即將結(jié)束,用switch()語句對冒號之后的那個字符進(jìn)行匹配,根據(jù)這個字符是char、 integer、bool 、real中的哪一個來將前面變量再符號表中信息欄的kind和type置成不同的值。完成此項任務(wù)后,移動指針,此時指針應(yīng)該指向分號,如果是分號則成功返回,不是分號給出錯誤。</p><p>  說明語句后緊接的是以begin開頭的賦值語句、布爾表達(dá)式語句、if

37、語句、while語句、repeat語句以及for語句,下面將一一加以介紹。</p><p>  2. 賦值語句(包括算術(shù)表達(dá)式)的分析:</p><p>  當(dāng)當(dāng)前的token為標(biāo)識符時,表示這是賦值語句的開始。下一個token應(yīng)該是 := ,如果不是將指出賦值語句出錯。然后調(diào)用函數(shù)exprAnalize()。在exprAnalize()中,首先將 := 后的表達(dá)式按順序入棧(由exprI

38、nit()函數(shù)完成)。然后進(jìn)入處理加減的函數(shù)mayAddSub(),由于乘除的優(yōu)先級大于加減,所以在mayAddSub()中首先調(diào)用mayMulDiv()來處理乘除,在mayMulDiv()中首先要調(diào)用mayNumber(),mayNumber()返回當(dāng)前標(biāo)識符的入口地址(如果當(dāng)前token為標(biāo)識符),在mayNumber()中還要對當(dāng)前的token是否為(39,_)即 ( 做出判斷,如果是則采用深度調(diào)用方法,即再次調(diào)用mayAddSu

39、b()處理擴號內(nèi)的算術(shù)表達(dá)式。此入口地址應(yīng)該作為生成的四元式的第一個操作數(shù),在這里我們暫且認(rèn)為四元式的后兩個或三個數(shù)是入口地址,如(+,a,b,T1),我們可以理解為(+,a的入口地址,b的入口地址,T1)。又如(:=,4,_,a)理解為(:=,4的入口地址,_, a的入口地址)。再如(jnz,A,_,10)理解為(jnz,</p><p>  3. If語句的分析(包含布爾表達(dá)式的分析):</p>

40、<p>  首先將 if 和 then 之間的布爾表達(dá)式按出現(xiàn)的先后順序入棧,把即將生成的四元式的序號(也就是由 if 語句生成的第一個四元式的序號)保存起來,以便最后將其返回。調(diào)用boolAnalize()進(jìn)行布爾表達(dá)式的分析。boolAnalize()首先調(diào)用mayOr(),mayOr()首先調(diào)用mayAnd(),而mayAnd ()首先調(diào)用isNot() ,在isNot()中,判斷當(dāng)前token是否對應(yīng) not ,若

41、為 not 則取下一個token并調(diào)用genCode()后交換真出口地址和假出口地址,否則直接調(diào)用genCode().函數(shù)genCode()的作用是規(guī)約,生成四元式。在生成四元式之前,需要判斷是不是關(guān)系式,即當(dāng)前token的下一個token對應(yīng)的是不是>、>= 、<>、 =、 <=、 <,如果是則在isRelationalExpression()中生成四元式,否則isRelationalExpress

42、ion()返回1之后在genCode()生成四元式,返回到isNot() ,再向上返回到mayAnd (),再調(diào)用isAnd (),檢測下一個token是否為 and ,如果是 an</p><p>  以假出口數(shù)組為例,falseLine指向最后一個假出口的下一項,falseAddress[falseLine-1]和falseAddress[falseLine-2]是最后兩個假地址,并鏈實際上就是將falseA

43、ddress[falseLine-1]所指向的四元式的第四項存放falseAddress[falseLine-2],然后刪除falseAddress[falseLine-2].代碼如下:</p><p>  Equ[falseAddress[falseLine-1]].result=falseAddress[falseLine-2];</p><p>  falseAddress[fals

44、eLine-2]=falseAddress[falseLine-1];</p><p>  falseAddress[falseLine-1]=0;</p><p>  falseLine--;</p><p>  如果下一個token還對應(yīng) and ,則遞歸調(diào)用isAnd().否則返回mayAnd(),再返回mayOr()。由mayOr()調(diào)用isOr()來判斷下

45、一個token是否對應(yīng) or ,如果是 or ,則回填假出口。為了區(qū)分時回填真出口還是回填假出口,在backPatch(int addr2,int flag)用第二個參數(shù)來區(qū)分,flag為 0 表示回填假出口,flag為1表示回填真出口?;靥畹脑砣缦拢河捎谠谏刹紶柋磉_(dá)式的四元式時,第四項都是-1000,這是一個標(biāo)志,表示回填的鏈已經(jīng)到了盡頭。只要不是-1000,我們就將第四項所指向的四元式回填?;靥罴俪隹谥?,調(diào)用mayAnd()進(jìn)

46、行其他表達(dá)式的分析。mayAnd()返回之后,如果trueLine大于1,表明有兩個以上的真出口,調(diào)用trueMerge()實現(xiàn)真出口的并鏈。如果下一個token對應(yīng) or ,則遞歸調(diào)用isOr(),否則返回mayOr(),這時布爾表達(dá)式可能已經(jīng)分析完,也有可能下一個token對應(yīng) ) ,對于后一種情況,調(diào)用boolAnalize()的是genCode(),所以您不用擔(dān)心碰到括號就無法分析了。</p><p> 

47、 在布爾表達(dá)式分析完成后,下一個token對應(yīng)得應(yīng)該是 then ,下面的就有可能是 if 語句、repeat語句、while語句、for語句、賦值及算術(shù)表達(dá)式語句 ,還有可能是begin開始的語句,因此需要調(diào)用其他函數(shù),這些函數(shù)返回的將是由這些語句生成的第一個四元式的序號。用這個序號回填 if 和 then 之間的布爾表達(dá)式的真出口。如果下一個token對應(yīng)else,那末應(yīng)該生成一個無條件跳轉(zhuǎn)四元式,我們暫且保存這個四元式的序號,并不

48、將它存放在真出口數(shù)組或假出口數(shù)組。調(diào)用相應(yīng)得函數(shù)分析else之后的語句,這些函數(shù)返回的將是else之后的語句產(chǎn)生的第一個四元式的序號,我們用這個序號回填布爾表達(dá)式的假出口。然后用lineOfEqu回填剛才的無條件跳轉(zhuǎn)四元式。如果這個 if 語句是嵌套在 for 循環(huán)中的,需要用另一個值回填,下面另作討論。</p><p>  4. while語句的分析:</p><p>  若當(dāng)前的to

49、ken對應(yīng)while,保存即將生成的四元式的序號,然后調(diào)用boolAnalize()分析布爾表達(dá)式, 下一個token應(yīng)該對應(yīng) do , do 后面的語句可能是各種語句,應(yīng)該調(diào)用相應(yīng)的程序來分析,用這些函數(shù)的返回值回填 while 和 do 之間的布爾表達(dá)式的真出口,然后生成一個無條件跳轉(zhuǎn)語句,跳向由這個 while – do循環(huán)所生成的第一個四元式,然后用lineOfEqu回填布爾表達(dá)式的假出口。即讓它跳出循環(huán)。</p>

50、<p>  5. for語句的分析:</p><p>  首先調(diào)用賦值語句分析函數(shù)startEvaluate()分析 for 和 to之間的賦值語句,這個賦值語句隨后會產(chǎn)生一個四元式(:=,op1,_,循環(huán)變量),我們調(diào)用newTemp()生成兩個隨即變量,將op1的值賦給變量t1,即生成一個四元式(:=,op1,_,t1).如果下一個token對應(yīng)to ,則將to 和 do 之間的數(shù)值賦給t2,然

51、后生成一個無條件跳轉(zhuǎn)四元式,調(diào)到下一個的下一個,然后生成t1 加 1 的四元式,再生成一個比較四元式,(j>.t1,t2,-1000)將此四元式的序號保存在jumpFor中,然后下一個token應(yīng)該對應(yīng)begin,否則給出錯誤。根據(jù)調(diào)用相應(yīng)得函數(shù)分析begin 和 end 之間語句。然后生成一個無條件跳轉(zhuǎn)四元式,調(diào)到將 t1 加 1的四元式,如果for中嵌套一個 if-then-else 語句,則 if語句的無條件跳轉(zhuǎn)語句也應(yīng)該跳

52、轉(zhuǎn)到 t1 加 1的四元式。然后將剛才的比較四元式的第四項設(shè)置為lineOfEqu,以跳出 for 循環(huán)。</p><p>  6. repeat 語句的分析:</p><p>  首先調(diào)用startEvaluate()、startIf() 、startWhile()、startFor() 、beginAnalyse()或調(diào)用自身分析 repeat 和 until 之間的語句,將返回地址

53、保存在rtn中。然后調(diào)用boolAnalize()分析布爾表達(dá)式,用linbeOfEqu回填布爾表達(dá)式的真出口,用rtn回填布爾表達(dá)式的假出口。</p><p><b>  2.5 測試數(shù)據(jù)</b></p><p>  1. test1.java 文件</p><p>  procedure test;</p><p>

54、;  var a,b,max:integer;</p><p><b>  begin</b></p><p>  a:=9; /*賦值語句*/</p><p><b>  b:=10;</b></p><p>  if a>b then max:=a else max:=b; /*if語句*

55、/</p><p><b>  end.</b></p><p>  /*賦值語句與if語句*/</p><p>  test2.java文件</p><p>  procedure test;</p><p>  var a,b,i:integer;</p><p>&l

56、t;b>  begin</b></p><p>  a:=10; /*賦值語句*/</p><p><b>  b:=100;</b></p><p>  for i:=0 to 10 do </p><p>  a:=a+b; /*for循環(huán)語句*/</p><p

57、><b>  end.</b></p><p>  /*賦值語句和for循環(huán)語句*/</p><p>  test3.java文件</p><p>  procedure test;</p><p>  var a,b,c,d:integer;</p><p><b>  begi

58、n</b></p><p>  a:=8; /*賦值語句*/</p><p><b>  b:=9;</b></p><p>  c:=(a+b)*(a-b); /*算術(shù)表達(dá)式*/</p><p>  d:=a+a*b*c/(a-b);</p><p><b>  e

59、nd.</b></p><p>  /*賦值語句和算術(shù)表達(dá)式*/</p><p>  test4.java文件</p><p>  procedure test;</p><p>  var a,b,c :integer;</p><p><b>  begin</b></p&g

60、t;<p>  a:=0; /*賦值語句*/</p><p><b>  b:=10;</b></p><p>  while a<b do a:=a+1; /*while語句*/</p><p>  repeat a:=a+1; until a>b; /*repeat語句*/</p><p>

61、;<b>  end.</b></p><p>  /*賦值語句、while語句、repeat語句*/</p><p>  test5.java文件</p><p>  procedure test;</p><p>  varb,c,i:integer;</p><p><b>  

62、begin</b></p><p><b>  b:=1;</b></p><p>  if a>b then</p><p><b>  c:=a+b</b></p><p><b>  else</b></p><p><b&

63、gt;  c:=a-b;</b></p><p>  for i:=0 to 3 do</p><p><b>  begin</b></p><p><b>  c:=i;</b></p><p><b>  end; </b></p><p&

64、gt;<b>  end;</b></p><p>  test6.java文件</p><p>  procedure test;</p><p>  var a,b,c:integer;</p><p>  var A,B:bool;</p><p><b>  begin <

65、/b></p><p><b>  a:=4;</b></p><p><b>  b:=5;</b></p><p>  A:=false; /*布爾表達(dá)式的賦值語句*/</p><p><b>  B:=true;</b></p><p>  

66、if A and B then </p><p><b>  c:=a+b</b></p><p><b>  else</b></p><p>  c:=a*b; </p><p><b>  end;</b></p><p>  /*布爾表

67、達(dá)式和if語句的分析*/</p><p>  2.6結(jié)果輸出及分析</p><p>  圖(2.6-1)test1.java 詞法分析的結(jié)果</p><p>  程序中有test、a、b和max四個標(biāo)志符,我們可以看到它們按照先后順序出現(xiàn)在字符串中,它們在字符串中的起始地址和長度如圖所示都正確(注意:字符串第一個位值是0)。但它們的類型還不知道。雖然原程序中多次出現(xiàn)

68、標(biāo)識符a和b以及max,但符號表中對每個標(biāo)識符只有一條記錄,當(dāng)詞法分析程序檢測到符號表中已經(jīng)有了a或b的記錄后,并沒有再次將a或b加到符號表里,程序有兩個數(shù)字,他們被加到符號表中。種類和類型都被填到了符號表中。每個字符以及所生成的token如圖右下框所示,也正確。</p><p>  圖(2.6-2)test1.java 語法/語義的結(jié)果 </p><p>  語法/語義分析之后,a、b和

69、max都知道是整型簡變,程序完成了符號表的修改,在分析完賦值語句后,a和b的值都知道了,程序用9和10分別修改了a和b的信息欄的val值。兩個賦值語句的四元式如圖右下框的0號和1號四元式。接下來的if-then-else語句,首先生成比較四元式2(j>,a,b,-0)和3(j,_,_,0),此時真假出口都不知道。分析完then后,賦值語句分析函數(shù)返回了這個賦值語句的首個四元式序號即4,此時用4回填真出口。因為else的存在,需要生

70、成一個無條件跳轉(zhuǎn)四元式5(j,_,_,0),賦值語句分析函數(shù)分析else之后的語句,他返回了這個語句所生成的首個四元式的序號即6,此時用6回填假出口即3(j,_,_,6),然后用7回填else之前的無條件跳轉(zhuǎn)語句即5(j,_,_7).</p><p>  圖(2.6-3)test2.java 詞法分析的結(jié)果</p><p>  原程序中有四個標(biāo)識符test、a、b和i,此法分析程序?qū)⑺鼈儼?/p>

71、順序裝入字符串,起始地址和長度被此法分析程序正確的識別出。每個標(biāo)識符再賦號表中只有一條記錄。程序中出現(xiàn)了四次數(shù)據(jù),但是10出現(xiàn)了倆次,當(dāng)詞法分析程序第二次檢測到10的時候,并沒有將10再次填加到賦號表里。</p><p>  圖(2.6-4)test2.java 語法/語義分析的結(jié)果</p><p>  語法/語義分析程序用10和100修改了標(biāo)志符a和b的val值,并生成了相應(yīng)的四元式,接

72、下來是for循環(huán)語句的分析。首先將賦值語句翻譯成四元式,然后將0賦給變量t1,將10賦給變量t2,接著生成一個跳向t1和t2比較的四元式,跳向的序號是自身的序號再加上2,隨后生成的是將變量t1加1的四元式及剛才所提到的t1和t2比較的四元式。然后是賦值表達(dá)式的分析,將a加上b的結(jié)果存入一個變量,在將這個變量賦給a.最后要生成一個跳轉(zhuǎn)語句,跳向t1和t2比較的四元式,用下一個四元式的序號回填比較四元式的出口。</p><

73、;p>  圖(2.6-5)test3.java 詞法分析的結(jié)果</p><p>  詞法分析程序正確的分析出test、a、b、c和d為四個標(biāo)識符,對于它們的多次出現(xiàn)詞法分析程序保證了符號表中只有它們各自的一跳記錄。8和9是整型簡單變量,詞法分析程序?qū)⑺鼈兗尤敕柋聿⒃O(shè)置了信息欄中的kind和type.</p><p>  圖(2.6-6)test3.java 語法/語義分析的結(jié)果&l

74、t;/p><p>  語法/語義分析程序檢測出a、b、c和d為整型簡單變量,因此修改了它們信息欄的kind和type。對兩個賦值語句分別生成了兩個四元式,并將8和9作為val值修改了a和b所在符號表中的記錄。接下來是賦值表達(dá)式的分析,雖然算術(shù)表達(dá)式中有括號,但這絲毫不能阻擋語法/語義分析程序生成正確的四元式。不信你看,首先將a加b的結(jié)果賦給T1,然后將a減b的結(jié)果賦給T2,在將T1和T2相乘的結(jié)果賦給T3,最后將T3

75、的值賦給c。接下來的賦值表達(dá)式的分析更是不成問題。將a乘b的結(jié)果賦給T4,將T4乘c的結(jié)果賦給T5,將a減b的結(jié)果賦給T6,將T5除以T6的結(jié)果賦給T7,將a加T7的結(jié)果賦給T8,將T8的值賦給d。怎么樣,本程序沒有辜負(fù)您的重托吧。</p><p>  圖(2.6-7)test4.java 詞法分析的結(jié)果</p><p>  詞法分析程序?qū)est、a、b和c按順序加入字符串,并將每個標(biāo)識

76、符的起始地址和長度填入符號表。還將0、10和1填入符號表并設(shè)置了信息欄的kind和type。詞法分析程序還準(zhǔn)確分析出了每一個關(guān)鍵字和其他字符,準(zhǔn)確輸出了原程序的token串。</p><p>  圖(2.6-8)test4.java 語法/語義分析的結(jié)果</p><p>  語法/語義分析程序檢測出a、b和c 為整型簡單變量,因此修改了它們信息欄的kind和type。對兩個賦值語句分別生成

77、了兩個四元式,并將0和10作為val值修改了a和b所在符號表中的記錄。</p><p>  While語句的分析:首先對條件表達(dá)式分析,生成了兩個四元式2(j,a,b,0)和3(j,_,_,0),此時真假出口都未知。然后進(jìn)行賦值表達(dá)式的分析,將a加1的結(jié)果賦給變量T1,在將T1的值賦給a。賦值表達(dá)式分析函數(shù)返回的是4,用4回填真出口。然后生成無條件跳轉(zhuǎn)語句,跳向條件四元式,然后用下一個四元式的序號7回填加出口。&

78、lt;/p><p>  Repeat語句的分析:首先賦值語句分析函數(shù)生成了兩個四元式即7(+,a,1,T2)和8(:=,T2,_,a) 。然后生成比較四元式,用下一個四元式的序號11回填真出口,并用賦值語句分析函數(shù)返回的首個四元式的序號7回填假出口。</p><p>  圖(2.6-9)test5.java無法通過詞法分析</p><p>  原程序無法通過詞法分析,因

79、為a沒有聲明就使用.在聲明中加上a,詞法分析如下:</p><p>  圖(2.6-10)test5.java 詞法分析的結(jié)果</p><p>  原程序中有5個標(biāo)志符,詞法分析程序?qū)⑺鼈兗尤敕柋?,并按順序?qū)⑺鼈兗尤胱址?。生成的token與程序中字符一一對應(yīng)。token串正確。</p><p>  圖(2.6-11)test5.java 語法/語義分析的結(jié)果&

80、lt;/p><p>  語法/語義分析程序分析出a、b、c和i為整型,程序完成修改符號表的任務(wù),將type設(shè)置為“整”,將kind設(shè)置為“簡變”。對b:=1生成了四元式0(:=,1,_,b),并將符號表中變量b的信息欄的val設(shè)置為1。對a>b生成兩個四元式1 (j>,a,b,0)和2 (j,_,_,0),分析到then,賦值語句分析函數(shù)返回了c:=a+b;的第一個四元式的序號,此時回填真出口1(j>

81、;,a,b,3).因為有else的存在,所以生成了一個無條件跳轉(zhuǎn)語句5(j,_,_0).分析完else后,賦值語句返回了c:=a-b;的第一個四元式的序號。此時回填假出口2(j,_,_6).整個if語句分析完后,回填無條件跳轉(zhuǎn)語句5 (j,_,_,8).此時進(jìn)入for循環(huán)語句的分析,將0賦給i,然后將0賦給一個變量T3, 將3賦給T4, 然后生成一個無條件跳轉(zhuǎn)語句,接著生成一個T3加1的四元式,然后生成比較T3和T4的四元式,隨后生成的

82、是賦值語句c:=i的四元式。最后生成一個無條件跳轉(zhuǎn)語句,跳到T3加1的四元式。再用16回填四元式13 (j>,a,b,16)。</p><p>  圖(2.6-12)test6.java的詞法分析結(jié)果</p><p>  詞法分析程序?qū)est、a、b、c、A和B作為標(biāo)志符填入字符串,并將起始地址和長度填入符號表。將4和5填入符號表,設(shè)置信息欄的kind和type.將關(guān)鍵字其他字符以

83、及標(biāo)識符都生成了token串。完成了詞法分析的任務(wù).</p><p>  圖(2.6-13)test6.java的語法/語義分析結(jié)果</p><p>  語法/語義分析程序檢測出a、b和c是整型,修改符號表,將a、b和c的信息欄的type設(shè)置成“整”,kind設(shè)置為“簡變”。檢測出A和B是布爾變量,因此將A和B的信息欄的type設(shè)置為“布爾”,kind設(shè)置為“簡變”。對兩個整型變量的賦值語

84、句生成了兩個賦值四元式(:=,4,_,a)和(:=,5,_,b),并用4和5作為val值修改了符號表中a和b的信息欄。對兩個布爾型的賦值語句生成了兩個賦值四元式(:=,false,_,A)和(:=,true,_,B),并將A的val的設(shè)置為false,將B的val值設(shè)置為true.</p><p>  If語句的分析:首先是布爾表達(dá)式的分析,對A生成(jnz,A,_,0)和(j,_,_,0)兩個四元式,布爾分析函

85、數(shù)分析B時,生成了兩個四元式(jnz,B,_,0)和(j,_,_,0)并返回了首個四元式的序號6。用6回填A(yù)所生成的四元式的真出口。然后并鏈,即將7號四元式(j,_,_,0)變?yōu)椋╦,_,_,5)。然后分析then后的語句。首先將a加b的結(jié)果賦給T1,再將T1的值賦給c,然后返回這個賦值語句的首個四元式的序號8,用8回填真出口。因為else的存在,需要生成一個無條件跳轉(zhuǎn)四元式10(j,_,_,0).賦值語句分析函數(shù)分析then之后的語句

86、,生成兩個四元式11(*,a,b,T3)和12(:=,T3,_,c),然后返回11,此時回填假出口,即修改5和7號四元式為5(j,_,_11)、7(j,_,_11)。最后用13回填那個無條件跳轉(zhuǎn)四元式即10(j,_,_,13),分析到此完成。</p><p>  2.7 軟件運行環(huán)境及限制</p><p>  操作系統(tǒng)要求Windows98以上。操作過程如下:</p><

87、;p>  安裝jdk1.5(如jdk-1_5_0_09-windows-i586-p.exe),假定安裝目錄為:D:\Program Files\java,安裝完成后,在D:\Program Files\java下有一個文件jdk1.5,在jdk1.5文件中有一個bin文件,將bin文件的完成路徑,即D:\Program Files\java\jdk1.5\bin復(fù)制下來。右擊“我的電腦”,選擇“屬性”,從中選擇“高級”面板,點擊

88、“環(huán)境變量”按鈕,在“系統(tǒng)變量”列表中雙擊Path屬性,將剛才的完整路徑追加到Path原來的值得后面。注意在追加這個完整路徑前需要加上一個分號。依次點擊“確定”、“應(yīng)用”和“確定”。</p><p>  安裝JCreator Pro軟件(推薦JCreator Pro 350漢化版),用此軟件打開工程Byylproject.jcw,編譯并運行即可。</p><p><b>  2.

89、8 心得體會</b></p><p>  歷時10多天的課程設(shè)計結(jié)束了,不禁有些留戀,也不禁有些欣喜。軟件的編寫是一件艱難而又會令人欣喜若狂的事。從程序連編譯都不能通過到程序能運行但會拋出許多異常,從運行的結(jié)果的與我們事先預(yù)料的結(jié)果大相徑庭到運行結(jié)果有些小小的錯誤,再到程序能夠輸出完全正確的結(jié)果,我們必須一步一步地分析,一段程序一段程序的檢測。有的時候為了一個錯誤檢測半天,幾乎都有崩潰的感覺,而等到最

90、后找到原因的時候,才恍然大悟,那時的欣喜心情是值得留戀的。等到程序最終完成,回憶那些執(zhí)著的時光,真的沒有白費。</p><p>  這個程序的完成,首先得感謝機械工業(yè)出版社出版、賀汛編著的《編譯方法學(xué)習(xí)指導(dǎo)與實踐》一書的指導(dǎo)。其中詞法分析部分是上個學(xué)期的完成的,當(dāng)時花了三天的時間完成了詞法分析。事后想想花的這三天是否值得,如今開來多虧了當(dāng)時就已經(jīng)完成了詞法分析部分,才使得課程設(shè)計的開始沒花多少時間就進(jìn)入了語法/語

91、義的分析工作。雖然語法/語義分析的比詞法分析困難得多,但有了對詞法分析器原理的理解為基礎(chǔ),對語法/語義分析原理的理解就不算那末太難了。尤其是那種分析程序的方法,值得以后借鑒和使用。見到莫大一個程序,大體瀏覽一下它的函數(shù)的調(diào)用關(guān)系。然后我們那幾個簡單的例子按照它的分析方法看看這個莫大的程序能否處理的了。最好我們先從理論上分析一下,如果從理論上這個程序確實能夠處理這個例子,我們再從實踐上用這個程序去處理它。但有的程序根本就不是我們所想的那樣

92、,需要我們按照自己的思路去進(jìn)行修改,有時甚至改造非常大。如在什么時候生成四元式。</p><p>  通過這次課程設(shè)計,我認(rèn)識到做一個程序并不難。關(guān)鍵是你是否有一種靈感。當(dāng)然,對你所做的程序的理論上的把握式這個關(guān)鍵的前提。在理論上把握住了,再加上你對某種編程語言的熟悉,這個靈感就會產(chǎn)生。有了靈感就有了編程的激情,當(dāng)你實現(xiàn)了你的部分設(shè)想后,你會更加的執(zhí)著。如果你對某種編程語言不是很了解,也沒有關(guān)系,因為編程語言是在

93、不斷的實踐中學(xué)習(xí)的。碰到不會的,可以上網(wǎng)查查。有些編程語言還有幫助文檔。查閱幫助文檔可以更好的幫助你學(xué)習(xí)這門語言。在這個程序中,有好幾處都是我從java的幫助文檔中學(xué)習(xí)并實現(xiàn)的。</p><p>  總之,這次課程設(shè)計使我在動手能力上有了很大的提高,也許這是畢業(yè)設(shè)計之前最好的一次鍛煉動手能力的機會,也可能是最后一次。我認(rèn)為這次課程設(shè)計是畢業(yè)設(shè)計的前奏,不過我想我已經(jīng)成功的抓住了這次機會并很好的把握住了這個前奏。&

94、lt;/p><p><b>  2.9參考文獻(xiàn)</b></p><p>  1 胡曰利,吳曉芙.林木生長與養(yǎng)分動態(tài)模型研究V杉木林曲線[1].中南林學(xué)院學(xué)報,1999,19(4):1-7</p><p>  2 曾思齊,歐陽君祥. 馬尾松低質(zhì)低效次生林分類技術(shù)研究.[J].中南林學(xué)院學(xué)報,2002,22(2):12-16</p>

95、<p>  3 華羅庚,王元.論一致分布與近似分析.中國科學(xué),1973(4):339~357</p><p>  4 趙杰,李濤,朱慧. SQL Server數(shù)據(jù)庫管理、設(shè)計與實現(xiàn)教程.北京:清華大學(xué)出版社,2004.03</p><p>  5 Borko H,Bernier C L.Indexing concepts and methods .New York:Acad

96、emic Pr,1978</p><p><b>  3 結(jié)論</b></p><p>  雖然當(dāng)時學(xué)習(xí)編譯原理這門課程時,覺得他的理論很枯燥,不想學(xué)習(xí)一門編程語言那樣有意義。但當(dāng)你真正的把這門課程課基本思想弄明白后,這對我們的實踐是有很大的幫助作用的。它讓你得實踐能力從編些程序的層面深入到如何編譯這些程序以及如何計算機如何執(zhí)行這些程序的層面。 </p>

97、<p>  本程序完成了詞法分析的任務(wù):組織源程序的輸入;輸出token串;刪除注釋行;刪除空格及無用符號;行計數(shù)、列計數(shù);發(fā)現(xiàn)并定位詞法錯誤;查填符號表。</p><p>  本程序正確完成了語法/語義分析的任務(wù):檢測語法/語義錯誤;修改符號表;輸出四元式。</p><p>  本程序的界面美觀,菜單的功能明確。源代碼的注釋簡單明了,尤其是javadoc的生成使得對源代碼的理

溫馨提示

  • 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(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

提交評論