編譯原理課程設(shè)計(jì)報(bào)告_第1頁(yè)
編譯原理課程設(shè)計(jì)報(bào)告_第2頁(yè)
編譯原理課程設(shè)計(jì)報(bào)告_第3頁(yè)
編譯原理課程設(shè)計(jì)報(bào)告_第4頁(yè)
編譯原理課程設(shè)計(jì)報(bào)告_第5頁(yè)
已閱讀5頁(yè),還剩61頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、2020年4月19日編譯原理課程設(shè)計(jì)報(bào)告文檔僅供參考編譯原理課程設(shè)計(jì)簡(jiǎn)單編譯器的設(shè)計(jì)與實(shí)現(xiàn)班 級(jí):組長(zhǎng):組員: 指導(dǎo)教師:設(shè)計(jì)時(shí)間: 12月姓名分工組長(zhǎng):語(yǔ)法分析部分,語(yǔ)義分析和中間代碼生成部分,符號(hào)表的管理,目標(biāo)代碼的生成,數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)和總體框架的設(shè)計(jì)。組員:中間代碼優(yōu)化部分,負(fù)責(zé)從DAG圖中獲得優(yōu)化后的四元式代碼,以及將中間變量填寫(xiě)入符號(hào)表內(nèi)。組員:中間代碼優(yōu)化部分,負(fù)責(zé)優(yōu)化DAG圖的建立。組員:詞法分析部分,詞法分析部分的符號(hào)表和錯(cuò)誤表的記錄。 TOC h z u t 標(biāo)題 2,1,標(biāo)題 3,1,標(biāo)題 4,2,標(biāo)題 5,3 HYPERLINK l _Toc 摘要 PAGEREF _To

2、c h 4 HYPERLINK l _Toc 1.概述 PAGEREF _Toc h 5 HYPERLINK l _Toc 2.課程設(shè)計(jì)任務(wù)及要求 PAGEREF _Toc h 6 HYPERLINK l _Toc 2.1 設(shè)計(jì)任務(wù) PAGEREF _Toc h 6 HYPERLINK l _Toc 2.2 設(shè)計(jì)要求 PAGEREF _Toc h 6 HYPERLINK l _Toc 3.算法及數(shù)據(jù)結(jié)構(gòu) PAGEREF _Toc h 7 HYPERLINK l _Toc 3.1算法的總體思想(流程) PAGEREF _Toc h 7 HYPERLINK l _Toc 3.2詞法分析模塊 PAG

3、EREF _Toc h 8 HYPERLINK l _Toc 3.2.1功能 PAGEREF _Toc h 8 HYPERLINK l _Toc 3.2.2數(shù)據(jù)結(jié)構(gòu) PAGEREF _Toc h 8 HYPERLINK l _Toc 3.2.3算法 PAGEREF _Toc h 10 HYPERLINK l _Toc 3.3語(yǔ)法分析(含語(yǔ)義分析和中間代碼生成)模塊 PAGEREF _Toc h 11 HYPERLINK l _Toc 3.3.1功能 PAGEREF _Toc h 11 HYPERLINK l _Toc 3.3.2數(shù)據(jù)結(jié)構(gòu) PAGEREF _Toc h 13 HYPERLINK

4、l _Toc 3.3.3算法 PAGEREF _Toc h 16 HYPERLINK l _Toc 3.4中間代碼優(yōu)化模塊 PAGEREF _Toc h 19 HYPERLINK l _Toc 3.4.1功能 PAGEREF _Toc h 19 HYPERLINK l _Toc 3.4.2數(shù)據(jù)結(jié)構(gòu) PAGEREF _Toc h 20 HYPERLINK l _Toc 3.4.3算法 PAGEREF _Toc h 20 HYPERLINK l _Toc 3.5目標(biāo)代碼生成模塊 PAGEREF _Toc h 23 HYPERLINK l _Toc 3.5.1功能 PAGEREF _Toc h 23

5、 HYPERLINK l _Toc 3.5.2數(shù)據(jù)結(jié)構(gòu) PAGEREF _Toc h 24 HYPERLINK l _Toc 3.5.3算法 PAGEREF _Toc h 24 HYPERLINK l _Toc 4.程序設(shè)計(jì)與實(shí)現(xiàn) PAGEREF _Toc h 26 HYPERLINK l _Toc 4.1程序流程圖 PAGEREF _Toc h 26 HYPERLINK l _Toc 4.2 程序說(shuō)明 PAGEREF _Toc h 26 HYPERLINK l _Toc 4.3實(shí)驗(yàn)結(jié)果 PAGEREF _Toc h 32 HYPERLINK l _Toc 5.系統(tǒng)特色 PAGEREF _To

6、c h 40 HYPERLINK l _Toc 6.結(jié)論 PAGEREF _Toc h 41 HYPERLINK l _Toc 7.參考文獻(xiàn) PAGEREF _Toc h 41 HYPERLINK l _Toc 8.收獲、體會(huì)和建議 PAGEREF _Toc h 41摘要一個(gè)編譯器所進(jìn)行的工作一般能夠劃分為五個(gè)階段:詞法分析、語(yǔ)法分析、語(yǔ)義分析和中間代碼產(chǎn)生、中間代碼的優(yōu)化、目標(biāo)代碼生成。我們?cè)O(shè)計(jì)了而且實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的類(lèi)C語(yǔ)言編譯器,該編譯器擁有完整的前端和后端,能夠進(jìn)行基本的編譯功能并產(chǎn)生可執(zhí)行文件向屏幕輸出源程序的運(yùn)行結(jié)果。該編譯器的詞法分析器能夠識(shí)別絕大部分標(biāo)準(zhǔn)C語(yǔ)言支持的詞法符號(hào),該詞

7、法分析器能夠過(guò)濾空格、Tab和回車(chē),而且支持注釋功能。該詞法分析器主要經(jīng)過(guò)有限自動(dòng)機(jī)的狀態(tài)跳轉(zhuǎn)來(lái)實(shí)現(xiàn),根據(jù)自動(dòng)機(jī)結(jié)束狀態(tài)來(lái)得到該單詞的TOKEN值。該模塊具有詞法錯(cuò)誤位置提示功能。該編譯器的語(yǔ)法部分采用了遞歸下降子程序的文法分析方法,所設(shè)計(jì)的文法支持了函數(shù)、函數(shù)類(lèi)型聲明、變量類(lèi)型聲明、變量定義、表示式語(yǔ)句、if條件語(yǔ)句和while循環(huán)語(yǔ)句以及簡(jiǎn)單輸出功能。在表示式語(yǔ)句方面,我們?cè)O(shè)計(jì)了支持所有算術(shù)運(yùn)算、關(guān)系運(yùn)算、邏輯運(yùn)算和位運(yùn)算功能的語(yǔ)法結(jié)構(gòu),而且語(yǔ)法上支持一維數(shù)組和結(jié)構(gòu)體。該編譯器語(yǔ)義分析和生成四元式階段能夠?qū)ψ兞慷x和語(yǔ)法錯(cuò)誤進(jìn)行檢測(cè),能夠識(shí)別出未定義的標(biāo)識(shí)符和重復(fù)定義標(biāo)識(shí)符,該階段最終實(shí)現(xiàn)

