資源描述:
《附錄A 一個完成的編譯器前端程序.doc》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在學(xué)術(shù)論文-天天文庫。
1、附錄A一個完成的編譯器前端程序這個附錄給出了一個完整的編譯器前端程序,它是基于2.5-2.8節(jié)中非正式描述的簡單編譯器編寫的。和第二章的主要不同之處在于這個前端象6.6節(jié)中描述的那樣為布爾表達式生成跳轉(zhuǎn)代碼。我們首先給出源語言的語法。描述這個語法所用的文法需要進行調(diào)整,以適應(yīng)自頂向下的語法分析技術(shù)。這個翻譯器的Java代碼由五個包組成:main、lexer、symbol、parser和inter。包inter中包含的類處理用抽象語法表示的語言結(jié)構(gòu)。因為語法分析器的代碼和其它各個包交互,它將在最后描述。每個包被存放在一個獨立的目錄中,每個
2、類都有一個單獨的文件。作為語法分析器的輸入時,源程序就是一個由詞法單元組成的流,因此面向?qū)ο筇匦院驼Z法分析器的代碼之間沒有什么關(guān)系。當(dāng)由語法分析器輸出時,源程序就是一棵抽象語法樹,樹中的結(jié)構(gòu)或結(jié)點被實現(xiàn)為對象。這些對象負責(zé)處理下列所有的事情:構(gòu)造一個抽象語法樹結(jié)點,類型檢查,生成三地址中間代碼(見包inter)。A.1源語言這個語言的一個程序由一個塊組成,該塊中包含了可選的聲明和語句。記號basic表示基本類型。(見原文)把賦值當(dāng)作一個語句,而不是表達式中的運算,進行處理可以簡化翻譯工作。面向?qū)ο笈c面向步驟在一個面向?qū)ο蠓椒ㄖ?,一個構(gòu)造
3、的所有代碼都集中在這個構(gòu)造對應(yīng)的類中。但是在面向步驟的方法中就不一樣,這個方法中的代碼是按照步驟進行組織的,因此一個類型檢查子過程中對每個構(gòu)造都有一個case分支,且一個代碼生成子過程對每個構(gòu)造也都有一個case分支,等等。這兩者的折中之處在于:使用面向?qū)ο蠓椒〞沟酶淖兓蛟黾右粋€構(gòu)造,比如“for”語句,變得較容易;而使用面向步驟的方法會使得改變或增加一個步驟,比如類型檢查,變得比較容易。使用對象來實現(xiàn)時,增加一個新的構(gòu)造可以通過寫一個自包含的類來實現(xiàn),但是如果要改變一個步驟,比如插入類型強制轉(zhuǎn)換的代碼,就需要改變所有受影響的類。使用
4、面向步驟的方式時,增加一個新構(gòu)造可能會引起各個步驟中的多個過程的改變。(見原文)表達式的產(chǎn)生式處理了運算符的結(jié)合率和優(yōu)先級。它們對每個優(yōu)先級級別都使用了一個非終結(jié)符號,而非終結(jié)符號factor被用來表示括號中的表達式、標(biāo)識符、數(shù)組引用和常量。(見原文)A.2Main程序的執(zhí)行從類Main的例程main中開始。例程main創(chuàng)建了一個詞法分析器和一個語法分析器,然后調(diào)用語法分析器中的例程program。(見原文)A.3詞法分析器包lexer是2.6.5節(jié)中的詞法分析器的代碼的擴展。類Tag定義了各個詞法單元對應(yīng)的常量:(見原文)其中的三個常
5、量,INDEX、MINUS和TEMP不是詞法單元;它們將在抽象語法樹中使用。類Token和Num和2.6.5節(jié)的相同,但是增加了例程toString:(見原文)類Word用于管理保留字,標(biāo)識符,和象&&這樣的復(fù)合詞法單元的詞素。它也可以被用來管理在中間代碼中運算符的寫法;比如單目減號,源文本中的-2的中間形式是minus2。(見原文)類Real用于處理浮點數(shù):(見原文)如我們在2.6.5節(jié)中討論的,類Lexer的主例程,即函數(shù)scan,識別數(shù)字、標(biāo)識符和保留字。類Lexer中的第9到13行保留了選定的關(guān)鍵字。第14-16行保留了在其它地
6、方定義的對象的詞素。對象Word.True和Word.False在類Word中定義。對應(yīng)于基本類型int、char、bool和float的對象在類Type中定義。類Type是Word的一個子類。類Type來自包symbols。(見原文)函數(shù)readch()(第18行)被用來把下一個輸入字符讀到變量peek中。名字readch被復(fù)用,或者說重載,(第19-24行)來幫助識別復(fù)合的詞法單元。比如,一看到了輸入字符<,調(diào)用readch(“=”)就會把下一個字符讀入peek,并檢查它是否=。(見原文)函數(shù)scan一開始首先略過所有的空白字符(第
7、26-30行)。它首先試圖識別象<=這樣的復(fù)合詞法單元(第31-34行)和象365及3.14這樣的數(shù)字(第45-58行)。如果不成功,它就試圖讀入一個字符串(第59-70行)。(見原文)最后,peek中的任意字符都被作為詞法單元返回(第71到72行)。(見原文)A.4符號表和類型包symbols實現(xiàn)了符號表和類型。類Env實質(zhì)上和圖2.37中的代碼一樣。盡管類Lexer把字符串映射為字,類Env把字符串詞法單元映射為類Id的對象。類Id和其它的對應(yīng)于表達式和語句的類一起都在包Inter中定義。(見原文)我們把類Type定義為類Word的
8、子類,因為象int這樣的基本類型名字就是保留字,將被詞法分析器從詞素映射為適當(dāng)?shù)膶ο?。對?yīng)于基本類型的對象是Type.Int、Type.Float、Type.Char和Type.Bool(第7-10行)。這