Duffblog

          前進一步,看看,需要前進更大一步才可以。

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            5 隨筆 :: 53 文章 :: 5 評論 :: 0 Trackbacks
          大學(xué)課程為什么開設(shè)編譯原理呢?這門課程關(guān)注的是編譯器方面的產(chǎn)生原理和技術(shù)問題,似乎和計算機的基礎(chǔ)領(lǐng)域不沾邊,可是編譯原理卻一直作為大學(xué)本科的必修課程,同時也成為了研究生入學(xué)考試的必考內(nèi)容。編譯原理及技術(shù)從本質(zhì)上來講就是一個算法問題而已,當(dāng)然由于這個問題十分復(fù)雜,其解決算法也相對復(fù)雜。我們學(xué)的數(shù)據(jù)結(jié)構(gòu)與算法分析也是講算法的,不過講的基礎(chǔ)算法,換句話說講的是算法導(dǎo)論,而編譯原理這門課程講的就是比較專注解決一種的算法了。在20世紀(jì)50年代,編譯器的編寫一直被認(rèn)為是十分困難的事情,第一Fortran的編譯器據(jù)說花了18年的時間才完成。在人們嘗試編寫編譯器的同時,誕生了許多跟編譯相關(guān)的理論和技術(shù),而這些理論和技術(shù)比一個實際的編譯器本身價值更大。就猶如數(shù)學(xué)家們在解決著名的哥德巴赫猜想一樣,雖然沒有最終解決問題,但是其間誕生不少名著的相關(guān)數(shù)論。 推薦參考書 雖然編譯理論發(fā)展到今天,已經(jīng)有了比較成熟的部分,但是作為一個大學(xué)生來說,要自己寫出一個像Turboc C,Java那樣的編譯器來說還是太難了。不僅寫編譯器困難,學(xué)習(xí)編譯原理這門課程也比較困難。 正是因為編譯原理學(xué)習(xí)相對困難,那么就要求有好的教師和好的教材。教師方面不是我們能自己更改的,而在教材方面我們卻可以按自己的意愿來閱讀。我下面推薦幾本好的編譯原理的教材。我推薦的書籍都是國外的經(jīng)典教材,因為在國內(nèi)的教材中,確實還沒發(fā)現(xiàn)什么讓人滿意的。 第一本書的原名叫《Compilers Principles,Techniques,and Tools》,另外一個響亮的名字就是龍書。原因是這本書的封面上有條紅色的龍,也因為獗臼樵詒嘁朐砘×煊蛉肥堤忻?所以很多國外的學(xué)者都直接取名為龍書。最近機械工業(yè)出版社已經(jīng)出版了此書的中文版,名字就叫《編譯原理》。該書出的比較早,大概是在85或86年編寫完成的,作者之一還是著名的貝爾實驗室的科學(xué)家。里面講解的核心編譯原理至今都沒有變過,所以一直到今天,它的價值都非凡。這本書最大的特點就是一開始就通過一個實際的小例子,把編譯原理的大致內(nèi)容羅列出來,讓很多編譯原理的初學(xué)者很快心里有了個底,也知道為什么會有這些理論,怎么運用這些理論。而這一點是我感覺國內(nèi)的教材缺乏的東西,所以國內(nèi)的教材都不是寫給愿意自學(xué)的讀者,總之讓人看了半天,卻不知道里面的東西有什么用。 第二本書的原名叫《Modern Compiler Design》,中文名字叫做《現(xiàn)代編譯程序設(shè)計》。該書由人民郵電出版社所出。此書比較關(guān)注的是編譯原理的實踐,書中給出了不少的實際程序代碼,還有很多實際的編譯技術(shù)問題等等。此書另外一個特點就是其“現(xiàn)代”而字。在傳統(tǒng)的編譯原理教材中,你是不可能看到如同Java中的“垃圾回收”等算法的。因為Java這樣的解釋執(zhí)行語言是在近幾年才流行起來的東西。如果你想深入學(xué)習(xí)編譯原理的理論知識,那么你肯定得看前面那本龍書,如果你想自己動手做一個先進的編譯器,那么你得看這本《現(xiàn)代編譯程序設(shè)計》。 第三本書就是很多國內(nèi)的編譯原理學(xué)者都推薦的那本《編譯原理及實踐》?;蛟S是這本書引入國內(nèi)比較早吧,我記得我是在高中就買了這本書,不過也是在前段時間才把整本書看完。此書作為入門教程也的確是個不錯的選擇。書中給出的編譯原理講解也相當(dāng)細致,雖然不如前面的龍書那么深入,但是很多地方都是點到為止,作為大學(xué)本科教學(xué)已經(jīng)是十分深入了。該書的特點就是注重實踐,不過感覺還不如前面那本《現(xiàn)代編譯程序設(shè)計》的實踐味道更重。此書的重點還是在原理上的實踐,而非前面那本那樣的技術(shù)實踐?!毒幾g原理及實踐》在講解編譯原理的各個部分的同時,也在逐步實踐一個現(xiàn)代的編譯器Tiny C.等你把整本書看完,差不多自己也可以寫一個Tiny C了。作者還對Lex和Yacc這兩個常用的編譯相關(guān)的工具進行了很詳細的說明,這一點也是很難在國內(nèi)的教材中看到的。 推薦了這三本教材,都有英文版和中文版的。很多英文好的同學(xué)只喜歡看原版的書,不我的感覺是這三本書的翻譯都很不錯,沒有必要特別去買英文版的。理解理論的實質(zhì)比理解表面的文字更為重要。 編譯原理的實質(zhì) 前面已經(jīng)說過,學(xué)習(xí)編譯原理其實也就是學(xué)習(xí)算法而已,沒什么特別的。只不過這些算法的產(chǎn)生已經(jīng)形成了一套理論。下面我來看看編譯原理里面到底有什么高深的理論吧。 幾乎每本編譯原理的教材都是分成詞法分析,語法分析(LL算法,遞歸下降算法,LR算法),語義分析,運行時環(huán)境,中間代碼,代碼生成,代碼優(yōu)化這些部分。其實現(xiàn)在很多編譯原理的教材都是按照85,86出版的那本龍書來安排教學(xué)內(nèi)容的,所以那本龍書的內(nèi)容格式幾乎成了現(xiàn)在編譯原理教材的定式,包括國內(nèi)的教材也是如此。一般來說,大學(xué)里面的本科教學(xué)是不可能把上面的所有部分都認(rèn)真講完的,而是比較偏重于前面幾個部分。像代碼優(yōu)化那部分東西,就像個無底洞一樣,如果要認(rèn)真講,就是單獨開一個學(xué)期的課也不可能講得清楚。所以,一般對于本科生,對詞法分析和語法分析掌握要求就相對要高一點了。 詞法分析相對來說比較簡單??赡苁窃~法分析程序本身實現(xiàn)起來很簡單吧,很多沒有學(xué)過編譯原理的人也同樣可以寫出各種各樣的詞法分析程序。不過編譯原理在講解詞法分析的時候,重點把正則表達式和自動機原理加了進來,然后以一種十分標(biāo)準(zhǔn)的方式來講解詞法分析程序的產(chǎn)生。這樣的做法道理很明顯,就是要讓詞法分析從程序上升到理論的地步。 語法分析部分就比較麻煩一點了?,F(xiàn)在一般有兩種語法分析算法,LL自頂向下算法和LR自底向上算法。LL算法還好說,到了LR算法的時候,困難就來了。很多自學(xué)編譯原理的都是遇到LR算法的理解成問題后就放棄了自學(xué)。其實這些東西都是只要大家理解就可以了,又不是像詞法分析那樣非得自己寫出來才算真正的會。像LR算法的語法分析器,一般都是用工具Yacc來生成,實踐中完全沒有比較自己來實現(xiàn)。對于LL算法中特殊的遞歸下降算法,因為其實踐十分簡單,那么就應(yīng)該要求每個學(xué)生都能自己寫。當(dāng)然,現(xiàn)在也有不少好的LL算法的語法分析器,不過要是換在非C平臺,比如Java,Delphi,你不能運用YACC工具了,那么你就只有自己來寫語法分析器。 等學(xué)到詞法分析和語法分析時候,你可能會出現(xiàn)這樣的疑問:“詞法分析和語法分析到底有什么?”就從編譯器的角度來講,編譯器需要把程序員寫的源程序轉(zhuǎn)換成一種方便處理的數(shù)據(jù)結(jié)構(gòu)(抽象語法樹或語法樹),那么這個轉(zhuǎn)換的過程就是通過詞法分析和語法分析的。其實詞法分析并非一開始就被列入編譯器的必備部分,只是我們?yōu)榱撕喕Z法分析的過程,就把詞法分析這種繁瑣的工作單獨提取出來,就成了現(xiàn)在的詞法分析部分。除了編譯器部分,在其它地方,詞法分析和語法分析也是有用的。比如我們在DOS,Unix,Linux下輸入命令的時候,程序如何分析你輸入的命令形式,這也是簡單的應(yīng)用??傊?,這兩部分的工作就是把不“規(guī)則”的文本信息轉(zhuǎn)換成一種比較好分析好處理的數(shù)據(jù)結(jié)構(gòu)。那么為什么編譯原理的教程都最終把要分析的源分析轉(zhuǎn)換成“樹”這種數(shù)據(jù)結(jié)構(gòu)呢?數(shù)據(jù)結(jié)構(gòu)中有Stack, Line,List…這么多數(shù)據(jù)結(jié)構(gòu),各自都有各自的特點。但是Tree這種結(jié)構(gòu)有很強的遞歸性,也就是說我們可以把Tree的任何結(jié)點Node提取出來后,它依舊是一顆完整的Tree。這一點符合我們現(xiàn)在編譯原理分析的形式語言,比如我們在函數(shù)里面使用函樹,循環(huán)中使用循環(huán),條件中使用條件等等,那么就可以很直觀地表示在Tree這種數(shù)據(jù)結(jié)構(gòu)上。同樣,我們在執(zhí)行形式語言的程序的時候也是如此的遞歸性。在編譯原理后面的代碼生成的部分,就會介紹一種堆棧式的中間代碼,我們可以根據(jù)分析出來的抽象語法樹,很容易,很機械地運用遞歸遍歷抽象語法樹就可以生成這種指令代碼。而這種代碼其實也被廣泛運用在其它的解釋型語言中。像現(xiàn)在流行的Java,.NET,其底層的字節(jié)碼bytecode,可以說就是這中基于堆棧的指令代碼的。 關(guān)于語義分析,語法制導(dǎo)翻譯,類型檢查等等部分,其實都是一種完善前面得到的抽象語法樹的過程。比如說,我們寫C語言程序的時候,都知道,如果把一個浮點數(shù)直接賦值給一個整數(shù),就會出現(xiàn)類型不匹配,那么C語言的編譯器是怎么知道的呢?就是通過這一步的類型檢查。像C++語言這中支持多態(tài)函數(shù)的語言,這部分要處理的問題就更多更復(fù)雜了。大部編譯原理的教材在這部分都是講解一些比較好的處理策略而已。因為新的問題總是在發(fā)生,舊的辦法不見得足夠解決。 本來說,作為一個編譯器,起作用的部分就是用戶輸入的源程序到最終的代碼生成。但是在講解最終代碼生成的時候,又不得不講解機器運行環(huán)境等內(nèi)容。因為如果你不知道機器是怎么執(zhí)行最終代碼的,那么你當(dāng)然無法知道如何生成合適的最終代碼。這部分內(nèi)容我自我感覺其意義甚至超過了編譯原理本身。因為它會把一個計算機的程序的運行過程都通通排在你面前,你將來可能不會從事編譯器的開發(fā)工作,但是只要是和計算機軟件開發(fā)相關(guān)的領(lǐng)域,都會涉及到程序的執(zhí)行過程。運行時環(huán)境的講解會讓你更清楚一個計算機程序是怎么存儲,怎么裝載,怎么執(zhí)行的。關(guān)于部分的內(nèi)容,我強烈建議大家看看龍書上的講解,作者從最基本的存儲組織,存儲分配策略,非局部名字的訪問,參數(shù)傳遞,符號表到動態(tài)存儲分配(malloc,new)都作了十分詳細的說明。這些東西都是我們編寫平常程序的時候經(jīng)常要做的事情,但是我們卻少去探求其內(nèi)部是如何完成。
          posted on 2006-08-21 16:24 追球者 閱讀(282) 評論(0)  編輯  收藏 所屬分類: 技術(shù)文摘
          主站蜘蛛池模板: 邳州市| 广河县| 新民市| 咸宁市| 英山县| 临洮县| 全南县| 纳雍县| 根河市| 四会市| 鞍山市| 仙桃市| 德江县| 射洪县| 东源县| 登封市| 汉寿县| 龙门县| 武义县| 葫芦岛市| 定陶县| 雷州市| 建昌县| 卓资县| 曲水县| 丹寨县| 宜丰县| 紫云| 平果县| 怀柔区| 海南省| 达拉特旗| 射洪县| 晋州市| 桐乡市| 潜江市| 浪卡子县| 修水县| 乐至县| 沾益县| 资阳市|