8、生成中間代碼四元式。該編譯器擁有中間代碼優(yōu)化模塊,采用DAG優(yōu)化算法按基本塊對(duì)四元式進(jìn)行了優(yōu)化,該編譯器的目標(biāo)代碼是8086匯編語(yǔ)言代碼,能夠?qū)崿F(xiàn)將優(yōu)化后的四元式序列轉(zhuǎn)化生成可執(zhí)行的匯編語(yǔ)言文件,而且運(yùn)行執(zhí)行該文件,向屏幕輸出運(yùn)算結(jié)果。該編譯程序的主要特色是能夠?qū)⒆罱K結(jié)果輸出顯示到屏幕,而且該編譯程序能夠支持前置+和后置+這種語(yǔ)法,擁有類(lèi)似C語(yǔ)言的這種簡(jiǎn)便性。關(guān)鍵詞:編譯原理,詞法分析,語(yǔ)法分析,四元式,DAG算法1.概述 編譯原理課程兼有很強(qiáng)的理論性和實(shí)踐性,是計(jì)算機(jī)專(zhuān)業(yè)的一門(mén)非常重要的專(zhuān)業(yè)基礎(chǔ)課程,在系統(tǒng)軟件中占有十分重要的地位。編譯原理課程設(shè)計(jì)是本課程重要的綜合實(shí)踐教學(xué)環(huán)節(jié),是對(duì)平時(shí)實(shí)驗(yàn)

9、的一個(gè)補(bǔ)充。經(jīng)過(guò)編譯器相關(guān)子系統(tǒng)的設(shè)計(jì),使學(xué)生能夠更好地掌握編譯原理的基本理論和編譯程序構(gòu)造的基本方法和技巧,融會(huì)貫通本課程所學(xué)專(zhuān)業(yè)理論知識(shí);培養(yǎng)學(xué)生獨(dú)立分析問(wèn)題、解決問(wèn)題的能力,以及系統(tǒng)軟件設(shè)計(jì)的能力;培養(yǎng)學(xué)生的創(chuàng)新能力及團(tuán)隊(duì)協(xié)作精神。一個(gè)編譯器所進(jìn)行的工作一般能夠劃分為五個(gè)階段:詞法分析、語(yǔ)法分析、語(yǔ)義分析和中間代碼產(chǎn)生、中間代碼的優(yōu)化、目標(biāo)代碼生成。首先是詞法分析,針對(duì)詞法分析,我們?cè)O(shè)計(jì)了一個(gè)能夠識(shí)別絕大部分標(biāo)準(zhǔn)C語(yǔ)言支持的詞法符號(hào),該詞法分析器能夠過(guò)濾空格、Tab和回車(chē),而且支持注釋功能,即過(guò)濾掉注釋符號(hào)$后面的代碼。該詞法經(jīng)過(guò)有限自動(dòng)機(jī)的狀態(tài)跳轉(zhuǎn)來(lái)實(shí)現(xiàn),根據(jù)自動(dòng)機(jī)結(jié)束狀態(tài)來(lái)得到該單詞

10、的TOKEN值,詞法分析器在識(shí)別到一個(gè)單詞后,將該單詞記錄下來(lái),如果是數(shù)據(jù),則會(huì)在符號(hào)表的相應(yīng)位置記錄它的值,如果是標(biāo)識(shí)符,則會(huì)先在符號(hào)表上進(jìn)行查詢(xún),若沒(méi)有則將其記錄到符號(hào)表上,并將相應(yīng)TOKEN的指針指向表中該位置。接下來(lái)進(jìn)行語(yǔ)法分析,在語(yǔ)法分析部分,會(huì)對(duì)所編寫(xiě)的代碼的語(yǔ)法進(jìn)行檢驗(yàn),看是否合乎我們所設(shè)定的語(yǔ)法規(guī)則,這里我們采用了遞歸下降子程序的文法分析方法,所設(shè)計(jì)的文法支持了函數(shù)、函數(shù)類(lèi)型聲明、變量類(lèi)型聲明、變量定義、表示式語(yǔ)句、if條件語(yǔ)句和while循環(huán)語(yǔ)句以及cout簡(jiǎn)單輸出功能。在表示式語(yǔ)句方面,我們?cè)O(shè)計(jì)了支持所有算術(shù)運(yùn)算、關(guān)系運(yùn)算、邏輯運(yùn)算和位運(yùn)算功能的語(yǔ)法結(jié)構(gòu),而且語(yǔ)法上支持一維

11、數(shù)組和結(jié)構(gòu)體。在語(yǔ)義分析和中間代碼產(chǎn)生的階段。我們?cè)谡Z(yǔ)法分析程序的相應(yīng)部分加上了語(yǔ)義動(dòng)作,實(shí)現(xiàn)將輸入的語(yǔ)句轉(zhuǎn)換成可識(shí)別的中間代碼四元式形式。在語(yǔ)義分析部分,主要做的工作是在識(shí)別到數(shù)據(jù)和標(biāo)識(shí)符時(shí)將它們壓入語(yǔ)義棧,當(dāng)語(yǔ)法分析到需要生成相應(yīng)四元式時(shí),執(zhí)行構(gòu)建四元式的動(dòng)作,并將語(yǔ)義棧中的數(shù)據(jù)作為四元式的數(shù)據(jù)組成部分。還有就是符號(hào)表的構(gòu)建,當(dāng)語(yǔ)法分析到變量的定義語(yǔ)句時(shí),需要將被定義的變量記錄到符號(hào)表內(nèi),在記錄之前需要檢查符號(hào)表內(nèi)該符號(hào)是否已經(jīng)被定義,從而檢查重復(fù)定義的錯(cuò)誤。語(yǔ)義分析和中間代碼產(chǎn)生是與語(yǔ)法分析同時(shí)進(jìn)行的,當(dāng)語(yǔ)法分析結(jié)束后,若輸入內(nèi)容的語(yǔ)法正確,則能夠獲得相應(yīng)的四元式序列。然后是優(yōu)化階段。在

12、優(yōu)化階段,我們主要運(yùn)用了DAG優(yōu)化算法。首先將編譯器前端生成的四元式劃分基本塊,然后對(duì)每一個(gè)基本塊執(zhí)行DAG優(yōu)化算法,經(jīng)過(guò)該算法能夠刪除多余的賦值操作和無(wú)用的中間變量,從而減少四元式的數(shù)量,得到更簡(jiǎn)潔的四元式序列。最后一個(gè)階段是目標(biāo)代碼生成。該階段將四元式進(jìn)一步翻譯生成相應(yīng)的目標(biāo)代碼,我們所選定的目標(biāo)代碼是8086匯編語(yǔ)言代碼,因此該階段的任務(wù)是將優(yōu)化后的四元式序列轉(zhuǎn)化生成可執(zhí)行的匯編語(yǔ)言文件,從而進(jìn)一步運(yùn)行執(zhí)行該文件,向屏幕輸出運(yùn)算結(jié)果。2.課程設(shè)計(jì)任務(wù)及要求2.1 設(shè)計(jì)任務(wù)設(shè)計(jì)一個(gè)簡(jiǎn)單的文法編譯器,該編譯器包括完整的前端和后端。該編譯器能夠劃分為詞法分析、語(yǔ)法分析和語(yǔ)義動(dòng)作、中間代碼優(yōu)化和

