版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p> 畢業(yè)設(shè)計(jì)(論文)任務(wù)書</p><p><b> 第1頁(yè)</b></p><p> 畢業(yè)設(shè)計(jì)(論文)題目:C語言編譯器設(shè)計(jì)與實(shí)現(xiàn)畢業(yè)設(shè)計(jì)(論文)要求及原始數(shù)據(jù)(資料):1.C語言簡(jiǎn)介和國(guó)內(nèi)外編譯器技術(shù)研究現(xiàn)狀;2.深入了解編譯器前端,包括詞法分析,語法分析, 語義分析;3.熟練掌握C語言語法及語法特點(diǎn);4.深入分析編譯器編寫語言(C++);5.
2、設(shè)計(jì)并實(shí)現(xiàn)編譯過程中各個(gè)子過程,詞法分析,語法分析,語義分析;6.訓(xùn)練檢索文獻(xiàn)資料和利用文獻(xiàn)資料的能力;7.訓(xùn)練撰寫技術(shù)文檔與學(xué)位論文的能力。 </p><p><b> 第2頁(yè)</b></p><p><b> 第3頁(yè)</b></p><p> C語言編譯器設(shè)計(jì)與實(shí)現(xiàn)</p><p>&l
3、t;b> 摘 要</b></p><p> 隨著計(jì)算機(jī)的廣泛應(yīng)用,計(jì)算機(jī)程序設(shè)計(jì)語言也從初期的機(jī)器語言發(fā)展為匯編語言,以及現(xiàn)在的各種高級(jí)程序設(shè)計(jì)語言。而編譯技術(shù)是計(jì)算機(jī)語言發(fā)展的支柱,也是計(jì)算機(jī)科學(xué)中發(fā)展最迅速、最成熟的一個(gè)分支,他集中體現(xiàn)了計(jì)算機(jī)發(fā)展的成果與精華。</p><p> 其核心思想就是把同樣的邏輯結(jié)構(gòu)和思想從一種語言表示的程序轉(zhuǎn)換為另外一種語言表示的程
4、序。從高級(jí)語言,甚至運(yùn)行與虛擬平臺(tái)的高級(jí)語言,到機(jī)器語言,最終到硬件執(zhí)行的物理信號(hào),這一層層的轉(zhuǎn)化,都涉及編譯技術(shù)的應(yīng)用。</p><p> 本系統(tǒng)采用C++為編程語言。論文主要介紹了本課題的開發(fā)背景,所要完成的功能和開發(fā)的過程。重點(diǎn)的說明了系統(tǒng)設(shè)計(jì)的重點(diǎn)、設(shè)計(jì)思想、難點(diǎn)技術(shù)和解決方案。</p><p> 關(guān)鍵詞:編譯技術(shù),編程程序,高級(jí)語言</p><p>
5、 C language compiler design and Implementation</p><p><b> Abstract</b></p><p> With the wide application of the computer, computer programming languages ??are developed from the ea
6、rly machine language into assembly language , and now a variety of high-level programming language. The compiler technology is the backbone of computer language development, but also the fastest growing in computer scien
7、ce , a branch of the most mature , he epitomizes the essence of the computer and the fruits of development .</p><p> The core idea is the same logical structure of the program and ideas expressed in the con
8、version from one language to another language program represented . From the high-level language , and even running with high-level language virtual platform to machine language , and ultimately to the hardware implement
9、ation of the physical signal , the layers of transformation involves application of compiler technology .</p><p> System uses C++ as the programming language. Paper introduces the development background of
10、the topic, the development and function to complete the process. Note the focus of systems design, design ideas, technologies and solutions difficult. </p><p> Key Words: Compiler technology,Programming pro
11、cedures,High-level programming language</p><p><b> 目 錄</b></p><p><b> 摘 要i</b></p><p> Abstractii</p><p><b> 第一章 緒論1</b><
12、;/p><p> 1.1 開發(fā)背景1</p><p> 1.2 開發(fā)目標(biāo)和意義1</p><p> 1.2 當(dāng)前編譯器國(guó)內(nèi)外的發(fā)展情況2</p><p> 第二章 理論基礎(chǔ)4</p><p> 2.1 編譯系統(tǒng)概述4</p><p> 2.1.1 什么是編譯器4<
13、;/p><p> 2.1.2 編譯器的產(chǎn)生4</p><p> 2.2 編譯器的結(jié)構(gòu)4</p><p> 2.3 編譯器的組織6</p><p> 2.3.1 編譯的分遍6</p><p> 2.3.2 分遍的設(shè)計(jì)6</p><p> 2.4 編譯器中的主要數(shù)據(jù)結(jié)構(gòu)
14、7</p><p> 2.5 編譯程序的開發(fā)7</p><p> 2.5.1 歷史與發(fā)展7</p><p> 2.5.2 開發(fā)注意事項(xiàng)7</p><p> 2.5.3 編譯技術(shù)和軟件工具7</p><p> 第三章 C編譯器可行性分析及總體設(shè)計(jì)9</p><p>
15、 3.1 可行性分析9</p><p> 3.1.1 經(jīng)濟(jì)可行性9</p><p> 3.1.2 技術(shù)可行性9</p><p> 3.1.3 運(yùn)行可行性9</p><p> 3.1.4 時(shí)間可行性10</p><p> 3.1.5 法律可行性10</p><p>
16、 3.2 C語言的基本描述10</p><p> 3.3 C編譯器的功能10</p><p> 3.4 C編譯器的程序結(jié)構(gòu)11</p><p> 3.4.1 C編譯器的設(shè)計(jì)模式11</p><p> 3.4.2 C編譯器的文件組成12</p><p> 3.5 C編譯器中的主要數(shù)據(jù)結(jié)構(gòu)
17、12</p><p> 第四章 C編譯器的實(shí)現(xiàn)14</p><p> 4.1 詞法分析階段14</p><p> 4.1.1 概述14</p><p> 4.1.2 C詞法分析程序的實(shí)現(xiàn)14</p><p> 4.1.3 關(guān)鍵字與標(biāo)識(shí)符的識(shí)別16</p><p>
18、 4.1.4 詞法識(shí)別具體實(shí)現(xiàn)16</p><p> 4.2 語法分析階段18</p><p> 4.2.1 概述18</p><p> 4.2.2 C語言抽象出來的文法規(guī)則19</p><p> 4.2.3 C語法分析程序的實(shí)現(xiàn)22</p><p> 4.3 語義分析階段27<
19、/p><p> 4.3.1 概述27</p><p> 4.3.2 C語言的語義27</p><p> 4.3.3 C的符號(hào)表27</p><p> 4.3.4 C語義分析程序的實(shí)現(xiàn)28</p><p> 4.4 中間代碼生成階段33</p><p> 4.4.1
20、概述33</p><p> 4.5 C編譯器的使用方法及測(cè)試33</p><p> 4.5.1 使用方法33</p><p> 4.5.2 測(cè)試源文件34</p><p> 4.5.3 測(cè)試詞法分析34</p><p> 4.5.4 測(cè)試語義分析及中間代碼生成35</p>
21、<p> 4.5.5 測(cè)試分析表文件的構(gòu)造36</p><p><b> 參考文獻(xiàn)38</b></p><p><b> 致謝39</b></p><p><b> 第一章 緒論</b></p><p><b> 1.1 開發(fā)背景<
22、;/b></p><p> 隨著計(jì)算機(jī)科學(xué)技術(shù)的飛速發(fā)展,計(jì)算機(jī)技術(shù)被應(yīng)用在了越來越廣泛的領(lǐng)域,實(shí)現(xiàn)各種各樣功能的計(jì)算機(jī)程序被大量地開發(fā)出來,應(yīng)用在我們的生活、學(xué)習(xí)和工作當(dāng)中。相應(yīng)地,也產(chǎn)生了許多用以編寫這些計(jì)算機(jī)程序的高級(jí)程序設(shè)計(jì)語言。程序編制者通過特定語言的編譯器將自己編寫的源程序翻譯為特定機(jī)器上的目標(biāo)程序,從而能夠最終達(dá)到程序執(zhí)行的目的。</p><p> 從20世紀(jì)60年
23、代以來,編譯器設(shè)計(jì)就一直是計(jì)算機(jī)研究發(fā)展和開發(fā)領(lǐng)域中的一個(gè)活躍主題。雖然編譯器設(shè)計(jì)已有很長(zhǎng)的歷史,并且也是一門相對(duì)成熟的計(jì)算機(jī)技術(shù),但編譯器畢竟是一種實(shí)現(xiàn)由高級(jí)語言源程序至機(jī)器或匯編指令的高效映射工具,隨著計(jì)算機(jī)軟、硬件水平的飛速發(fā)展,使得計(jì)算機(jī)應(yīng)用日新月異,程序語言的設(shè)計(jì)在不斷地變化,目標(biāo)機(jī)體系結(jié)構(gòu)也在不斷地改進(jìn),軟件越來越復(fù)雜,其規(guī)模也越來越大。盡管編譯器設(shè)計(jì)問題在高級(jí)層次上沒有變化(或變化很?。?,但當(dāng)我們深入其內(nèi)部研究時(shí)就會(huì)發(fā)現(xiàn),
24、編譯器的內(nèi)部構(gòu)造其實(shí)也一直在變化。此外,由于我們能夠提供給編譯器本身使用的計(jì)算資源也在不斷增加。因此,現(xiàn)代編譯器可以采用比以前更耗費(fèi)時(shí)間和空間的算法。當(dāng)然,編譯技術(shù)研究人員也在繼續(xù)努力開發(fā)新的、更好的技術(shù)來解決傳統(tǒng)編譯器的一些設(shè)計(jì)性問題[1]。</p><p> 另一方面,很多編譯“前端”技術(shù),如文法、正則表達(dá)式、語法分析器以及語法制導(dǎo)翻譯器等,仍然被廣泛使用。</p><p> 1.
25、2 開發(fā)目標(biāo)和意義</p><p> 編譯器是一種相當(dāng)復(fù)雜的系統(tǒng)程序,其代碼的長(zhǎng)度可從幾千行到幾百萬行不等,所以編寫甚至讀懂這樣的一個(gè)程序都不是一件容易的事。絕大多數(shù)的計(jì)算機(jī)專業(yè)人員從來沒有編寫過一個(gè)完整的編譯器,但是,幾乎所有形式的計(jì)算均要用到編譯器,而且任何一個(gè)與計(jì)算機(jī)打交道的專業(yè)人員都應(yīng)該掌握編譯器的基本結(jié)構(gòu)和操作。除此之外,計(jì)算機(jī)應(yīng)用程序中經(jīng)常遇到的一個(gè)任務(wù)就是有關(guān)命令解釋程序和界面程序的開發(fā),這比編
26、譯器的開發(fā)規(guī)模要小,但使用的卻是很類似的技術(shù)。因此,掌握編譯器的開發(fā)技術(shù)具有非常重大的實(shí)際意義。</p><p> 編譯器的設(shè)計(jì)的原理和技術(shù)還可以用于編譯器設(shè)計(jì)之外的眾多領(lǐng)域。因此,這些原理和技術(shù)通常會(huì)在一個(gè)計(jì)算機(jī)科學(xué)家的職業(yè)生涯中多次被用到。研究編譯器的編寫講設(shè)計(jì)程序設(shè)計(jì)語言、計(jì)算機(jī)體系結(jié)構(gòu)、形式語言理論、算法和軟件工程。</p><p> 編譯器的設(shè)計(jì)從本質(zhì)上來說是一種工程活動(dòng),它
27、所使用的方法必須很好地解決現(xiàn)實(shí)中出現(xiàn)的各種翻譯問題(即用真實(shí)的語言編制且在真實(shí)的機(jī)器上能夠執(zhí)行的真實(shí)的程序)。大多數(shù)情況下,開發(fā)編譯器的人必須接受他們面對(duì)的語言和機(jī)器,很少能夠去影響或改善這兩者的設(shè)計(jì)。在開發(fā)過程中做什么樣的分析和轉(zhuǎn)換,以及什么時(shí)候去做,這些都是工程上的選擇,但正是這些選擇決定了一個(gè)編譯器的性能高低。本實(shí)驗(yàn)就建立在一個(gè)自主開發(fā)的名為C的微型編譯器基礎(chǔ)之上,該編譯器雖然功能弱于像Turbo C或Borland Pascal
28、這樣的經(jīng)典編譯器,但也已經(jīng)完全具備了一個(gè)編譯器應(yīng)有的所有特征。</p><p> 雖然本實(shí)驗(yàn)只是一個(gè)規(guī)模很小的微型編譯器的開發(fā),但所謂“麻雀雖小,五臟俱全”,作為一次較為完整的編譯開發(fā)實(shí)踐,它已經(jīng)足夠讓我透徹地了解一個(gè)編譯器開發(fā)過程了,同時(shí)能更深刻地理解和運(yùn)用編譯開發(fā)過程中的眾多技術(shù)和方法,并能在此基礎(chǔ)上針對(duì)編譯器的優(yōu)化展開深入的討論,這些對(duì)于自己以后的研究和發(fā)展方向?qū)⑵鸬椒浅4蟮耐苿?dòng)作用。</p>
29、<p> C編譯器以C++語言作為開發(fā)語言,以Microsoft Visual Studio2012作為開發(fā)工具,C編譯器的各個(gè)階段以類的形式表示,最后以項(xiàng)目文件為單位來編譯生成C編譯器的可執(zhí)行文件。</p><p> 本實(shí)驗(yàn)以Microsoft Visual Studio2012作為開發(fā)工具,用標(biāo)準(zhǔn)C++進(jìn)行開發(fā),因此可以很好的的移植到其他平臺(tái)(比如:linux,用g++編譯生成可執(zhí)行文件)。
30、</p><p> 1.2 當(dāng)前編譯器國(guó)內(nèi)外的發(fā)展情況</p><p> 在編譯器技術(shù)的發(fā)展過程中,如何提高編譯的效率一直是核心研究目標(biāo)之一,編譯效率主要是根據(jù)該編譯器所生成的目標(biāo)代碼在執(zhí)行過程中的時(shí)間指標(biāo)和空間指標(biāo)來衡量的,所以編譯優(yōu)化也必定圍繞時(shí)間和空間這兩個(gè)方面來實(shí)施。在編譯過程中針對(duì)代碼優(yōu)化的技術(shù)有很多,它們通常是通過搜集源代碼或中間代碼的特定信息,然后利用這些信息對(duì)代碼中的數(shù)
31、據(jù)結(jié)構(gòu)或算法操作實(shí)施等價(jià)的改進(jìn)變換,從而力求在時(shí)間效率和空間效率上達(dá)到一個(gè)最佳平衡點(diǎn)。編譯器的開發(fā)者們總是希望能夠?qū)⒏鞣N代碼優(yōu)化技術(shù)充分地運(yùn)用在自己的編譯器設(shè)計(jì)中,但往往事與愿違,畢竟優(yōu)化操作本身也是需要付出開銷的。在C編譯器的開發(fā)過程中,雖然沒有運(yùn)用到太復(fù)雜的代碼優(yōu)化技術(shù),但通過本實(shí)驗(yàn)的研究,在現(xiàn)有開發(fā)的C編譯器基礎(chǔ)之上,能夠在后續(xù)相關(guān)項(xiàng)目的開發(fā)中有效地提高程序代碼的編譯質(zhì)量,對(duì)于自己以后的研究和發(fā)展方向?qū)⑵鸬椒浅4蟮耐苿?dòng)作用。這正是
32、本實(shí)驗(yàn)的研究意義所在。</p><p> 本實(shí)驗(yàn)是以C微型編譯器的項(xiàng)目開發(fā)為基礎(chǔ),該項(xiàng)目的開發(fā)目標(biāo)是自定義一種C高級(jí)語言,然后編碼實(shí)現(xiàn)出C語言的編譯器(稱為C編譯器),完成將C語言源程序翻譯為基于MM機(jī)(Mini Machine)的目標(biāo)代碼的任務(wù),這是本實(shí)驗(yàn)的實(shí)際應(yīng)用背景。</p><p> 編譯器的開發(fā)具有極高的實(shí)用價(jià)值和意義,高級(jí)語言編譯器的性能決定了基于該語言平臺(tái)所開發(fā)出的軟件的
33、質(zhì)量。所以國(guó)內(nèi)外很多大學(xué)的科研和技術(shù)人員也在積極地開展這方面的技術(shù)探索和項(xiàng)目實(shí)踐。他們大多是以特定的軟件項(xiàng)目為背景來進(jìn)行一些與編譯器開發(fā)相關(guān)或類似的研究分析,他們的研究目標(biāo)大多是基于某種實(shí)驗(yàn)型高級(jí)語言的編譯器開發(fā)和優(yōu)化改進(jìn),然后把有價(jià)值的研究成果移植或運(yùn)用到產(chǎn)品級(jí)的編譯器開發(fā)中(比如.NET平臺(tái)編譯器)。</p><p> 最近十年以來,國(guó)外關(guān)于編譯器設(shè)計(jì)的發(fā)展動(dòng)態(tài)主要體現(xiàn)在:首先,編譯器采用了大量的更加復(fù)雜的
34、算法,主要用于推斷或簡(jiǎn)化程序中的信息,這又與更為復(fù)雜的程序設(shè)計(jì)語言的發(fā)展結(jié)合在一起,其中典型的有用于函數(shù)語言編譯的Hindley-Milner類型檢查的統(tǒng)一算法[2]。其次,編譯器已越來越成為基于窗口的可視化交互開發(fā)環(huán)境(Interactive Development Environment,IDE)的一部分,該環(huán)境還包括了智能編輯器、連接程序、調(diào)試程序以及項(xiàng)目管理程序等,已經(jīng)成為了事實(shí)上的編譯器行業(yè)標(biāo)準(zhǔn)。另一方面,盡管國(guó)內(nèi)外的專家學(xué)者
35、們近年來在編譯原理領(lǐng)域進(jìn)行了大量的研究,但是基本的編譯器設(shè)計(jì)原理在近20年中都沒有多大的改變,它現(xiàn)在正迅速地成為計(jì)算機(jī)科學(xué)課程中的中心環(huán)節(jié)之一。</p><p> 在九十年代,作為GNU項(xiàng)目或其它開放源代碼項(xiàng)目的一部分,許多免費(fèi)的編譯器或編譯器構(gòu)造工具被開發(fā)出來。這些工具可用來編譯數(shù)種程序設(shè)計(jì)語言的源程序(典型的就是GCC)。它們中的一些項(xiàng)目被認(rèn)為是高質(zhì)量的,而且對(duì)現(xiàn)代編譯理論感興趣的人都可以較容易地得到它們的
36、免費(fèi)源代碼。典型的是在1999年,SGI公布了他們的一個(gè)工業(yè)化的并行優(yōu)化編譯器Pro64的源代碼,隨后被全世界多個(gè)編譯器研究小組用做研究平臺(tái),并命名為Open64。Open64的設(shè)計(jì)結(jié)構(gòu)好,分析優(yōu)化全面,是編譯器高級(jí)研究的理想平臺(tái)。</p><p> 反觀國(guó)內(nèi),現(xiàn)階段對(duì)于編譯技術(shù)的相關(guān)研究,基本上都是著眼于特定編譯器的特定部分來展開的,而本實(shí)驗(yàn)將研究和分析的重點(diǎn)主要集中于一個(gè)完整的微型編譯器的構(gòu)造的討論。<
37、;/p><p><b> 第二章 理論基礎(chǔ)</b></p><p> 2.1 編譯系統(tǒng)概述</p><p> 2.1.1 什么是編譯器</p><p> 編譯器,是將便于人類編寫、閱讀、維護(hù)的計(jì)算機(jī)高級(jí)語言程序翻譯為機(jī)器能夠識(shí)別、運(yùn)行的計(jì)算機(jī)低級(jí)語言程序的一種系統(tǒng)軟件。編譯器將源程序(Source Program
38、)作為輸入,翻譯產(chǎn)生使用目標(biāo)語言的等價(jià)目標(biāo)程序((Target Program)。其中,源程序一般為高級(jí)語言(High-level language),如Pascal,C++等,而目標(biāo)語言則是匯編語言或目標(biāo)機(jī)器的機(jī)器語言[3]。編譯器的這一作用如圖2-1所示:</p><p> 圖2-1 編譯器的作用</p><p> 2.1.2 編譯器的產(chǎn)生</p><p>
39、; 本世紀(jì)四十年代,由于馮·諾依曼在存儲(chǔ)程序計(jì)算機(jī)方面的先鋒作用,使得編寫一串代碼或程序已成為可能和必要,這樣計(jì)算機(jī)就可以執(zhí)行所需的計(jì)算。在初期,這些程序都是用機(jī)器語言編寫,編寫或維護(hù)這樣的代碼是非??菰锓ξ肚倚实拖碌模詸C(jī)器語言很快就被匯編語言代替了。匯編語言大大提高了程序編寫速度和準(zhǔn)確度,但它也有許多缺點(diǎn)。于是發(fā)展編程技術(shù)的下一個(gè)重要革新就是以一個(gè)更加類似于數(shù)學(xué)定義或自然語言的簡(jiǎn)潔形式來編寫程序的功能操作,它應(yīng)與任何
40、機(jī)器都無關(guān),而且也可由一個(gè)程序翻譯為可執(zhí)行的代碼。</p><p> 隨著對(duì)形式語言和自動(dòng)機(jī)理論的研究,人們對(duì)高級(jí)程序設(shè)計(jì)語言的認(rèn)識(shí)越來越深,對(duì)編譯器結(jié)構(gòu)的設(shè)計(jì)也越來越清晰。人們通過對(duì)形式語言文法規(guī)則的研究,相當(dāng)完善地解決了分析問題。當(dāng)分析問題變得相對(duì)成熟時(shí),設(shè)計(jì)者們又花費(fèi)了很多的精力來研究這一部分的編譯器的自動(dòng)構(gòu)造,這就是分析程序生成器(parser generator)最初的雛形。類似地,對(duì)有窮自動(dòng)機(jī)的研究
41、也促進(jìn)了一種稱為掃描程序生成器(scanner generator)工具的發(fā)展。接著,人們又深化了生成有效目標(biāo)代碼的方法,這些就構(gòu)成了傳統(tǒng)的編譯器,在這個(gè)過程中運(yùn)用到的技術(shù)被一直使用至今。</p><p> 2.2 編譯器的結(jié)構(gòu)</p><p> 嚴(yán)格地說,編譯器是一個(gè)將高級(jí)語言源程序轉(zhuǎn)換成能在一臺(tái)計(jì)算機(jī)上執(zhí)行的等價(jià)目標(biāo)代碼或機(jī)器語言程序的軟件系統(tǒng)。這個(gè)定義可擴(kuò)展到包含將一個(gè)高級(jí)語言
42、程序轉(zhuǎn)換成匯編語言程序的系統(tǒng),將一個(gè)高級(jí)語言程序轉(zhuǎn)換成另一種高級(jí)語言程序的系統(tǒng),從一個(gè)機(jī)器語言程序轉(zhuǎn)換成另一種機(jī)器語言程序的系統(tǒng),從一種高級(jí)語言程序轉(zhuǎn)換成一種中間語言程序的系統(tǒng),等等。</p><p> 在通常情況下,一個(gè)編譯器應(yīng)由一系列的階段組成,這些階段從要編譯的源程序的字符序列開始,依次對(duì)一個(gè)給定形式的程序進(jìn)行分析,并得到一種新的表示形式,在大多數(shù)情況下最終產(chǎn)生一個(gè)可以與其他目標(biāo)代碼鏈接,并裝入一臺(tái)機(jī)器的
43、存儲(chǔ)器中執(zhí)行的可重定位目標(biāo)模塊。這一編譯過程一般由如下6個(gè)階段構(gòu)成,它們執(zhí)行不同的邏輯操作如圖2-2所示[4]:</p><p> (1) 掃描程序(scanner)</p><p> 在這個(gè)階段,編譯器閱讀源程序(通常以字符流的形式表示,比如本實(shí)驗(yàn)設(shè)計(jì)的C語言的源程序.c),由掃描程序執(zhí)行詞法分析(lexical analysis):它將字符序列收集到稱為記號(hào)(token)的單元中,
44、也就是說,將其識(shí)別為一個(gè)個(gè)符合編程語言詞法規(guī)范的單詞符號(hào)。實(shí)際上,一個(gè)掃描程序所做的工作與自然語言中對(duì)英文單詞的拼寫是十分類似的。掃描程序還可完成與識(shí)別記號(hào)一起執(zhí)行的其他操作,例如,可將相應(yīng)的記號(hào)輸入到對(duì)應(yīng)的符號(hào)表中。</p><p> ?。?) 語法分析程序(parser)</p><p> 語法分析程序從掃描程序中獲取記號(hào)形式的代碼,并完成定義程序結(jié)構(gòu)的語法分析(syntax ana
45、lysis),根據(jù)語言的語法規(guī)則將上階段產(chǎn)生的單詞串分解成各類語法單位(如表達(dá)式、語句、子過程等),這與自然語言中關(guān)于某篇文章的句子的語法分析類似。語法分析定義了程序的結(jié)構(gòu)元素及其關(guān)系。通常將語法分析的結(jié)果表示為分析樹或語法樹。</p><p> ?。?) 語義分析程序(semantic analyzer)</p><p> 程序的語義就是它的“意思”,程序如何運(yùn)行以及運(yùn)行結(jié)果都由它的語
46、義來決定。大多數(shù)程序設(shè)計(jì)語言具有在執(zhí)行之前被確定語義的特征,這些特征不容易用語法結(jié)構(gòu)表示,更無法用詞法分析程序進(jìn)行分析,這些特征被稱為靜態(tài)語義。語義分析程序的職責(zé)就是分析這樣的語義,為代碼生成階段搜集相關(guān)的語義信息。一般程序設(shè)計(jì)語言的典型靜態(tài)語義有聲明和類型檢查。而在程序執(zhí)行階段才能確定的程序特性稱為動(dòng)態(tài)語義,語義分析程序無法對(duì)這類特性做出分析。語義分析程序還要計(jì)算被稱為屬性(attribute)的程序固有信息,如數(shù)據(jù)類型、值等。語義分
47、析程序通常將計(jì)算后的屬性值添加到語法樹中(也可將屬性添加到符號(hào)表中)。</p><p> ?。?) 源代碼優(yōu)化程序(source code optimizer)</p><p> 完善的編譯器通常包括許多代碼改進(jìn)和優(yōu)化步驟。這些優(yōu)化和改進(jìn)一般是在語義分析之后完成的。在語法分析和語義分析的基礎(chǔ)之上,將源程序變換為等價(jià)的中間代碼。所謂中間代碼,是指一種結(jié)構(gòu)簡(jiǎn)單、含義明確、形式多樣化的記號(hào)系統(tǒng)
48、,它比較容易能轉(zhuǎn)換為目標(biāo)代碼。優(yōu)化程序?qū)⒃创a以中間代碼(intermediate code)的形式輸出,進(jìn)而完成對(duì)源代碼的相應(yīng)優(yōu)化處理,目的是使將來生成的目標(biāo)代碼更為高效(即省時(shí)間、省空間)。</p><p> ?。?) 代碼生成器(code generator)</p><p> 這是編譯的最后必備階段,它將中間代碼(或經(jīng)優(yōu)化后的中間代碼)轉(zhuǎn)換成特定機(jī)器上的絕對(duì)指令代碼或可重新定位的
49、指令代碼或匯編指令代碼。由于該階段的工作與硬件系統(tǒng)結(jié)構(gòu)和機(jī)器指令含義有關(guān),涉及到硬件系統(tǒng)功能部件的運(yùn)用、機(jī)器指令的選擇、各種數(shù)據(jù)的存儲(chǔ)空間分配以及寄存器調(diào)度等,也就是說目標(biāo)機(jī)器的特性成為了主要因素,所以這個(gè)階段的工作相當(dāng)復(fù)雜。正是出于這點(diǎn)考慮,本實(shí)驗(yàn)設(shè)計(jì)選擇了與機(jī)器指令無關(guān)的三地址碼的四元式表示形式。</p><p> ?。?) 目標(biāo)代碼優(yōu)化程序(target code optimizer)</p>
50、<p> 在這個(gè)階段中,編譯器嘗試著改進(jìn)由代碼生成器生成的目標(biāo)代碼。這種改進(jìn)包括對(duì)編址模式的選擇、提高性能、將速度慢的指令更換成速度快的以及刪除多余的操作等。</p><p> 除了這6個(gè)階段,編譯器通常還包含一張符號(hào)表和訪問該表的若干例程,以及針對(duì)編譯過程中發(fā)現(xiàn)的各種錯(cuò)誤進(jìn)行檢查和處理的錯(cuò)誤處理程序,它們?cè)诰幾g過程的所有階段都會(huì)使用到。</p><p> 上述編譯過程的
51、階段劃分只是一個(gè)典型模式,事實(shí)上并非所有的編譯程序都分成這6個(gè)階段,有些編譯程序并不生成中間代碼,有些編譯程序并不進(jìn)行優(yōu)化,有些最簡(jiǎn)單的編譯程序甚至在語法分析的同時(shí)產(chǎn)生目標(biāo)代碼。編譯器生成的目標(biāo)代碼可以是可重定位目標(biāo)代碼或匯編代碼,如果是匯編代碼則需要再用匯編器來生成可重定位目標(biāo)代碼,本實(shí)驗(yàn)設(shè)計(jì)的C編譯器生成的目標(biāo)代碼是三地址碼的四元式表示形式。</p><p> 2.3 編譯器的組織</p>
52、<p> 2.3.1 編譯的分遍</p><p> 在2.2節(jié)中我們討論了一個(gè)編譯器的典型結(jié)構(gòu),簡(jiǎn)要介紹了編譯器的6個(gè)階段各自應(yīng)完成的基本工作,并通過圖2-2指出了它們之間的相互關(guān)系,但需要注意的是,這些關(guān)系僅代表它們之間的邏輯關(guān)系,并不一定就是執(zhí)行時(shí)間上的先后順序。事實(shí)上,可按不同的執(zhí)行流程來組織上述各階段的工作,這在很大程度上依賴于編譯過程中對(duì)源程序掃描的遍數(shù),以及如何劃分各遍掃描所進(jìn)行的工作
53、。這里所說的“遍”,是指對(duì)源程序或其內(nèi)部表示從頭到尾掃視一次,并進(jìn)行有關(guān)的加工處理工作,每一遍的工作都是從獲取上一遍的工作結(jié)果開始,經(jīng)過本遍的加工后,將結(jié)果保存起來以便交給下一遍[5]。例如,對(duì)于要求經(jīng)一遍掃描就能完成從源代碼到目標(biāo)代碼翻譯的編譯程序,我們可以語法分析程序?yàn)橹行膩斫M織它的工作流程,這樣就不必產(chǎn)生中間代碼,顯然,這種做法所得到的目標(biāo)代碼的質(zhì)量是不能保證的,總體來說弊大于利。</p><p> 對(duì)于
54、絕大部分語言(例如Pascal或C),實(shí)現(xiàn)一遍掃描的編譯程序是非常困難的,所以宜于采用多遍掃描的編譯程序結(jié)構(gòu)。具體的做法是將整個(gè)編譯程序劃分為若干個(gè)相繼執(zhí)行的模塊,每一模塊都對(duì)它前一模塊的輸出掃描一遍,并在掃描過程中完成前述6個(gè)階段中的一個(gè)或幾個(gè),然后將工作結(jié)果保存下來供下一模塊加工。顯然,第一個(gè)模塊所掃描的是字符序列形式的源程序,最后一個(gè)模塊所輸出的是目標(biāo)代碼,而每一個(gè)中間模塊輸出的是與源程序等價(jià)的內(nèi)部表示或中間代碼。</p&g
55、t;<p> 2.3.2 分遍的設(shè)計(jì)</p><p> 在設(shè)計(jì)一個(gè)編譯程序時(shí),如何確定掃描遍數(shù),如何組織各遍中的工作,主要取決于源語言的具體情況及編譯程序運(yùn)行的具體環(huán)境,如語言的結(jié)構(gòu)、計(jì)算機(jī)軟硬件的配置,以及對(duì)編譯程序本身運(yùn)行效率的要求等等。一般而言,多遍掃描源程序具有如下優(yōu)點(diǎn):</p><p> ?。?) 由于采用了模塊結(jié)構(gòu),各遍掃描的功能相對(duì)獨(dú)立,整個(gè)編譯程序的結(jié)構(gòu)
56、比較清晰。</p><p> ?。?) 由于對(duì)源程序及其內(nèi)部表示進(jìn)行多次掃視和加工,有利于進(jìn)行比較細(xì)致和充分的代碼優(yōu)化處理。</p><p> ?。?) 由于可將編譯程序按模塊依次調(diào)入內(nèi)存,有利于采用覆蓋技術(shù),以減少執(zhí)行編譯程序時(shí)所占的內(nèi)存空間。</p><p> 由于分遍問題對(duì)具體語言及編譯程序的運(yùn)行環(huán)境有很強(qiáng)的依賴性,經(jīng)過權(quán)衡,本實(shí)驗(yàn)設(shè)計(jì)的編譯器采用了簡(jiǎn)單的1
57、遍掃描策略。</p><p> 2.4 編譯器中的主要數(shù)據(jù)結(jié)構(gòu)</p><p> 當(dāng)然,編譯器的各個(gè)階段使用的算法與支持這些階段的數(shù)據(jù)結(jié)構(gòu)之間的交互是非常密切的。編譯器的編寫者在實(shí)施這些算法的同時(shí)應(yīng)盡可能地保證它們不過于復(fù)雜,最理想的情況是:該編譯器在編譯時(shí)所耗費(fèi)的時(shí)間與程序大小成線形比例,即時(shí)間復(fù)雜度為O(n)。能否達(dá)到這樣的理想情況,很大程度上取決于所采用的數(shù)據(jù)結(jié)構(gòu),它們是各個(gè)階
58、段都需要使用到的,并用來在各階段之間交流信息。通常編譯器中的主要數(shù)據(jù)結(jié)構(gòu)包括:記號(hào)、語法樹、符號(hào)表、常數(shù)表、中間代碼、臨時(shí)文件等。 </p><p> 2.5 編譯程序的開發(fā)</p><p> 2.5.1 歷史與發(fā)展</p><p> 在編譯器開發(fā)的原始階段,人們主要用機(jī)器語言或匯編語言來構(gòu)造編譯程序,難度極大且效率很低?,F(xiàn)在的大部分編譯器是用某種高級(jí)語言
59、開發(fā)的,這樣更節(jié)約時(shí)間,而且易讀、易改、易移植,同時(shí)也便于進(jìn)行編譯器的優(yōu)化設(shè)計(jì)。相信在不久的將來,編譯器的開發(fā)將主要借助于成熟的自動(dòng)化生成編譯程序技術(shù)。</p><p> 2.5.2 開發(fā)注意事項(xiàng)</p><p> ?。?) 源語言:對(duì)被編譯的源語言,要深刻理解其結(jié)構(gòu)和含義。在定義C語言的過程中,是通過嚴(yán)格制定其詞法規(guī)則、語法規(guī)則和語義規(guī)則來達(dá)到的。</p><p&
60、gt; ?。?) 目標(biāo)語言: C編譯器的目標(biāo)語言選擇為三地址的四元表達(dá)式。</p><p> ?。?) 編譯技術(shù):詞法分析、語法分析、語義分析、代碼優(yōu)化及代碼生成的相關(guān)技術(shù)有很多,必須根據(jù)所開發(fā)的編譯器的需求和特點(diǎn)來選擇最合適的編譯技術(shù)和方法。關(guān)于C編譯器中使用到的編譯技術(shù)可詳細(xì)參考論文第四章。</p><p> (4) 各種具體因素:例如系統(tǒng)功能要求、硬件開發(fā)環(huán)境、軟件開發(fā)工具等。&l
61、t;/p><p> 2.5.3 編譯技術(shù)和軟件工具</p><p> 為了提高軟件開發(fā)的效率和保證開發(fā)質(zhì)量,人們除了要遵循軟件工程中對(duì)軟件開發(fā)過程的規(guī)范化或標(biāo)準(zhǔn)化之外,還應(yīng)盡量使用先進(jìn)的軟件開發(fā)技術(shù)和相應(yīng)的軟件工具,而大部分軟件工具的開發(fā),常常要用到編譯技術(shù)和方法。實(shí)際上編譯程序本身也是一種軟件開發(fā)工具。為了提高編程效率,縮短調(diào)試時(shí)間,軟件工作人員研制了不少對(duì)源程序處理的工具,這些工具的
62、開發(fā)不同程度地用到編譯程序各個(gè)部分的技術(shù)和方法,典型的有下面幾種[7]:</p><p> ?。?) 語言的結(jié)構(gòu)化編輯器:結(jié)構(gòu)化編輯器是引導(dǎo)用戶在語言的語法制導(dǎo)下編制程序,能自動(dòng)地提供關(guān)鍵字和與其匹配的關(guān)鍵字,這樣可以減少語法上的錯(cuò)誤,加快對(duì)源程序的輸入和調(diào)試,提高效率和質(zhì)量?,F(xiàn)在的可視化開發(fā)工具基本都具備了這個(gè)功能。</p><p> ?。?) 語言程序的調(diào)試工具:調(diào)試是軟件開發(fā)過程中一
63、個(gè)重要環(huán)節(jié),凡是對(duì)算法的實(shí)現(xiàn)錯(cuò)誤或程序沒能反映算法的功能等錯(cuò)誤就需用調(diào)試器來協(xié)助解決。調(diào)試器的功能越強(qiáng)則實(shí)現(xiàn)越復(fù)雜,它必須與語法分析、語義處理有緊密聯(lián)系。</p><p> ?。?) 語言程序測(cè)試工具:對(duì)源程序進(jìn)行語法分析并制定相應(yīng)表格,檢查變量定值與引用的關(guān)系;也可在源程序的適當(dāng)位置插入某些信息,并用測(cè)試用例記錄程序運(yùn)行時(shí)的實(shí)際路徑,將運(yùn)行結(jié)果與期望的結(jié)果進(jìn)行比較分析,幫助編程人員快速查找問題所在。</p
64、><p> ?。?) 高級(jí)語言之間的轉(zhuǎn)換工具:為了減少重新編制程序所耗費(fèi)的人力和時(shí)間,就要解決如何把一種高級(jí)語言轉(zhuǎn)換成另一種高級(jí)語言,乃至匯編語言轉(zhuǎn)換成高級(jí)語言的問題,這種異種程序設(shè)計(jì)語言之間的翻譯轉(zhuǎn)換工作要對(duì)被轉(zhuǎn)換的語言進(jìn)行詞法和語法分析,只不過生成的目標(biāo)語言是另一種高級(jí)語言而已,這與實(shí)現(xiàn)一個(gè)完整的編譯程序相比工作量要少些。</p><p> ?。?) 并行編譯技術(shù):隨著并行機(jī)及多處理機(jī)的發(fā)
65、展,對(duì)軟件的并行處理提出了新的要求,特別是并行編譯技術(shù)發(fā)展很快。運(yùn)用重構(gòu)技術(shù)把已有的串行語言編寫的程序經(jīng)過分析分解成可并行的成分,然后分配到多處理機(jī)上運(yùn)行。如果編程人員能按程序設(shè)計(jì)情況寫出并行語言程序,那么兩者結(jié)合將產(chǎn)生更高的效率。</p><p> 第三章 C編譯器可行性分析及總體設(shè)計(jì)</p><p> 3.1 可行性分析 </p><p> 3.1.1 經(jīng)
66、濟(jì)可行性</p><p> 經(jīng)濟(jì)可行性研究是對(duì)組織的經(jīng)濟(jì)現(xiàn)狀和投資能力進(jìn)行分析,對(duì)系統(tǒng)建設(shè)運(yùn)行和維護(hù)費(fèi)用進(jìn)行估算,對(duì)系統(tǒng)建成后可能取得的社會(huì)和經(jīng)濟(jì)效益進(jìn)行估計(jì)。由于本系統(tǒng)是作為畢業(yè)設(shè)計(jì)由我們自己開發(fā)的,在經(jīng)濟(jì)上的投入甚微,系統(tǒng)建成之后將為今后C源程序的編譯提供很大的方便,估算新系統(tǒng)的開發(fā)費(fèi)用和今后的運(yùn)行、維護(hù)費(fèi)用,估計(jì)新系統(tǒng)將獲得的效益,并將費(fèi)用與效益進(jìn)行比較,看是否有利。開發(fā)、運(yùn)行和維護(hù)費(fèi)用主要包括:<
67、/p><p> 購(gòu)買和安裝設(shè)備的費(fèi)用:無。軟件開發(fā)費(fèi)用:若由實(shí)習(xí)單位的技術(shù)人員開發(fā),則該項(xiàng)費(fèi)用可以計(jì)入下面的人員費(fèi)用一項(xiàng);人員費(fèi)用:系統(tǒng)開發(fā)人員、操作人員和維護(hù)人員的工資、培訓(xùn)費(fèi)用等;消耗品費(fèi)用:系統(tǒng)開發(fā)所用材料、系統(tǒng)正常運(yùn)行所用消耗品,例如水、電費(fèi),打印紙、軟盤、色帶等開支。所有開支都不大,所以經(jīng)濟(jì)上是可行的。</p><p> 3.1.2 技術(shù)可行性</p><p
68、> 技術(shù)可行性要考慮現(xiàn)有的技術(shù)條件是否能夠順利完成開發(fā)工作,軟硬件配置是否滿足開發(fā)的需求等。C編譯系統(tǒng)用的是標(biāo)準(zhǔn)C++開發(fā)語言,調(diào)試相對(duì)簡(jiǎn)單,當(dāng)前的計(jì)算機(jī)硬件配置也完全能滿足開發(fā)的需求,因此在技術(shù)上是絕對(duì)可行的。軟件方面:由于目前BS模式軟件相對(duì)發(fā)展成熟,故軟件的開發(fā)平臺(tái)成熟可行,它們速度快、容量大、可靠性能高、價(jià)格低,完全能滿足系統(tǒng)的需求。</p><p> 3.1.3 運(yùn)行可行性</p>
69、;<p> 對(duì)新系統(tǒng)運(yùn)行后給現(xiàn)行系統(tǒng)帶來的影響(包括組織機(jī)構(gòu)、管理方式、工作環(huán)境等)和后果進(jìn)行估計(jì)和評(píng)價(jià)。同時(shí)還應(yīng)考慮現(xiàn)有管理人員的培訓(xùn)、補(bǔ)充,分析在給定時(shí)間里能否完成預(yù)定的系統(tǒng)開發(fā)任務(wù)等。</p><p> 運(yùn)行可行性是對(duì)組織結(jié)構(gòu)的影響,現(xiàn)有人員和機(jī)構(gòu)和環(huán)境對(duì)系統(tǒng)的適應(yīng)性及人員培訓(xùn)補(bǔ)充計(jì)劃的可行性。當(dāng)前我國(guó)信息化技術(shù)已經(jīng)相當(dāng)普及,各類操作人員水平都有相當(dāng)?shù)母叨?,所以在運(yùn)行上是可行性的。<
70、/p><p> 本系統(tǒng)的開發(fā),是用典型的VS2012或者其他c++編譯工具開發(fā),主要是對(duì)算法的處理,包括詞法分析和分析表的構(gòu)造,及目標(biāo)代碼的輸出。已無技術(shù)上的問題。</p><p> 3.1.4 時(shí)間可行性</p><p> 從時(shí)間上看,在兩個(gè)月的時(shí)間里學(xué)習(xí)相關(guān)知識(shí),并開發(fā)C編譯器系統(tǒng),時(shí)間上是有點(diǎn)緊,但是不是不可能實(shí)現(xiàn),通過兩個(gè)多月的努力功能應(yīng)該基本實(shí)現(xiàn)。&l
71、t;/p><p> 3.1.5 法律可行性</p><p> ?、?所有技術(shù)資料都為合法。</p><p> ?、?開發(fā)過程中不存在知識(shí)產(chǎn)權(quán)問題。</p><p> ?、?未抄襲任何已存在的會(huì)員信息管理系統(tǒng),不存在侵犯版權(quán)問題。</p><p> ?、?開發(fā)過程中未涉及任何法律責(zé)任。</p><p&
72、gt; 綜上所述,本系統(tǒng)的開發(fā)從技術(shù)上、從經(jīng)濟(jì)上、從法律上都是完全可靠的。</p><p> 3.2 C語言的基本描述</p><p> C語言是本實(shí)驗(yàn)設(shè)計(jì)要實(shí)現(xiàn)的一種微型語言的名稱,該語言的源程序?yàn)槲谋拘问降腁SCII字符序列??紤]到針對(duì)現(xiàn)有的處理器來說,如果使用真正的機(jī)器代碼作為C編譯器的目標(biāo)語言會(huì)太過于復(fù)雜,所以C語言將目標(biāo)程序簡(jiǎn)化為三地址碼的四元式表示形式??稍谌我庖环N文本
73、編輯器中編輯C語言的源程序并保存為擴(kuò)展名為.c的文件,然后用命令行的形式調(diào)用C編譯器(C.EXE)對(duì)該源程序進(jìn)行編譯,經(jīng)過詞法分析、語法分析并在此基礎(chǔ)上展開語義處理,如果源程序中沒有錯(cuò)誤,則最終生成目標(biāo)代碼即三地址碼的四元式表示形式。這種四元式表達(dá)式更接近于中間語言形式,由于這種形式的中間語言便于優(yōu)化處理,因此是一種比較普遍采用的中間代碼形式。</p><p> C語言的程序結(jié)構(gòu)很簡(jiǎn)單,它的語法與C相似但規(guī)模小
74、于C語言。C源程序是一個(gè)由分號(hào)分隔開的語句序列。C只有兩個(gè)控制語句:if語句和while 語句,這兩個(gè)控制語句本身也可包含語句序列。if語句有一個(gè)可選的else部分。除此之外,還有數(shù)據(jù)的輸入和輸出(輸入語句一次只讀入一個(gè)變量,而輸出語句一次只輸出一個(gè)表達(dá)式)。</p><p> C的表達(dá)式也局限于布爾表達(dá)式和整型算術(shù)表達(dá)式。布爾表達(dá)式由對(duì)兩個(gè)算術(shù)表達(dá)式的比較組成,所有比較使用<和=比較運(yùn)算符。算術(shù)表達(dá)式可
75、以包括整型常數(shù)、變量、參數(shù)以及4個(gè)整型算符+、-、*、/,它們具備和通用語言相似的數(shù)學(xué)屬性。布爾表達(dá)式通常只作為測(cè)試條件出現(xiàn)在控制語句中。</p><p> 雖然缺少實(shí)用程序設(shè)計(jì)語言(如C、Pascal)所需要的許多特征——比如數(shù)組和指針等,但作為一次完整的編譯開發(fā)實(shí)踐,它已經(jīng)足夠體現(xiàn)出一個(gè)編譯器的開發(fā)過程了。</p><p> 3.3 C編譯器的功能</p><
76、p> C編譯器的主要任務(wù)是分析基于C語言規(guī)范的字符組成的C源程序,把它們識(shí)別為一個(gè)個(gè)具有獨(dú)立意義的單詞符號(hào)(Token),并識(shí)別其有關(guān)屬性再轉(zhuǎn)換成長(zhǎng)度統(tǒng)一的屬性字,以供后續(xù)語義部分分析使用。簡(jiǎn)單的說,C編譯器的功能就是掃描C源程序,識(shí)別單詞,轉(zhuǎn)換成屬性字,再經(jīng)過語義處理和代碼生成,最終得到目標(biāo)代碼文件即三地址四元表達(dá)式。</p><p> 一般的說,C編譯器實(shí)現(xiàn)了下列幾項(xiàng)功能: </p>
77、<p> ?。?)從C源程序中逐一取出單詞。</p><p> ?。?)生成LR(1)分析表。</p><p> (3)識(shí)別單詞的屬性并填入構(gòu)造好的符號(hào)表中。</p><p> (4)將單詞轉(zhuǎn)換成屬性字,并輸出二元組屬性字流。</p><p> ?。?)將符號(hào)表提供給語義分析程序加工處理。</p><p>
78、; ?。?)生成目標(biāo)代碼。</p><p> ?。?)提供基本出錯(cuò)處理。</p><p> 3.4 C編譯器的程序結(jié)構(gòu)</p><p> 3.4.1 C編譯器的設(shè)計(jì)模式</p><p> C編譯器用C++實(shí)現(xiàn),下面是主要類的類圖:</p><p> 圖3-1 C++實(shí)現(xiàn)C語言編譯器的類圖</p>
79、;<p> 主控模塊main.cpp:C編譯器的主程序。</p><p> 文法類ReadCfg:文法規(guī)則類,定義C語言文法的規(guī)則。</p><p> ?。?)詞法掃描類Scanner:關(guān)鍵字、算符與界符將直接形成Token字;標(biāo)識(shí)符將插入符號(hào)表后形成Token字,數(shù)字將插入常數(shù)表后形成Token字。</p><p> ?。?) 詞法掃描類Scan
80、ner:將源程序的字符序列收集到稱作記號(hào)(token)的有意義單元中,即完成與語言單詞拼寫相類似的任務(wù)。</p><p> (5) LR(1)分析表的構(gòu)造類Grammer:根據(jù)C語言文法的特點(diǎn),夠造出相應(yīng)的分析表(包括ACTION表和GOTO表)。</p><p> ?。?) 語法分析類Lr:將語言結(jié)構(gòu)的語義以屬性(attribute)的形式賦予代表此結(jié)構(gòu)的文法符號(hào),而屬性的計(jì)算以語義規(guī)
81、則(semantic rules)的形式賦予由文法符號(hào)組成的產(chǎn)生式;在語法分析推導(dǎo)或歸約的每一步驟中,通過語義規(guī)則實(shí)現(xiàn)對(duì)屬性的計(jì)算,以達(dá)到對(duì)語義的處理。</p><p> 3.4.2 C編譯器的文件組成</p><p> 表3-1 C編譯器的文件組成</p><p> 基類Token,它包括了編譯器中各種數(shù)據(jù)類型的定義和整個(gè)編譯器均可能使用到的全局變量的定義
82、。ReadCfg類從文件讀取C語言文法,并保存在文法結(jié)點(diǎn)Cfg_node中。C語言文法總結(jié)出有57個(gè)產(chǎn)生式,終結(jié)符(terminal)31和存放在set<int>terminal中,非終結(jié)符26個(gè),存放在set<int>nonterminal中。Scanner類是詞法分析的類,成員函數(shù)scan()每次返回一個(gè)Token字。Grammer類主要負(fù)責(zé)大量數(shù)據(jù)結(jié)構(gòu)的保存和LR(1)分析表的構(gòu)造,最終分析表存放在ac
83、tion_goto_table.txt中。Lr類的包含語法分析的總控程序,用成員函數(shù)analyse()實(shí)現(xiàn)對(duì)語法的分析,在語法分析推導(dǎo)或歸約的每一步驟中,通過語義規(guī)則實(shí)現(xiàn)對(duì)屬性的計(jì)算,以達(dá)到對(duì)語義的處理。main.c 文件是C編譯器的主程序,它負(fù)責(zé)整個(gè)程序的掌控。</p><p> 3.5 C編譯器中的主要數(shù)據(jù)結(jié)構(gòu)</p><p> 下面列舉出在C編譯器中使用到的主要數(shù)據(jù)結(jié)構(gòu),它們通
84、常在編譯的多個(gè)階段都需要使用到,并用來在各階段中共享一些特定數(shù)據(jù)[8]。</p><p> ?。?) 記號(hào)(token)</p><p> 當(dāng)掃描程序?qū)⑷舾蓚€(gè)字符收集到一個(gè)記號(hào)中時(shí),它通常是以符號(hào)表示這個(gè)記號(hào)的,也就是說,用一個(gè)枚舉數(shù)據(jù)類型的值來表示源程序的記號(hào)集。有時(shí)還必須保留字符串本身或由此派生出的其他信息(例如:與標(biāo)識(shí)符記號(hào)相關(guān)的名字或數(shù)字記號(hào)值)。在C編譯器中,掃描程序一次只需要
85、生成一個(gè)記號(hào)(這稱為單符號(hào)先行),考慮到這種情況,可以用全程變來量放置記號(hào)信息。</p><p> (2) 符號(hào)表(symbol table)</p><p> 符號(hào)表中的信息與標(biāo)識(shí)符(函數(shù)、變量、常量以及數(shù)據(jù)類型等)有關(guān)。它幾乎與編譯器的所有階段交互:掃描程序、分析程序或?qū)?biāo)識(shí)符輸入到表格中的語義分析程序;語義分析程序?qū)⒃黾訑?shù)據(jù)類型和其它語義信息;優(yōu)化階段和代碼生成階段也將利用由符號(hào)
86、表提供的信息生成正確而恰當(dāng)?shù)拇a。因?yàn)樵诰幾g的全程中對(duì)符號(hào)表的訪問非常頻繁,所以插入、刪除和訪問等符號(hào)表操作都必須比常規(guī)操作更有效。盡管可以使用各種樹的結(jié)構(gòu),但雜湊表卻是能達(dá)到這一要求的最理想的數(shù)據(jù)結(jié)構(gòu)。</p><p> (3) 項(xiàng)目(item)</p><p> 在文法G中,某個(gè)產(chǎn)生式的右部標(biāo)上“點(diǎn)號(hào)”的產(chǎn)生式,再放置一個(gè)向前所搜符號(hào)a,成為L(zhǎng)R(1)項(xiàng)目。每個(gè)LR(1)項(xiàng)目集簇由
87、若干狀態(tài)組成,每個(gè)狀態(tài)由若干項(xiàng)目組成。因此,對(duì)于構(gòu)建項(xiàng)目集簇,項(xiàng)目的操作相當(dāng)頻繁,如何表示和處理項(xiàng)目成為構(gòu)造分析表的重點(diǎn)。</p><p> ?。?) 中間代碼(intermediate code)</p><p> 根據(jù)中間代碼的類型(例如三元式代碼和P-代碼)和優(yōu)化的類型,該代碼可以是字符串?dāng)?shù)組(指針數(shù)組)、臨時(shí)文本文件或是結(jié)構(gòu)的連接列表。對(duì)于進(jìn)行復(fù)雜優(yōu)化的編譯器,應(yīng)特別注意選擇允許
88、簡(jiǎn)單重組的中間代碼表示。</p><p> 第四章 C編譯器的實(shí)現(xiàn)</p><p> C編譯器從整體上被劃分為4個(gè)階段:詞法分析、語法分析、語義分析、代碼生成,這4個(gè)階段分別用不同的程序模塊來實(shí)現(xiàn)(如表3-1)。一個(gè)C源程序經(jīng)過C編譯器的編譯之后,生成三地址的四元表達(dá)式目標(biāo)代碼,在整個(gè)編譯過程中,這4個(gè)階段分別承擔(dān)了相應(yīng)的翻譯任務(wù)。</p><p> 4.1
89、 詞法分析階段</p><p><b> 4.1.1 概述</b></p><p> 編譯器的詞法分析階段可將源程序讀作有序字符文件并將其掃描分解為若干個(gè)記號(hào)(token)。記號(hào)與自然語言中的單詞類似:每一個(gè)記號(hào)都是表示源程序中信息單元的字符序列。典型的有:關(guān)鍵字(keyword),例如if和while,它們是字母的固定串,在該語言中具有特定的含義;標(biāo)識(shí)符(i
90、dentifier)是由用戶定義的串,它們通常由字母和數(shù)字組成并由一個(gè)字母開頭,例如變量名函數(shù)名等;算符符(operation symbol)在語言中是作為語法上的運(yùn)算符號(hào)使用的。例如,+,-,*,/,(,),和++, --, <=;界符在語言中作為語法上的分界;數(shù)字,廣義上就是源程序中的字面值。</p><p> 如前所述,詞法分析程序的輸入是源程序字符串,輸出是與源程序等價(jià)的符號(hào)序列。作為詞法分析程序
91、的符號(hào)可以有各種不同的內(nèi)部表現(xiàn)形式,原則是不同的符號(hào)能彼此區(qū)別開且有唯一的表示。</p><p> 為了便于編譯程序的進(jìn)一步加工(語法分析),內(nèi)部表示的符號(hào)都按屬性字形式,因此,詞法分析程序的輸出即是屬性字序列,采用二元式來表示一個(gè)單詞符號(hào)的內(nèi)部形式。</p><p> 表4-1 詞法Token字</p><p> 這五類單詞將用不同的方法處理。關(guān)鍵字、算符與
92、界符將直接形成Token字;標(biāo)識(shí)符將插入符號(hào)表后形成Token字,數(shù)字將插入常數(shù)表后形成Token字。 </p><p> 在實(shí)際做詞法分析時(shí),考慮了所有的C語言現(xiàn)象,使得每一個(gè)C語言程序都可以被此法分析切割為單詞并且賦值上屬性。</p><p> 一般情況下,可以通過兩種途徑來設(shè)計(jì)詞法分析程序。一種是用手工方式構(gòu)造,另一種是所謂詞法分析程序的自動(dòng)生成。為了實(shí)現(xiàn)簡(jiǎn)單,本實(shí)驗(yàn)采取手工構(gòu)造
93、方式。</p><p> 4.1.2 C詞法分析程序的實(shí)現(xiàn)</p><p> C語言的記號(hào)分為5種類型:標(biāo)示符,關(guān)鍵字,數(shù)字,算符和界限符。關(guān)鍵字一共有8個(gè),它們的含義類似于標(biāo)準(zhǔn)C語言中的相應(yīng)關(guān)鍵字。特殊符號(hào)共有12種:分別是4種基本的整數(shù)運(yùn)算符號(hào),5種比較符號(hào)(等號(hào)、小于號(hào)、小于等于、大于、大于等于),以及左括號(hào)、右括號(hào)、分號(hào)、賦值符號(hào)。其中,除了比較等號(hào)、小于等于符號(hào)和大于等于是
94、兩個(gè)字符的長(zhǎng)度之外,其余均為單個(gè)字符?!捌渌庇浱?hào)就是數(shù)和標(biāo)識(shí)符了,數(shù)是一個(gè)或多個(gè)數(shù)字的序列,而標(biāo)識(shí)符又是一個(gè)或多個(gè)字母的序列。所有這些記號(hào)歸納如下表4-2:</p><p> 表4-2C語言的記號(hào)</p><p> 除了上表的記號(hào)之外,C語言的源程序還要遵循以下的詞法規(guī)則:代碼應(yīng)是自由書寫格式;空白符由空格、制表位和新行組成。</p><p> 根據(jù)對(duì)語言中
95、各類單詞某種描述的定義,用手工方式構(gòu)造詞法分析程序。</p><p> 詞法分析程序的主要任務(wù)就是掃描程序、識(shí)別單詞、轉(zhuǎn)換并輸出屬性字。下面給出單獨(dú)成趟詞法分析控制流程圖。</p><p> 圖4-1 單獨(dú)成趟的詞法分析控制流程圖</p><p> 詞法分析主要包含在Scanner.h和Scanner.cpp文件中,其核心函數(shù)是scan( ),它每次從第一個(gè)非
96、空格或換行符開始識(shí)別,直到遇到空格或者換行符,遇到單行注釋就跳過本行從“//”開始的以后字符識(shí)別,遇到多行注釋就跳過直到遇到“*/”為止(不支持注釋嵌套)。每次返回一個(gè)識(shí)別的單詞,遇到不識(shí)別的單詞就報(bào)錯(cuò),輸出不識(shí)別的單詞和該單詞的行數(shù)。</p><p> 掃描程序在識(shí)別出每個(gè)記號(hào)的同時(shí),還會(huì)計(jì)算出該記號(hào)的特性(比如串值)這五類單詞將用不同的方法處理。關(guān)鍵字、算符與界符將直接形成Token字;標(biāo)識(shí)符將插入符號(hào)表后
97、形成Token字,數(shù)字將插入常數(shù)表后形成Token字。 </p><p> Token是本實(shí)驗(yàn)的所有類的基類,有2個(gè)成員變量:Tag,Value。Value是文法中非終結(jié)符,而Tag是Value對(duì)應(yīng)的唯一標(biāo)記。</p><p> 4.1.3 關(guān)鍵字與標(biāo)識(shí)符的識(shí)別</p><p> C對(duì)于關(guān)鍵字的識(shí)別,是通過先將它們看作是標(biāo)識(shí)符,然后再調(diào)用Token類的get
98、_int()方法,根據(jù)返回值Tag是否22(標(biāo)示符的標(biāo)志)為來判斷是標(biāo)示符還是關(guān)鍵字。</p><p> 4.1.4 詞法識(shí)別具體實(shí)現(xiàn)</p><p> //分析一個(gè)單詞,并返回單詞的Token字</p><p> Token Scanner::scan()</p><p><b> {</b></p&g
99、t;<p><b> int i=0;</b></p><p><b> string s;</b></p><p> static char prev_c = 0;</p><p> char line[Token::NAME_SIZE] = {0};</p><p> p
100、rev_c = c;</p><p> while (true)</p><p><b> {</b></p><p> if (fin.get(c)==NULL)//到文件結(jié)尾</p><p> return (Token());</p><p> if (c=='\n&
101、#39;)//遇到換行符</p><p> linenum++;//行數(shù)+1</p><p> else if (c==' ' || c=='\t')//遇到空格或者制表符</p><p> continue;//跳過,繼續(xù)讀</p><p> else//遇到普通字符,跳出循環(huán)
102、</p><p><b> break;</b></p><p><b> }</b></p><p><b> //遇到注釋的情況</b></p><p> while (c=='/' && (fin.peek()=='/
103、9; || fin.peek()=='*'))</p><p><b> {</b></p><p><b> //處理注釋</b></p><p> } //end while</p><p> if (isalpha(c))//字母</p><p
104、> return (alpha_process());</p><p> else if (isdigit(c))//數(shù)字</p><p> return (digit_process());</p><p> else//其他</p><p><b> {</b></p&
105、gt;<p> switch(c)//對(duì)字符進(jìn)行分析</p><p><b> {</b></p><p><b> case '+':</b></p><p><b> {...}</b></p><p><b> cas
106、e '-':</b></p><p><b> {...}</b></p><p><b> case '*':</b></p><p><b> {...}</b></p><p><b> case '/
107、':</b></p><p><b> {...}</b></p><p><b> case '=':</b></p><p><b> {...}</b></p><p><b> case '<'
108、:</b></p><p><b> {...}</b></p><p><b> case '>':</b></p><p><b> {...}</b></p><p><b> case '!':<
109、/b></p><p><b> {...}</b></p><p><b> case '&':</b></p><p><b> {...}</b></p><p><b> case '|':</b&g
110、t;</p><p><b> {...}</b></p><p><b> case '~':</b></p><p><b> {...}</b></p><p> case '(':return (Token(get_int(&
111、quot;("), "("));</p><p> case ')':return (Token(get_int(")"), ")"));</p><p> case '[':return (Token(get_int("["), "["
112、));</p><p> case ']':return (Token(get_int("]"), "]"));</p><p> case '{':return (Token(get_int("{"), "{"));</p><p> ca
113、se '}':return (Token(get_int("}"), "}"));</p><p> case '"':return (string_process());</p><p> case ';':return (Token(get_int(";"
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 編譯原理課程設(shè)計(jì)___c語言編譯器的實(shí)現(xiàn)畢業(yè)論文
- 畢業(yè)論文-c語言在線編譯器
- c語言在線編譯器畢業(yè)論文
- 編譯原理課程設(shè)計(jì)--c語言編譯器實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)--c語言編譯器實(shí)現(xiàn)
- c語言編譯器實(shí)現(xiàn)-編譯原理課程設(shè)計(jì)
- 小型c語言編譯器設(shè)計(jì)
- 畢業(yè)設(shè)計(jì)(論文)c語言編譯器的設(shè)計(jì)開發(fā)-字節(jié)代碼格式設(shè)計(jì)與實(shí)現(xiàn)
- 編譯原理課程設(shè)計(jì)____c語言編譯器的實(shí)現(xiàn)-
- 編譯原理課程設(shè)計(jì)---c語言編譯器的實(shí)現(xiàn)
- c語言編譯器前端的設(shè)計(jì)與實(shí)現(xiàn)課程設(shè)計(jì)
- 編譯原理課程的設(shè)計(jì)--c語言編譯器
- 基于ASIP的專用C語言編譯器的設(shè)計(jì)與實(shí)現(xiàn).pdf
- 編譯原理課程設(shè)計(jì)---s語言的編譯器的設(shè)計(jì)與實(shí)現(xiàn)
- DSP-2400的C語言編譯器的設(shè)計(jì)及實(shí)現(xiàn).pdf
- c-編譯器設(shè)計(jì)文檔
- 國(guó)際結(jié)算系統(tǒng)業(yè)務(wù)語言編譯器設(shè)計(jì)與實(shí)現(xiàn).pdf
- C語言安全編譯器研究.pdf
- DSP處理器C編譯器的設(shè)計(jì)與實(shí)現(xiàn).pdf
- 編譯原理課程設(shè)計(jì)---小型程序設(shè)計(jì)語言編譯器的設(shè)計(jì)與實(shí)現(xiàn)
評(píng)論
0/150
提交評(píng)論