13、目標(biāo)代碼生成四個(gè)模塊。詞法分析:能夠識(shí)別標(biāo)準(zhǔn)C語(yǔ)言所支持的大部分詞法,能夠進(jìn)行簡(jiǎn)單的詞法錯(cuò)誤判斷,輸出錯(cuò)誤提示,而且具有注釋功能,能夠過(guò)濾掉無(wú)用符號(hào),如空格、Tab和回車(chē)等。語(yǔ)法分析和語(yǔ)義動(dòng)作:能夠支持基本類(lèi)似于C語(yǔ)言的基本語(yǔ)法。語(yǔ)法上能夠支持聲明語(yǔ)句、基本類(lèi)型的變量定義,如整型、實(shí)型和字符型數(shù)據(jù);能夠支持表示式語(yǔ)句,包括賦值表示式、算術(shù)表示式、邏輯表示式、關(guān)系表示式和位運(yùn)算表示式;能夠支持if條件語(yǔ)句和while循環(huán)語(yǔ)句。中間代碼優(yōu)化:采用DAG優(yōu)化算法,能夠?qū)λ脑竭M(jìn)行優(yōu)化,從而減少中間代碼的數(shù)量,提高編譯后生成的程序的效率。目標(biāo)代碼生成:將中間代碼生成匯編語(yǔ)言代碼,而且實(shí)現(xiàn)目標(biāo)代碼的運(yùn)行

14、,從而驗(yàn)證編譯器編譯結(jié)果的正確性。2.2 設(shè)計(jì)要求1、在深入理解編譯原理基本原理的基礎(chǔ)上,對(duì)于選定的題目,以小組為單位,先確定設(shè)計(jì)方案;2、設(shè)計(jì)系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)和程序結(jié)構(gòu),設(shè)計(jì)每個(gè)模塊的處理流程。要求設(shè)計(jì)合理;3、編程序?qū)崿F(xiàn)系統(tǒng),要求運(yùn)行界面應(yīng)清楚地反映出系統(tǒng)的運(yùn)行結(jié)果;4、確定測(cè)試方案,選擇測(cè)試用例,對(duì)系統(tǒng)進(jìn)行測(cè)試;5、運(yùn)行系統(tǒng)并要經(jīng)過(guò)驗(yàn)收,講解運(yùn)行結(jié)果,說(shuō)明系統(tǒng)的特色和創(chuàng)新之處,并回答指導(dǎo)教師的提問(wèn);6、提交課程設(shè)計(jì)報(bào)告。3.算法及數(shù)據(jù)結(jié)構(gòu)3.1算法的總體思想(流程)我們將編譯器的設(shè)計(jì)按照功能劃分為以下四個(gè)部分,經(jīng)過(guò)這四個(gè)部分來(lái)實(shí)現(xiàn)編譯器的全部功能。如下圖。圖3.1 算法總體思想圖詞法分析器

15、用來(lái)對(duì)輸入的字符流進(jìn)行詞法分析,識(shí)別每一個(gè)單詞并生成相應(yīng)的TOKEN碼,并記錄它們的數(shù)據(jù)信息。語(yǔ)法分析和語(yǔ)義分析以及中間代碼的生成被劃分為一個(gè)模塊是因?yàn)樗鼈兊牟豢煞指钚裕?dāng)某個(gè)語(yǔ)法分析經(jīng)過(guò)后,就開(kāi)始產(chǎn)生語(yǔ)義動(dòng)作生成相應(yīng)的四元式,因此該部分用來(lái)對(duì)詞法分析產(chǎn)生的TOKEN序列進(jìn)行語(yǔ)法分析,從而在符號(hào)表中記錄相關(guān)數(shù)據(jù)信息,而且產(chǎn)生中間代碼。中間代碼優(yōu)化模塊是為了簡(jiǎn)化中間代碼而設(shè)計(jì)的,該部分經(jīng)過(guò)四元式構(gòu)建相應(yīng)的無(wú)向圖,經(jīng)過(guò)算法產(chǎn)生優(yōu)化后的四元式序列。目標(biāo)代碼生成模塊用于產(chǎn)生匯編代碼,將優(yōu)化后的四元式進(jìn)行翻譯,生成對(duì)應(yīng)的匯編語(yǔ)言。該編譯器包含了前端和后端的基本功能,能夠進(jìn)行詞法錯(cuò)誤檢測(cè)、語(yǔ)法錯(cuò)誤檢測(cè)、標(biāo)

16、識(shí)符定義錯(cuò)誤檢測(cè),并提示錯(cuò)誤行數(shù),且編譯后生成能夠直接運(yùn)行的匯編程序,能夠算是一個(gè)較為完整的簡(jiǎn)單編譯器。3.2詞法分析模塊3.2.1功能經(jīng)過(guò)將源程序輸入該模塊,詞法分析器能夠進(jìn)行分析,檢測(cè)詞法是否正確,從而生成相應(yīng)的TOKEN碼,并向符號(hào)表中記錄,如果遇到錯(cuò)誤詞法,則記錄在錯(cuò)誤表中。該詞法分析器所能識(shí)別的詞法包括以下幾個(gè)部分。整數(shù):TOKEN值為0實(shí)數(shù):TOKEN值為1字符:TOKEN值為2字符串:TOKEN值為3標(biāo)識(shí)符:TOKEN值為4關(guān)鍵字:TOKEN值為10-49現(xiàn)有能夠識(shí)別的關(guān)鍵字有:auto,short,int,long,real,double,char,struct,union,e

17、num,typedef,const,unsigned,signed,extern,register,static,volatile,void,if,else,switch,case,for,do,while,goto,continue,break,default,sizeof,return,bool,cout.界符:TOKEN值為50-69現(xiàn)有能夠識(shí)別的界符有:,(,),”,;,,,.,-,?,#運(yùn)算符:TOKEN值為70-99現(xiàn)有能夠識(shí)別的運(yùn)算符有:+,-,*,/,%,+,-,=,=,,?,#;/界符表char OT233+,-,*,/,%,+,-,=,=, FunctionFunction

18、Function - FType i4 ( Parameter ) Declaration Content 類(lèi)型文法:FType - void|TypeType - int|real|charParameter - |void|Type Id , Type Id Id - i4|i4 i1 結(jié)構(gòu)體聲明文法:Declaration - |struct i4 Base_declaration ;|Base_declaration 基本類(lèi)型定義文法:Base_declaration - | Type Id , Id ; 語(yǔ)句塊文法:Content - Structure Structure Stru

19、cture - |E ;|If|While|Fun|Cout函數(shù)調(diào)用文法:Fun - i4 ( ) ;|i4 ( Assignment , Assignment ) ;if條件語(yǔ)句文法:If - if ( Expression ) Content | if ( Expression ) Content else Content while循環(huán)語(yǔ)句文法:While - while ( Expression ) Content 逗號(hào)表示式文法:Expression - Assignment , Assignment 賦值表示式文法:Assignment - i4 . Id = Logical_or

20、 | Id = Logical_or | Logical_or邏輯表示式文法:Logical_or - Logical_and | Logical_and Logical_and - Inclusive_or & Inclusive_or Inclusive_or -Exclusive_or | Exclusive_or Exclusive_or -And And And - Equality & Equality 關(guān)系表示式文法:Equality - Relational w0 Relational Relational - Shift w1 Shift 算術(shù)表示式文法:Shift - Ad

21、ditive w2 Additive Additive - Multiplicative w3 Multiplicative Multiplicative - Unary w4 Unary 前置算符文法:Unary - w5 Postfix | Postfix后置算符文法:Postfix -Primary w6 Primary -i4|constant| ( Expression )其中符號(hào)表示:w0 - = | !=w1 - | =w2 - w3 - + | -w4 - * | / | %w5 - ! | | + | - | sizeofw6 - + | - | Expression | .

22、 i4其中constant為整數(shù)、實(shí)數(shù)或者字符類(lèi)型數(shù)據(jù),i4為用戶(hù)自定義標(biāo)識(shí)符,能夠由字母、數(shù)字和下劃線組成,不能以數(shù)字開(kāi)頭,而且不能與關(guān)鍵字相同。該模塊還要執(zhí)行相應(yīng)的語(yǔ)義功能以及中間代碼的生成。語(yǔ)義功能主要包括變量的定義、表示式四元式的生成、if條件語(yǔ)句和while循環(huán)語(yǔ)句的四元式生成等。變量的定義需要實(shí)現(xiàn)與符號(hào)表進(jìn)行信息交換的功能,該變量定義的文法經(jīng)過(guò)檢驗(yàn)后,會(huì)向符號(hào)表中查找該標(biāo)識(shí)符名稱(chēng),如果沒(méi)有查到則將該變量的類(lèi)型和相關(guān)信息寫(xiě)入符號(hào)表;如果在符號(hào)表中查詢(xún)到該標(biāo)識(shí)符,則說(shuō)明該變量名已經(jīng)被定義,于是向錯(cuò)誤表中寫(xiě)入標(biāo)識(shí)符重復(fù)定義的錯(cuò)誤信息,并標(biāo)注錯(cuò)誤行數(shù)。表示式和if、while語(yǔ)句在相應(yīng)文法

23、檢驗(yàn)的過(guò)程中,會(huì)對(duì)操作數(shù)進(jìn)行壓棧處理,當(dāng)文法檢驗(yàn)成功后,會(huì)彈出操作數(shù)生成相應(yīng)的四元式序列。當(dāng)所有的語(yǔ)句都經(jīng)過(guò)了文法檢驗(yàn)而且生成了相應(yīng)的四元式后,該模塊會(huì)對(duì)四元式中的操作數(shù)進(jìn)行檢測(cè),如果該操作數(shù)是用戶(hù)自定義的標(biāo)識(shí)符,就去符號(hào)表中查詢(xún),如果出現(xiàn)符號(hào)表中查詢(xún)不到的標(biāo)識(shí)符,則說(shuō)明該標(biāo)識(shí)符未被定義,此時(shí)向錯(cuò)誤表中寫(xiě)入標(biāo)識(shí)符未定義的錯(cuò)誤信息,并標(biāo)注錯(cuò)誤行數(shù)。3.3.2數(shù)據(jù)結(jié)構(gòu)語(yǔ)法分析過(guò)程是對(duì)詞法分析生成的token序列進(jìn)行分析,判斷是否符合語(yǔ)法標(biāo)準(zhǔn),因此不需要新的數(shù)據(jù)結(jié)構(gòu),只需要獲取到token序列即可。語(yǔ)義分析的過(guò)程則需要額外的數(shù)據(jù)結(jié)構(gòu)來(lái)對(duì)語(yǔ)義動(dòng)作和相應(yīng)操作進(jìn)行存儲(chǔ)。其中在生成四元式的過(guò)程中需要用到語(yǔ)義

24、棧來(lái)存儲(chǔ)當(dāng)前的token,以便當(dāng)識(shí)別到算符語(yǔ)法結(jié)束位置時(shí)從語(yǔ)義棧中彈出token生成相應(yīng)的四元式序列。另外,在語(yǔ)法分析的過(guò)程中,還有變量、數(shù)組的定義和結(jié)構(gòu)體的聲明,這些語(yǔ)法檢驗(yàn)經(jīng)過(guò)后也要經(jīng)過(guò)執(zhí)行相應(yīng)的語(yǔ)義動(dòng)作將相關(guān)信息填寫(xiě)入符號(hào)表內(nèi)。因此這里新增了一個(gè)語(yǔ)義棧結(jié)構(gòu)體,用來(lái)存儲(chǔ)生成四元式所需的操作數(shù),還開(kāi)辟了一個(gè)四元式鏈表,用來(lái)存儲(chǔ)生成的四元式,四元式中的運(yùn)算符是經(jīng)過(guò)二維數(shù)組的數(shù)據(jù)結(jié)構(gòu)來(lái)保存的。同時(shí)符號(hào)表中還需要類(lèi)型表、數(shù)組表和結(jié)構(gòu)體表,其中類(lèi)型表用來(lái)存儲(chǔ)標(biāo)識(shí)符的類(lèi)型,如果該標(biāo)識(shí)符是數(shù)組或者結(jié)構(gòu)體,則需要額外的數(shù)組表或結(jié)構(gòu)體表來(lái)存儲(chǔ)數(shù)據(jù)之間的關(guān)系。typedef struct SEM/語(yǔ)義棧 st

25、ruct TOKEN* tpToken; struct SEM* fron; struct SEM* next;SEM;typedef struct Operand/操作數(shù) struct TOKEN* tpToken;Operand;char OperatorL375+,-,*,/,%,+,-,=,=,gt,lb,if,el,ie,wh,do,we,inc,dec,arr,si,.,co;typedef struct Quaternary/四元式 char* Operator;/操作符表 struct Operand* operand3;/3個(gè)操作數(shù) struct Quaternary* ne

26、xt;Quaternary;typedef struct TYPEL/類(lèi)型表 char tval;/類(lèi)碼,類(lèi)型代碼,決定下列指針選擇,現(xiàn)有類(lèi)碼為:i(整型),r(實(shí)型),c(字符型),a(數(shù)組),d(結(jié)構(gòu)體) struct AINFL* ainfl;/數(shù)組表指針 struct RINFL* rinfl;/結(jié)構(gòu)體表指針TYPEL;typedef struct AINFL/數(shù)組表 int low;/數(shù)組下界 int up;/數(shù)組上界 struct TYPEL* ctp;/成分類(lèi)型指針,指向該維數(shù)組成分的類(lèi)型的指針 int clen;/成分類(lèi)型的長(zhǎng)度,成分類(lèi)型數(shù)據(jù)所占值單元的個(gè)數(shù)AINFL;type

27、def struct RINFL/結(jié)構(gòu)表 char ID10;/結(jié)構(gòu)域名 int OFF;/(區(qū)距)是idk的值單元首址相對(duì)于所在記錄值區(qū)區(qū)頭位置 struct TYPEL* TP;/指針,指向idk域成分類(lèi)型(在類(lèi)型表中的信息)RINFL;3.3.3算法圖3.3 賦值語(yǔ)法的算法圖3.4 邏輯或算法圖3.5 數(shù)據(jù)生成部分算法圖3.6 if條件語(yǔ)句算法圖3.7 while循環(huán)語(yǔ)句算法3.4中間代碼優(yōu)化模塊3.4.1功能該部分的功能是對(duì)從前端得到的四元式進(jìn)行優(yōu)化,目的是為了精簡(jiǎn)代碼數(shù)量,使得編譯后的程序能夠更高效的運(yùn)行,這里我們采用了DAG算法對(duì)中間代碼進(jìn)行優(yōu)化。首先對(duì)前端輸出的四元式進(jìn)行基本塊劃

28、分,然后對(duì)一個(gè)基本塊執(zhí)行DAG算法,構(gòu)造一個(gè)無(wú)向圖,從該圖中獲取到優(yōu)化后的四元式序列。之后清空該圖,對(duì)之后的基本塊執(zhí)行相同的算法,直到將所有基本塊的四元式序列都優(yōu)化為止,最后輸出優(yōu)化后的四元式序列。3.4.2數(shù)據(jù)結(jié)構(gòu)中間代碼優(yōu)化部分需要建立一個(gè)無(wú)向圖,經(jīng)過(guò)相應(yīng)算法來(lái)實(shí)現(xiàn)對(duì)基本塊的優(yōu)化,因此這里需要一個(gè)圖的數(shù)據(jù)結(jié)構(gòu),該圖結(jié)點(diǎn)有左右孩子、編號(hào)、運(yùn)算符、標(biāo)記和前后指針。其中單獨(dú)創(chuàng)立了一個(gè)標(biāo)記鏈表的數(shù)據(jù)結(jié)構(gòu),首個(gè)標(biāo)記作為主標(biāo)記,主標(biāo)記后面所連接的標(biāo)記作為從標(biāo)記。運(yùn)算符是用來(lái)記錄四元式的運(yùn)算符的,左右孩子是為了記錄單目運(yùn)算符和雙目運(yùn)算符所指向的操作數(shù),標(biāo)記是為了記錄操作數(shù),而前后指針是為了在DAG算法中

29、更方便地查找刪除重復(fù)的非用戶(hù)定義標(biāo)識(shí)符。另外創(chuàng)立了一個(gè)塊鏈表,用來(lái)存儲(chǔ)分塊后的四元式,從而方便將四元式按照基本塊進(jìn)行劃分保存,以便進(jìn)行DAG算法優(yōu)化。typedef struct Block struct Quaternary* qua_block;/分塊后的四元式塊集合 struct Block* next;/下一個(gè)塊Block;typedef struct DAG/無(wú)向圖 int num; char* oper; struct Mark* mark; struct DAG* lchild; struct DAG* rchild; struct DAG* next; struct DAG*

30、fron;DAG;typedef struct Mark/標(biāo)記 struct TOKEN* name; struct Mark* fron; struct Mark* next;Mark;3.4.3算法劃分基本塊的算法如下:圖3.8 構(gòu)建基本塊算法構(gòu)建DAG優(yōu)化圖的算法如下所示:圖3.9 DAG優(yōu)化創(chuàng)立算法從DAG中獲取優(yōu)化后四元式的算法如下圖所示:圖3.10 優(yōu)化后四元式獲取算法3.5目標(biāo)代碼生成模塊3.5.1功能該模塊的功能是經(jīng)過(guò)優(yōu)化后的四元式序列生成目標(biāo)代碼匯編語(yǔ)言。該部分首先會(huì)對(duì)得到的四元式序列進(jìn)行分析,對(duì)四元式序列中的操作數(shù)進(jìn)行判斷,如果該操作數(shù)是系統(tǒng)生成的中間變量(該中間變量不能在

31、運(yùn)算化簡(jiǎn)中被舍棄),那么就會(huì)在符號(hào)表中查找,看符號(hào)表中是否存在該變量,如果不存在該變量,則向符號(hào)表中寫(xiě)入該變量,并標(biāo)注變量類(lèi)型,從而方便接下來(lái)的目標(biāo)代碼生成。按基本塊順序讀取優(yōu)化后的四元式序列,根據(jù)四元式的運(yùn)算符進(jìn)行判斷,生成相應(yīng)的匯編代碼,當(dāng)所有基本塊都被讀完后,匯編代碼生成完畢,最后將匯編代碼輸出到ASM文件中,運(yùn)行DOS將其編譯連接并運(yùn)行,得到源程序的運(yùn)行結(jié)果。3.5.2數(shù)據(jù)結(jié)構(gòu)該部分需要一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)目標(biāo)語(yǔ)句,這里采用鏈表的數(shù)據(jù)結(jié)構(gòu),使用一個(gè)目標(biāo)語(yǔ)句鏈表來(lái)保存目標(biāo)語(yǔ)句的相關(guān)信息,其中包含存儲(chǔ)的目標(biāo)代碼語(yǔ)句,該語(yǔ)句所處的位置標(biāo)號(hào)以及當(dāng)前語(yǔ)句的類(lèi)型。當(dāng)前語(yǔ)句的類(lèi)型當(dāng)前有4種,一種是0,

32、表示此語(yǔ)句為一般語(yǔ)句,另外3種分別為i、e、d,分別代表if、else、do的四元式產(chǎn)生的目標(biāo)語(yǔ)句,這些語(yǔ)句因?yàn)樯婕暗教D(zhuǎn),需要當(dāng)讀取到它們跳轉(zhuǎn)到的語(yǔ)句時(shí)才能獲得地址信息,因此它們所生成的目標(biāo)語(yǔ)句的跳轉(zhuǎn)地址需要回填,這個(gè)語(yǔ)句類(lèi)型作為回填時(shí)查找該語(yǔ)句的標(biāo)志來(lái)使用。typedef struct Object/目標(biāo)語(yǔ)句 char code30;/存儲(chǔ)的目標(biāo)代碼 int lab;/標(biāo)號(hào) char type;/需要回填的類(lèi)型,0為不需要回填,i為if的回填,e為else的回填,d為do的回填 struct Object* fron; struct Object* next;Object;3.5.3算法目

33、標(biāo)代碼的生成算法如下圖所示:圖3.11 目標(biāo)代碼生成算法4.程序設(shè)計(jì)與實(shí)現(xiàn)4.1程序流程圖圖4.1 程序運(yùn)行流程圖4.2 程序說(shuō)明程序的編寫(xiě)使用的是C+語(yǔ)言,采用了類(lèi)的封裝,將整個(gè)編譯器拆分為了四個(gè)模塊,分別是詞法分析器模塊、語(yǔ)法分析(含語(yǔ)義分析和中間代碼生成)模塊、中間代碼優(yōu)化模塊和目標(biāo)代碼生成模塊,各個(gè)模塊由上到下依次繼承,實(shí)現(xiàn)了良好的封裝性。下面按照每個(gè)模塊類(lèi)的設(shè)計(jì)對(duì)各個(gè)模塊所含有的成員和方法進(jìn)行說(shuō)明。詞法分析:class Scanner/詞法分析器模塊private: char ch,ch_before;/當(dāng)前詞,前一個(gè)詞 int state,state_before;/狀態(tài),前狀態(tài)

34、int line,warn;/行數(shù),警告 void CreatNewToken(TOKEN*& t);/創(chuàng)立新的Token結(jié)點(diǎn) void reset(int& state,char* code,int& i,int& warn);/重置自動(dòng)機(jī)狀態(tài) int state_change(int st,char ch,int& warn);/自動(dòng)機(jī)狀態(tài)轉(zhuǎn)換 void state_to_code(TOKEN* t, int state_before, char code100, int line, int warn);/根據(jù)自動(dòng)機(jī)狀態(tài)生成Token序列public: struct TOKEN* toke

35、n;/token頭指針 struct ERRORL* error_head;/錯(cuò)誤表頭指針 struct ERRORL* error_now;/錯(cuò)誤表當(dāng)前位置 Scanner()token=NULL;error_head=NULL;error_now=NULL;/構(gòu)造函數(shù) void Scan();/詞法分析主函數(shù) int Findexist(char* code, TOKEN*& p);/查詢(xún)符號(hào)表函數(shù) void ConvertItoS(int i, string& s);/類(lèi)型轉(zhuǎn)換,int to string void ConvertFtoS(float f,string& st);/類(lèi)型轉(zhuǎn)

36、換,float to string void ConvertStoC(string st,char* c);/類(lèi)型轉(zhuǎn)換,string to char void ConvertStoI(string st,int& i);/類(lèi)型轉(zhuǎn)換,string to int void ConvertStoF(string st,float& f);/類(lèi)型轉(zhuǎn)換,string to float void CoutErrorL();/輸出錯(cuò)誤表;語(yǔ)法分析、語(yǔ)義分析和中間代碼生成:class GrammaticalAnalysis:public Scanner/語(yǔ)法分析和語(yǔ)義動(dòng)作及/中間代碼生成模塊private:

37、/語(yǔ)法部分 struct TOKEN* ch;/當(dāng)前詞 int Start();/語(yǔ)法,開(kāi)始 int Function();/語(yǔ)法,函數(shù) int Parameter();/語(yǔ)法,參數(shù) int FType();/語(yǔ)法,函數(shù)類(lèi)型 int Type();/語(yǔ)法,變量類(lèi)型 int Declaration();/語(yǔ)法,聲明 int Base_declaration();/語(yǔ)法,基本類(lèi)型聲明 int Id();/語(yǔ)法,基本類(lèi)型 int Id_Expression();/語(yǔ)法,數(shù)據(jù)類(lèi)型 int Content();/語(yǔ)法,內(nèi)容 int Structure();/語(yǔ)法,結(jié)構(gòu) int Expression();

38、/語(yǔ)法,表示式 int Cout();/語(yǔ)法,輸出函數(shù) int Assignment();/語(yǔ)法,賦值 int Logical_or();/語(yǔ)法,邏輯或 int Logical_and();/語(yǔ)法,邏輯與 int Inclusive_or();/語(yǔ)法,或 int Exclusive_or();/語(yǔ)法,異或 int And();/語(yǔ)法,位與 int Equality();/語(yǔ)法,相等 int Relational();/語(yǔ)法,不等 int Shift();/語(yǔ)法,移位 int Additive();/語(yǔ)法,加法減法 int Multiplicative();/語(yǔ)法,乘法除法 int Unary(

39、);/語(yǔ)法,前置算符 int Postfix();/語(yǔ)法,后置算符 int Primary();/語(yǔ)法,標(biāo)識(shí)符、常數(shù)生成 int IF();/語(yǔ)法,if條件語(yǔ)句 int While();/語(yǔ)法,while循環(huán)語(yǔ)句 int Fun();/語(yǔ)法,函數(shù)語(yǔ)句 /語(yǔ)義部分 int d;/結(jié)構(gòu)體標(biāo)記 struct TOKEN* type;/類(lèi)型標(biāo)記 struct TOKEN* ch_sem;/入語(yǔ)義棧的詞 struct TOKEN* operand_now;/當(dāng)前操作數(shù) struct SEM* top;/棧頂 struct SEM* base;/棧底 struct Quaternary* quater_n

40、ow;/當(dāng)前四元式指針 void CreateSEM();/生成一個(gè)語(yǔ)義棧 void PushStack();/入棧 void DeStack();/出棧 int mark;/標(biāo)明運(yùn)算符位置 int counter;/系統(tǒng)變量計(jì)數(shù)器 void CreateQuaternary();/生成一個(gè)四元式 void PushQuaternary();/入四元式隊(duì)列 void Bi_oper_qua();/雙目算符的操作數(shù)生成 void Unary_oper_qua();/單目算符的操作數(shù)生成 void Assign_oper_qua();/賦值操作數(shù)生成 void If_While_qua();/IF

41、條件,WHILE循環(huán)操作數(shù)生成 void GetMark(TOKEN* ch_ope);/獲取運(yùn)算符 void GetMark_front(TOKEN* ch_ope);/獲取前置運(yùn)算符 int FindSynbl();/查重 void PushSynbl();/添加進(jìn)符號(hào)表 int CoutSynbl();/輸出符號(hào)表 void CheckSynbl();/檢查標(biāo)識(shí)符是否被定義,未定義則記錄到錯(cuò)誤表中public: void Grammar(); /語(yǔ)法部分 int result;GrammaticalAnalysis()token=NULL;counter=1;d=0;error_head

42、=NULL;error_now=NULL; /語(yǔ)義部分 struct Operand* operand3;/語(yǔ)義操作數(shù) struct Quaternary* quater;/四元式 struct Identifier* id;/用戶(hù)定義標(biāo)識(shí)符 struct Identifier* id_now;/當(dāng)前標(biāo)識(shí)符指針 void CoutQuaternary();/輸出四元式;中間代碼優(yōu)化:class Optimization:public GrammaticalAnalysis/中間代碼優(yōu)化模塊private: struct Quaternary* optimize_now;/當(dāng)前優(yōu)化四元式 str

43、uct Block* optimize_block_now;/優(yōu)化后的當(dāng)前塊 struct Block* block_now;/當(dāng)前塊指針 struct Quaternary* qua;/四元式 struct DAG* dag_head;/DAG頭指針 struct DAG* dag_tail;/DAG尾指針 struct DAG* dag_now;/DAG當(dāng)前指針 struct Operand* find_now_num1;/當(dāng)前查找詞 struct Operand* find_now_num2;/當(dāng)前查找詞 char* find_now_ope;/當(dāng)前查找運(yùn)算符 struct Operan

44、d* add_now;/當(dāng)前需要加入的結(jié)點(diǎn) char* op_now;/當(dāng)前運(yùn)算符 struct DAG* find_begin;/查找開(kāi)始處 struct DAG* pos;/找到的位置 struct Mark* mark_pos;/找到的標(biāo)記位置 struct DAG* temp_dag;/待交換標(biāo)記所在的dag結(jié)點(diǎn) struct Mark* temp1;/待交換標(biāo)記1 struct Mark* temp2;/待交換標(biāo)記2 void CreateOptimize();/創(chuàng)立一個(gè)優(yōu)化后四元式頭部 void CreateOptimize_Block();/創(chuàng)立一個(gè)優(yōu)化后塊頭部 void Div

45、ideBlock();/塊劃分函數(shù) void CoutBlock();/按基本塊輸出四元式 void CreateDAG();/創(chuàng)立一個(gè)DAG void DeleteDAG();/刪除DAG void AddDAG();/加入一個(gè)DAG點(diǎn) int FindDAG();/檢查重復(fù)DAG結(jié)點(diǎn) int FindDAG_unary();/檢查單目運(yùn)算符重復(fù)DAG結(jié)點(diǎn) int FindDAG_Bi();/檢查雙目運(yùn)算符重復(fù)DAG結(jié)點(diǎn) int MainMark();/檢查該標(biāo)記是不是主標(biāo)記 void SwopMark();/交換兩個(gè)標(biāo)記 void DeleteMark();/刪除一個(gè)標(biāo)記 void Get

46、DAG();/得到DAG生成結(jié)果 void CoutOptimize();/輸出優(yōu)化后的四元式public: struct Quaternary* optimize;/優(yōu)化四元式 struct Block* optimize_block;/優(yōu)化后的塊 struct Block* block;/塊指針 void Optimize(); Optimization()dag_head=NULL;dag_tail=NULL;dag_now=NULL;目標(biāo)代碼生成:class ObjectCode:public Optimization/目標(biāo)代碼生成模塊private: struct Object* o

47、bj_now;/當(dāng)前目標(biāo)代碼 struct Object* obj_find;/回溯找到的目標(biāo)代碼位置 struct Block* blo; struct Quaternary* qua; struct Operand* num;/當(dāng)前操作數(shù) char numType;/操作數(shù)的類(lèi)型 int find_num;/需要查找的系統(tǒng)變量名稱(chēng) int lab;/標(biāo)號(hào) char type_find;/需要查找的目標(biāo)代碼類(lèi)型,i為if,e為else,d為do,用于回溯重填跳轉(zhuǎn)位置 int SystemExist();/查找符號(hào)表中是否有必須的中間變量 void UpdateSymbol();/更新符號(hào)表,

48、將系統(tǒng)生成中間變量放入 void GetObjCode();/生成目標(biāo)代碼 void AddObject();/加入obj結(jié)點(diǎn) void CoutObj();/輸出目標(biāo)代碼 void Judge(string& st);/獲取操作數(shù)類(lèi)型,存到numType int Find_obj();/從后向前尋找相應(yīng)類(lèi)型的首個(gè)目標(biāo)代碼語(yǔ)句 int Find_obj_head();/從前向后尋找相應(yīng)類(lèi)型的首個(gè)目標(biāo)代碼語(yǔ)句 /目標(biāo)代碼生成函數(shù)(代碼段具體語(yǔ)句) void MOV_BX_A(); void MOV_BX_B(); void MOV_CX_B(); void MOV_C_BX(); void MO

49、V_C_CX(); void MOV_A_BX(); void MOV_AX_A(); void MOV_C_AX(); void MOV_DX_ZERO(); void MOV_C_DX(); void MOV_CX_ONE(); void MOV_CX_ZERO(); void CMP_AX_BX(); void CMP_AX_ZERO(); void CMP_BX_ZERO(); void GetHead();/目標(biāo)代碼頭部生成(含數(shù)據(jù)段) void GetTail();/目標(biāo)代碼尾部生成public: struct Object* obj;/目標(biāo)代碼指針 void ObjCode();

50、/目標(biāo)代碼主函數(shù) ObjectCode()lab=0;/構(gòu)造函數(shù);4.3實(shí)驗(yàn)結(jié)果測(cè)試樣例1:void main() int a,b; struct A int c; int d; ; a=1; b=1; while(b5) if(a%2=0) cout a; else b+; +a; 詞法分析模塊:輸出結(jié)果如下所示,顯示為結(jié)果為行數(shù)、token值、單詞。 圖4.2 詞法分析結(jié)果語(yǔ)法分析模塊:變量的定義會(huì)被保存在符號(hào)表中,用于之后的標(biāo)識(shí)符檢測(cè)和最后的目標(biāo)代碼生成階段,符號(hào)表存儲(chǔ)結(jié)果如下圖。圖4.3 符號(hào)表顯示 該模塊會(huì)執(zhí)行相應(yīng)的語(yǔ)義動(dòng)作并生成中間代碼四元式,產(chǎn)生的四元式結(jié)果如下圖所示。圖4.4

51、四元式顯示結(jié)果中間代碼優(yōu)化:中間代碼優(yōu)化采用DAG算法按照基本塊進(jìn)行四元式優(yōu)化,得到的最后優(yōu)化四元式結(jié)果如下圖所示。圖4.5 優(yōu)化后四元式結(jié)果目標(biāo)代碼生成:目標(biāo)代碼模塊會(huì)產(chǎn)生相應(yīng)的匯編代碼,并最終生成可編譯的.ASM匯編文件,生成的最終文件結(jié)果如下圖所示。 圖4.6 目標(biāo)代碼生成結(jié)果該模塊已經(jīng)配置好了相應(yīng)環(huán)境,會(huì)自動(dòng)調(diào)用匯編的編譯文件生成可執(zhí)行文件,并自動(dòng)執(zhí)行該可執(zhí)行文件,從而向屏幕打印輸出源程序的結(jié)果,實(shí)現(xiàn)完整的編譯程序。運(yùn)行結(jié)果如下圖所示。圖4.7 源程序結(jié)果顯示測(cè)試樣例2:void main() int a,b,c; a=1; b=1; c=15; while(a=5) cout a+;

52、 cout c; while(b=5) cout +b; 詞法分析: 圖4.8 詞法分析結(jié)果語(yǔ)法分析:圖4.9 四元式生成結(jié)果中間代碼優(yōu)化:圖4.10 中間代碼優(yōu)化結(jié)果目標(biāo)代碼生成: 圖4.11 匯編代碼生成結(jié)果圖4.12 程序運(yùn)行結(jié)果程序容錯(cuò)性測(cè)試:詞法錯(cuò)誤檢測(cè):測(cè)試樣例:int main() real a,b; char c; char d10; a=1.5; b=1.; c=a; d=hello;該測(cè)試用樣具有明顯的詞法錯(cuò)誤,如實(shí)數(shù)小數(shù)點(diǎn)后直接跟了分號(hào)結(jié)束,字符數(shù)據(jù)缺少右半邊單引號(hào),字符串?dāng)?shù)據(jù)缺少右半邊雙引號(hào)。當(dāng)輸入錯(cuò)誤單詞形式或者程序無(wú)法識(shí)別的字符時(shí),詞法分析器會(huì)檢測(cè)到該錯(cuò)誤單詞,并提

53、示錯(cuò)誤所在行數(shù),測(cè)試結(jié)果如下圖所示。 圖4.13 詞法錯(cuò)誤檢測(cè)語(yǔ)法和語(yǔ)義錯(cuò)誤檢測(cè):測(cè)試樣例:int main() real a; int c; a=1.5; b=1.23; c=3*d; 該測(cè)試樣例的變量定義存在錯(cuò)誤,能夠看到變量b和變量d都是未定義的標(biāo)識(shí)符,而且測(cè)試樣例存在語(yǔ)法錯(cuò)誤,第三行多了一個(gè)分號(hào)。因此在語(yǔ)法模塊中會(huì)對(duì)其進(jìn)行檢測(cè),將未被定義的錯(cuò)誤記錄在錯(cuò)誤表中。測(cè)試結(jié)果如下所示。圖4.14 語(yǔ)法錯(cuò)誤和變量定義錯(cuò)誤檢測(cè)5.系統(tǒng)特色(1)設(shè)計(jì)實(shí)現(xiàn)了一個(gè)完整的編譯程序,包括詞法分析、語(yǔ)法分析、語(yǔ)義分析和中間代碼生成、中間代碼優(yōu)化以及目標(biāo)代碼的生成。(2)經(jīng)過(guò)程序編譯能夠得到可執(zhí)行文件,并設(shè)計(jì)了

54、一個(gè)簡(jiǎn)單的cout輸出功能,能夠?qū)⒊绦虻倪\(yùn)行結(jié)果顯示到屏幕上,從而驗(yàn)證編譯程序的正確性。(3)語(yǔ)法上設(shè)計(jì)了前置+(-)和后置+(-)的類(lèi)C語(yǔ)言功能,能夠使用i+或者+i這種語(yǔ)法,而且運(yùn)算結(jié)果與C語(yǔ)言的運(yùn)算結(jié)果一致。(4)在語(yǔ)法上支持標(biāo)準(zhǔn)C語(yǔ)言的全部算術(shù)運(yùn)算、邏輯運(yùn)算、關(guān)系運(yùn)算以及位運(yùn)算,而且支持if-else條件語(yǔ)句和while循環(huán)語(yǔ)句。(5)具有編譯錯(cuò)誤提示的功能,能夠提示詞法錯(cuò)誤、語(yǔ)法錯(cuò)誤、標(biāo)識(shí)符未定義錯(cuò)誤、標(biāo)識(shí)符重復(fù)定義錯(cuò)誤等,而且會(huì)提示錯(cuò)誤所在行數(shù),方便用戶(hù)修改源程序,實(shí)現(xiàn)了良好的用戶(hù)體驗(yàn)。6.結(jié)論從總體上來(lái)說(shuō),我們?cè)O(shè)計(jì)實(shí)現(xiàn)了一個(gè)較為完整的擁有前端和后端、能夠生成可執(zhí)行文件而且能夠程序

55、運(yùn)行結(jié)果的簡(jiǎn)單編譯器,該編譯器的最終設(shè)計(jì)目的得到了實(shí)現(xiàn)。我們的編譯器能夠識(shí)別標(biāo)準(zhǔn)C語(yǔ)言所支持的絕大部分詞法符號(hào),而且具有詞法錯(cuò)誤記錄功能,能夠提示詞法錯(cuò)誤的位置。語(yǔ)法部分,我們的編譯器支持了變量的定義、數(shù)組的定義、函數(shù)的聲明、各類(lèi)表示式語(yǔ)句、if-else條件語(yǔ)句和while循環(huán)語(yǔ)句以及輸出結(jié)果的cout語(yǔ)句。在語(yǔ)義動(dòng)作上能夠生成相應(yīng)語(yǔ)句動(dòng)作的四元式,從而實(shí)現(xiàn)了編譯前端。同樣,在語(yǔ)法方面的錯(cuò)誤也會(huì)被記錄到錯(cuò)誤表內(nèi),并最終生成錯(cuò)誤記錄,提示給用戶(hù)。在編譯器的后端方面,我們的編譯器能夠?qū)ι傻乃脑叫蛄羞M(jìn)行DAG算法優(yōu)化,從而簡(jiǎn)化中間代碼,最后我們的編譯器能夠生成能夠執(zhí)行的匯編語(yǔ)言文件,并將其運(yùn)行

56、,實(shí)現(xiàn)源程序結(jié)果的輸出顯示,實(shí)現(xiàn)真正意義上的完整編譯運(yùn)行。由于時(shí)間緊任務(wù)重,我們編譯器總體設(shè)計(jì)上的功能得到了基本的實(shí)現(xiàn),美中不足的就是沒(méi)有來(lái)得及實(shí)現(xiàn)更多一些的功能,例如結(jié)構(gòu)體和函數(shù)調(diào)用等功能。盡管我們的語(yǔ)法結(jié)構(gòu)能夠支持這些語(yǔ)法,可是語(yǔ)義動(dòng)作的相關(guān)實(shí)現(xiàn)并沒(méi)有來(lái)得及做,這算是一個(gè)需要改進(jìn)和努力的地方。但總的來(lái)說(shuō),我們的編譯器設(shè)計(jì)任務(wù)還是取得了較好實(shí)現(xiàn)結(jié)果。7.參考文獻(xiàn)1、陳火旺.程序設(shè)計(jì)語(yǔ)言編譯原理(第3版). 北京:國(guó)防工業(yè)出版社. .2、美 Alfred V.Aho Ravi Sethi Jeffrey D. Ullman著.李建中,姜守旭譯.編譯原理.北京:機(jī)械工業(yè)出版社. .3、美 Ken

57、neth C.Louden著.馮博琴等譯.編譯原理及實(shí)踐.北京:機(jī)械工業(yè)出版社. .4、金成植著.編譯程序構(gòu)造原理和實(shí)現(xiàn)技術(shù). 北京:高等教育出版社. .8.收獲、體會(huì)和建議這次編譯原理的課程設(shè)計(jì)對(duì)于我來(lái)說(shuō),不得不說(shuō)是一個(gè)很大的挑戰(zhàn),雖然學(xué)習(xí)了編譯原理,知道了這些編譯過(guò)程是怎么一回事,可是要想把這個(gè)過(guò)程經(jīng)過(guò)程序來(lái)編寫(xiě)出來(lái),自己實(shí)現(xiàn)一個(gè)編譯器,對(duì)我來(lái)說(shuō)確實(shí)還是一個(gè)不小的挑戰(zhàn)。給我感受最深的就是張老師在給我們講課程設(shè)計(jì)要求時(shí),讓我們?cè)谠O(shè)計(jì)符號(hào)表結(jié)構(gòu)的時(shí)候設(shè)計(jì)一個(gè)能夠支持很多功能的表,可是在設(shè)計(jì)語(yǔ)法和功能時(shí)先從簡(jiǎn)單的開(kāi)始實(shí)現(xiàn),等到整個(gè)流程實(shí)現(xiàn)了之后,再增加新的功能,這樣因?yàn)榉?hào)表是按照整體布局來(lái)設(shè)計(jì)

58、的,再增添起來(lái)就比較容易,而不要一開(kāi)始設(shè)計(jì)很多的功能,不然到最后有可能寫(xiě)不完程序。設(shè)計(jì)結(jié)束之后我感到這份建議確實(shí)很重要,因?yàn)閷?duì)于寫(xiě)編譯器這個(gè)東西,我們都是新手,很難對(duì)整體的編譯器模塊設(shè)計(jì)有一個(gè)整體的把握,很多時(shí)候在設(shè)計(jì)這個(gè)模塊的數(shù)據(jù)結(jié)構(gòu)的時(shí)候,我都是比較迷茫的,因?yàn)椴恢酪O(shè)計(jì)成什么樣的結(jié)構(gòu)才能夠支持之后的功能。等到這部分程序功能真正寫(xiě)了出來(lái)才發(fā)現(xiàn)很多結(jié)構(gòu)部分都進(jìn)行了修改,這也是一個(gè)讓人很頭疼的問(wèn)題,因?yàn)橛昧私Y(jié)構(gòu)體方便于擴(kuò)展才沒(méi)有造成太大的困擾。等到編譯程序的大致框架和功能實(shí)現(xiàn)的差不多了的時(shí)候,我對(duì)編譯器的整體設(shè)計(jì)才有了一個(gè)較為清晰和完整的認(rèn)識(shí),包括每個(gè)模塊進(jìn)行什么樣的功能,它是如何實(shí)現(xiàn)這些功能的,什么時(shí)候要對(duì)符號(hào)表進(jìn)行操作,什么時(shí)候要進(jìn)行指針的連接等等。這些問(wèn)題在沒(méi)有真正開(kāi)始設(shè)計(jì)編譯器之前是不會(huì)想到的,可是一旦開(kāi)始設(shè)計(jì)了,就必須要面對(duì)這些問(wèn)題,每個(gè)問(wèn)題在得到解決之后,我對(duì)編譯器的設(shè)計(jì)細(xì)節(jié)就有了更深一步的了解。整個(gè)編譯器的設(shè)計(jì)過(guò)程中,我感覺(jué)最難的,最令我頭疼的部分必須是符號(hào)表的管理問(wèn)題了,什么時(shí)候填寫(xiě)符號(hào)表,什么時(shí)候進(jìn)行標(biāo)識(shí)符的檢查,不同語(yǔ)義動(dòng)作時(shí)應(yīng)該向符號(hào)表進(jìn)行何種數(shù)據(jù)交換,以及最后目標(biāo)代碼生成時(shí)如何使用符號(hào)表,這些問(wèn)題都是在編程過(guò)程中一步一步解決的,這也讓我受益匪淺,收獲頗多??傊?,這次編譯課設(shè)真的是至今為止大學(xué)期間最難的一次課程設(shè)計(jì)了,我

溫馨提示

  • 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ù)網(wǎng)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論