『壹』 編譯原理及實踐的內容簡介
本書系統介紹了經典的編譯理論和技術,同時也包含了面向對象語言等當前較新語言的編譯技術。本書更可貴之處在於提供了較完整的適用於教學實踐的樣例語言,是一本理論和實踐內容相結合的、不可多得的好書。本書可用作大專院校教材、教師參考書以及編譯器研究人員的參考資料。
作者簡介
Kenneth C.Louden,加拿大麥吉爾大學獲得博士學位之後,曾在多所大學任教。他的主要研究領域是統和統譯器,涉及范疇論及其編程、形式語義、編譯器優化與自動化技術等。1985年在美國聖何塞州立大學任教至今。所撰寫的教材還有Programming Languages、Programming Languages Text和 Compiler Constuction Text等。
『貳』 把編譯程序設計原理(第二版)高等教育出版社的課後答案給我發一份 可以嗎
目錄
第1章編譯器概述
1.1為什麼要學習編譯技術
1.2編譯器和解釋器
1.3編譯器的功能分解和組織結構
1.4編譯器的夥伴
1.5編譯器的復雜性
1.6編譯器的設計與實現
1.7編譯器的測試與維護
第2章一個微型編譯器
2.1基礎知識
2.2ToyL語言
2.3ToyL語言詞法分析器
2.4ToyL語言語法分析器
2.5ToyL語言解釋器
2.6ToyL語言編譯器
第3章有窮自動機與詞法分析
3.1詞法分析基礎
3.1.1詞法分析器的功能
3.1.2單詞識別
3.1.3詞法分析的復雜性
3.1.4字元串
3.1.5保留字處理
3.1.6空格符、回車符、換行符
3.1.7括弧類配對預檢
3.1.8詞法錯誤修正
3.1.9詞法分析獨立化的意義
3.2有窮自動機
3.2.1確定有窮自動機的定義
3.2.2確定有窮自動機的實現
3.2.3非確定有窮自動機
3.2.4NFA到DFA的轉換
3.2.5確定有窮自動機的極小化
3.2.6自動機狀態轉換表的實現
3.3正則表達式
3.3.1正則符號串集
3.3.2正則表達式的定義
3.3.3正則表達式的局限性
3.3.4正則定義
3.3.5正則表達式到有窮自動機的轉換
3.4詞法分析器的構造
3.4.1用DFA人工構造詞法分析器
3.4.2詞法分析器的生成器Lex
練習
第4章文法與語法分析
4.1語法分析
4.1.1語法分析器的輸入
4.1.2語法分析的任務
4.1.3語法分析方法分類
4.2文法和文法分析
4.2.1上下文無關文法和語言
4.2.2最左推導和最右推導
4.2.3語法分析樹與二義性
4.2.4文法分析演算法
4.2.5自頂向下方法概述
4.2.6自底向上方法概述
4.3遞歸下降法——自頂向下分析
4.3.1遞歸下降法原理
4.3.2消除公共前綴
4.3.3代入
4.3.4消除左遞歸
4.4LL分析方法——自頂向下分析
4.4.1LL(1)文法
4.4.2LL(1)分析表
4.4.3LL(1)分析的驅動器
4.4.4LL(1)中的If-Then-Else問題
4.4.5LL(1)分析器的自動生成器LLGen
4.4.6LL(1)分析法與遞歸下降法的比較
4.4.7正則文法
4.5LR方法——自底向上分析
4.5.1句柄
4.5.2活前綴
4.5.3歸約活前綴識別器——LR(0)自動機
4.5.4LR(0)文法及其分析演算法
4.5.5SLR(1)文法及其分析演算法
4.5.6LR(1)文法
4.5.7LALR(1)文法
4.5.8二義性文法的處理
4.5.9另一種Shift-Rece分析技術:簡單優先法
4.5.10LL(1)和LALR(1)方法比較
4.6LR分析器的生成器
4.6.1LALR分析器的生成器YACC
4.6.2LALR分析器的生成器LALRGen
4.7語法錯誤處理
4.7.1錯誤恢復和修復
4.7.2遞歸下降分析的錯誤恢復
4.7.3LL分析的錯誤恢復
4.7.4LR分析的錯誤恢復
練習
第5章語義分析
5.1語義分析基礎
5.1.1語義分析內容
5.1.2標識符信息的內部表示
5.1.3類型信息的內部表示
5.1.4運行時值的表示
5.2符號表
5.2.1符號表查找技術
5.2.2符號表的局部化
5.2.3二叉式局部符號表
5.2.4散列式全局符號表
5.2.5嵌套式全局符號表
5.2.6符號表界面函數
5.3類型分析
5.3.1類型的等價性和相容性
5.3.2類型分析的總控演算法
5.3.3類型名分析
5.3.4枚舉類型分析
5.3.5數組類型分析
5.3.6記錄類型分析
5.3.7聯合類型分析
5.3.8指針類型分析
5.3.9遞歸類型分析
5.4聲明的語義分析
5.4.1聲明的語法結構
5.4.2標號聲明部分的語義分析
5.4.3常量聲明部分的語義分析
5.4.4類型聲明部分的語義分析
5.4.5變數聲明部分的語義分析
5.4.6過程、函數聲明的語義分析
5.5執行體的語義分析
5.5.1執行體的語義分析
5.5.2帶標號語句和轉向語句的語義分析
5.5.3賦值語句的語義分析
5.5.4條件語句的語義分析
5.5.5while循環語句的語義分析
5.5.6for循環語句的語義分析
5.5.7過程調用語句的語義分析
5.5.8表達式的語義分析
5.5.9變數的語義分析
練習
第6章運行時的存儲環境
6.1運行時的存儲空間結構與分配
6.1.1運行時的存儲空間基本結構
6.1.2靜態區的存儲分配
6.1.3棧區的存儲分配
6.1.4堆區的存儲分配
6.1.5堆區空間管理
6.2過程活動記錄與棧區組織結構
6.2.1過程活動記錄
6.2.2活動記錄的填寫
6.2.3棧區組織結構——AR鏈
6.3運行時的變數訪問環境
6.3.1可訪問活動記錄
6.3.2局部Display表方法
6.3.3靜態鏈方法
6.3.4全局Display表方法和寄存器方法
6.3.5無嵌套時的AR及訪問環境
6.4分程序和動態數組空間
6.4.1無動態數組時的分程序空間
6.4.2動態數組空間
練習
第7章面向語法的語義描述
7.1動作文法
7.1.1動作文法定義
7.1.2動作文法的遞歸實現
7.1.3動作文法的LL實現
7.1.4動作文法的LR實現
7.2動作文法應用
7.2.1用動作文法描述表達式計算
7.2.2用動作文法描述表達式抽象樹的構造
7.2.3用動作文法描述語句抽象樹的構造
7.3抽象動作文法及其應用
7.3.1抽象變數
7.3.2抽象動作文法
7.3.3棧式LL動作文法驅動器
7.3.4抽象動作文法到棧式LL動作文法的轉換
7.3.5棧式LR動作文法驅動器
7.3.6抽象動作文法到棧式LR動作文法的轉換
7.4屬性文法
7.4.1屬性文法定義
7.4.2屬性語法樹和屬性依賴圖
7.4.3計算順序
7.4.4屬性值的計算方法
7.4.5拷貝型屬性文法
7.5屬性文法在編譯器設計中的應用
7.5.1類型樹的屬性文法描述
7.5.2表達式中間代碼的屬性文法描述
7.5.3變數中間代碼的屬性文法描述
7.5.4語句中間代碼的屬性文法描述
7.5.5正則表達式到自動機轉換的屬性文法描述
7.6S-屬性文法及其屬性計算
7.6.1S-屬性文法
7.6.2S-屬性文法的遞歸實現
7.6.3S-屬性文法的LR實現
7.7L-屬性文法及其屬性計算
7.7.1L-屬性文法
7.7.2L-屬性文法的遞歸實現
7.7.3L-屬性文法的LR(1)實現
7.8語義分析器的自動生成系統
7.8.1YACC
7.8.2LALRGen
7.8.3Accent系統
練習
第8章中間代碼生成
8.1中間代碼
8.1.1中間代碼的種類
8.1.2後綴式中間代碼
8.1.3三地址中間代碼
8.1.4抽象語法樹和無環有向圖
8.1.5多元式中間代碼
8.1.6中間代碼分量ARG結構
8.2表達式的中間代碼生成
8.2.1表達式的語義信息
8.2.2表達式的中間代碼
8.2.3變數的中間代碼
8.2.4表達式的中間代碼生成
8.2.5變數的中間代碼生成
8.2.6布爾表達式的短路中間代碼
8.3原子語句的中間代碼生成
8.3.1輸入/輸出語句的中間代碼生成
8.3.2goto語句和標號定位語句的中間代碼生成
8.3.3return語句的中間代碼生成
8.3.4賦值語句的中間代碼生成
8.3.5函數(過程)調用的中間代碼生成
8.4結構語句的中間代碼生成
8.4.1條件語句的中間代碼生成
8.4.2while語句的中間代碼生成
8.4.3repeat語句的中間代碼生成
8.4.4for語句的中間代碼生成
8.4.5case語句的中間代碼生成
8.4.6函數聲明的中間代碼生成
練習
第9章中間代碼優化
9.1引言
9.1.1優化的目標和要求
9.1.2優化的必要性
9.1.3優化的內容
9.1.4局部優化和全局優化
9.1.5基本塊和程序流圖
9.2常表達式優化
9.2.1常表達式的局部優化
9.2.2基於常量定值分析的常表達式全局優化
9.2.3常量定值分析
9.3公共表達式優化
9.3.1基於相似性的公共表達式局部優化
9.3.2基於值編碼的公共表達式局部優化
9.3.3基於活躍代碼分析的公共表達式全局優化
9.3.4活躍運算代碼分析
9.4程序流圖循環
9.4.1循環的基本概念
9.4.2支撐結點
9.4.3自然循環
9.4.4可歸約程序流圖
9.4.5基於文本的循環及其處理
9.5循環不變代碼外提
9.5.1代碼外提的基本概念
9.5.2循環不變代碼的判定
9.5.3循環不變代碼外提的條件
9.5.4基於文本循環和定值表的不變代碼外提
9.5.5一種簡單的外提優化方案
9.5.6別名分析
9.5.7過程與函數的副作用分析
9.6循環內歸納表達式的優化
9.6.1歸納變數
9.6.2歸納變數計算的優化演算法原理
練習
第10章目標代碼生成
10.1目標代碼
10.1.1虛擬機代碼
10.1.2目標機代碼
10.1.3窺孔優化
10.2臨時變數
10.2.1臨時變數的特點
10.2.2臨時變數的存儲空間
10.2.3臨時變數的存儲分配
10.2.4變數狀態描述
10.3寄存器
10.3.1寄存器分類及其使用准則
10.3.2寄存器分配單位
10.3.3寄存器狀態描述
10.3.4寄存器分配演算法
10.4基於三地址中間代碼的目標代碼生成
10.4.1目標地址生成
10.4.2間接目標地址的轉換
10.4.3表達式中間代碼的目標代碼生成
10.4.4賦值中間代碼的目標代碼生成
10.4.5其他寄存器分配法
10.4.6標號和goto語句中間代碼的目標代碼生成
10.4.7return中間代碼的目標代碼生成
10.4.8變數中間代碼的目標代碼生成
10.4.9函數調用中間代碼的目標代碼生成
10.5基於AST的代碼生成
10.5.1三地址中間代碼到AST的轉換
10.5.2標記需用寄存器個數
10.5.3從帶寄存器個數標記的AST生成代碼
10.6基於DAG的代碼生成
10.6.1從AST到DAG的轉換
10.6.2DAG排序和虛寄存器
10.6.3從帶序號和虛寄存器標記的DAG生成代碼
10.7代碼生成器的自動生成
10.7.1代碼生成器的自動化
10.7.2基於指令模板匹配的代碼生成技術
10.7.3基於語法分析的代碼生成技術
練習
第11章對象式語言的實現
11.1引言
11.2SOOL語法
11.2.1程序
11.2.2分程序
11.2.3類聲明
11.2.4類型
11.2.5變數聲明
11.2.6函數聲明和方法聲明
11.2.7語句
11.2.8變數
11.2.9表達式
11.2.10程序示例
11.3SOOL語義
11.3.1聲明的作用域
11.3.2Class聲明的語義
11.3.3語句的語義
11.4SOOL語義分析
11.4.1標識符的符號表項
11.4.2符號表結構
11.4.3符號表的局部化
11.5SOOL目標代碼
11.5.1對象空間
11.5.2當前對象——self
11.5.3活動記錄
11.5.4成員變數的目標地址
11.5.5表達式的目標代碼
11.5.6Offset原理
11.5.7類的多態性
11.5.8目標代碼區
11.5.9方法的動態綁定
11.5.10快速動態綁定目標代碼
主要參考文獻
『叄』 《編譯原理》txt下載在線閱讀全文,求百度網盤雲資源
《編譯原理》(陳意雲)電子書網盤下載免費在線閱讀
鏈接: https://pan..com/s/1BOpMeUxvK5kF_TeMACnD6Q
書名:編譯原理
作者:陳意雲
豆瓣評分:6.2
出版社:高等教育出版社
出版年份:2003-1
頁數:381
內容簡介:
《編譯原理》介紹編譯器構造的一般原理和基本實現方法,主要內容包括詞法分析、語法分析、語義分析、中間代碼生成、代碼優化和目標代碼生成等。除了介紹命令式編程語言的編譯技術外,《編譯原理》還介紹面向對象語言和函數式編程語言的實現技術。《編譯原理》還強調一些相關的理論知識,如形式語言和自動機理論、語法制導的定義和屬性文法、類型論和類型系統等。
《編譯原理》取材廣泛新穎、圖文並茂,注意理論聯系實際。為滿足教師教學和學生自學及考研需求,《編譯原理》作者編寫了配套教學參考書《編譯原理習題精選與解析》(高等教育出版社2005年8月出版),同時提供本課程的電子教案,可從高等教育出版社高等理工教學資源網免費下載。《編譯原理》可作為高等學校計算機科學及相關專業的教材,也可供計算機軟體工程技術人員參考使用。
『肆』 計算機科學與技術《編譯原理》求解題
1、錯
2、對
3、錯
4、對
5、錯
6、對
7、對
8、對
9、對
10、錯
『伍』 為什麼要學習編譯原理(轉)
大學課程為什麼要開設編譯原理呢?這門課程關注的是編譯器方面的產生原理和技術問題,似乎和計算機的基礎領域不沾邊,可是編譯原理卻一直作為大學本科的必修課程,同時也成為了研究生入學考試的必考內容。編譯原理及技術從本質上來講就是一個演算法問題而已,當然由於這個問題十分復雜,其解決演算法也相對復雜。我們學的數據結構與演算法分析也是講演算法的,不過講的基礎演算法,換句話說講的是演算法導論,而編譯原理這門課程講的就是比較專註解決一種的演算法了。在20世紀50年代,編譯器的編寫一直被認為是十分困難的事情,第一Fortran的編譯器據說花了18年的時間才完成。在人們嘗試編寫編譯器的同時,誕生了許多跟編譯相關的理論和技術,而這些理論和技術比一個實際的編譯器本身價值更大。就猶如數學家們在解決著名的哥德巴赫猜想一樣,雖然沒有最終解決問題,但是其間誕生不少名著的相關數論。 推薦參考書 雖然編譯理論發展到今天,已經有了比較成熟的部分,但是作為一個大學生來說,要自己寫出一個像TurbocC,Java那樣的編譯器來說還是太難了。不僅寫編譯器困難,學習編譯原理這門課程也比較困難。 第一本書的原名叫《CompilersPrinciples,Techniques,andTools》,另外一個響亮的名字就是龍書。原因是這本書的封面上有條紅色的龍,也因為獗臼樵詒嘁朐?砘?嘴域確實?忻?所以很多國外的學者都直接取名為龍書。最近機械工業出版社已經出版了此書的中文版,名字就叫《編譯原理》。該書出的比較早,大概是在85或86年編寫完成的,作者之一還是著名的貝爾實驗室的科學家。裡面講解的核心編譯原理至今都沒有變過,所以一直到今天,它的價值都非凡。這本書最大的特點就是一開始就通過一個實際的小例子,把編譯原理的大致內容羅列出來,讓很多編譯原理的初學者很快心裡有了個底,也知道為什麼會有這些理論,怎麼運用這些理論。而這一點是我感覺國內的教材缺乏的東西,所以國內的教材都不是寫給願意自學的讀者,總之讓人看了半天,卻不知道裡面的東西有什麼用。 第二本書的原名叫《ModernCompilerDesign》,中文名字叫做《現代編譯程序設計》。該書由人民郵電出版社所出。此書比較關注的是編譯原理的實踐,書中給出了不少的實際程序代碼,還有很多實際的編譯技術問題等等。此書另外一個特點就是其現代而字。在傳統的編譯原理教材中,你是不可能看到如同Java中的垃圾回收等演算法的。因為Java這樣的解釋執行語言是在近幾年才流行起來的東西。如果你想深入學習編譯原理的理論知識,那麼你肯定得看前面那本龍書,如果你想自己動手做一個先進的編譯器,那麼你得看這本《現代編譯程序設計》。 第三本書就是很多國內的編譯原理學者都推薦的那本《編譯原理及實踐》。或許是這本書引入國內比較早吧,我記得我是在高中就買了這本書,不過也是在前段時間才把整本書看完。此書作為入門教程也的確是個不錯的選擇。書中給出的編譯原理講解也相當細致,雖然不如前面的龍書那麼深入,但是很多地方都是點到為止,作為大學本科教學已經是十分深入了。該書的特點就是注重實踐,不過感覺還不如前面那本《現代編譯程序設計》的實踐味道更重。此書的重點還是在原理上的實踐,而非前面那本那樣的技術實踐。《編譯原理及實踐》在講解編譯原理的各個部分的同時,也在逐步實踐一個現代的編譯器TinyC.等你把整本書看完,差不多自己也可以寫一個TinyC了。作者還對Lex和Yacc這兩個常用的編譯相關的工具進行了很詳細的說明,這一點也是很難在國內的教材中看到的。 推薦了這三本教材,都有英文版和中文版的。很多英文好的同學只喜歡看原版的書,不我的感覺是這三本書的翻譯都很不錯,沒有必要特別去買英文版的。理解理論的實質比理解表面的文字更為重要。 編譯原理的實質 幾乎每本編譯原理的教材都是分成詞法分析,語法分析(LL演算法,遞歸下降演算法,LR演算法),語義分析,運行時環境,中間代碼,代碼生成,代碼優化這些部分。其實現在很多編譯原理的教材都是按照85,86出版的那本龍書來安排教學內容的,所以那本龍書的內容格式幾乎成了現在編譯原理教材的定式,包括國內的教材也是如此。一般來說,大學裡面的本科教學是不可能把上面的所有部分都認真講完的,而是比較偏重於前面幾個部分。像代碼優化那部分東西,就像個無底洞一樣,如果要認真講,就是單獨開一個學期的課也不可能講得清楚。所以,一般對於本科生,對詞法分析和語法分析掌握要求就相對要高一點了。 詞法分析相對來說比較簡單。可能是詞法分析程序本身實現起來很簡單吧,很多沒有學過編譯原理的人也同樣可以寫出各種各樣的詞法分析程序。不過編譯原理在講解詞法分析的時候,重點把正則表達式和自動機原理加了進來,然後以一種十分標準的方式來講解詞法分析程序的產生。這樣的做法道理很明顯,就是要讓詞法分析從程序上升到理論的地步。 語法分析部分就比較麻煩一點了。現在一般有兩種語法分析演算法,LL自頂向下演算法和LR自底向上演算法。LL演算法還好說,到了LR演算法的時候,困難就來了。很多自學編譯原理的都是遇到LR演算法的理解成問題後就放棄了自學。其實這些東西都是只要大家理解就可以了,又不是像詞法分析那樣非得自己寫出來才算真正的會。像LR演算法的語法分析器,一般都是用工具Yacc來生成,實踐中完全沒有比較自己來實現。對於LL演算法中特殊的遞歸下降演算法,因為其實踐十分簡單,那麼就應該要求每個學生都能自己寫。當然,現在也有不少好的LL演算法的語法分析器,不過要是換在非C平台,比如Java,Delphi,你不能運用YACC工具了,那麼你就只有自己來寫語法分析器。 等學到詞法分析和語法分析時候,你可能會出現這樣的疑問:詞法分析和語法分析到底有什麼?就從編譯器的角度來講,編譯器需要把程序員寫的源程序轉換成一種方便處理的數據結構(抽象語法樹或語法樹),那麼這個轉換的過程就是通過詞法分析和語法分析的。其實詞法分析並非一開始就被列入編譯器的必備部分,只是我們為了簡化語法分析的過程,就把詞法分析這種繁瑣的工作單獨提取出來,就成了現在的詞法分析部分。除了編譯器部分,在其它地方,詞法分析和語法分析也是有用的。比如我們在DOS,Unix,linux下輸入命令的時候,程序如何分析你輸入的命令形式,這也是簡單的應用。總之,這兩部分的工作就是把不規則的文本信息轉換成一種比較好分析好處理的數據結構。那麼為什麼編譯原理的教程都最終把要分析的源分析轉換成樹這種數據結構呢?數據結構中有Stack,Line,List這么多數據結構,各自都有各自的特點。但是Tree這種結構有很強的遞歸性,也就是說我們可以把Tree的任何結點Node提取出來後,它依舊是一顆完整的Tree。這一點符合我們現在編譯原理分析的形式語言,比如我們在函數裡面使用函樹,循環中使用循環,條件中使用條件等等,那麼就可以很直觀地表示在Tree這種數據結構上。同樣,我們在執行形式語言的程序的時候也是如此的遞歸性。在編譯原理後面的代碼生成的部分,就會介紹一種堆棧式的中間代碼,我們可以根據分析出來的抽象語法樹,很容易,很機械地運用遞歸遍歷抽象語法樹就可以生成這種指令代碼。而這種代碼其實也被廣泛運用在其它的解釋型語言中。像現在流行的Java,.NET,其底層的位元組碼bytecode,可以說就是這中基於堆棧的指令代碼的。 關於語義分析,語法制導翻譯,類型檢查等等部分,其實都是一種完善前面得到的抽象語法樹的過程。比如說,我們寫C語言程序的時候,都知道,如果把一個浮點數直接賦值給一個整數,就會出現類型不匹配,那麼C語言的編譯器是怎麼知道的呢?就是通過這一步的類型檢查。像C++語言這中支持多態函數的語言,這部分要處理的問題就更多更復雜了。大部編譯原理的教材在這部分都是講解一些比較好的處理策略而已。因為新的問題總是在發生,舊的辦法不見得足夠解決。 本來說,作為一個編譯器,起作用的部分就是用戶輸入的源程序到最終的代碼生成。但是在講解最終代碼生成的時候,又不得不講解機器運行環境等內容。因為如果你不知道機器是怎麼執行最終代碼的,那麼你當然無法知道如何生成合適的最終代碼。這部分內容我自我感覺其意義甚至超過了編譯原理本身。因為它會把一個計算機的程序的運行過程都通通排在你面前,你將來可能不會從事編譯器的開發工作,但是只要是和計算機軟體開發相關的領域,都會涉及到程序的執行過程。運行時環境的講解會讓你更清楚一個計算機程序是怎麼存儲,怎麼裝載,怎麼執行的。關於部分的內容,我強烈建議大家看看龍書上的講解,作者從最基本的存儲組織,存儲分配策略,非局部名字的訪問,參數傳遞,符號表到動態存儲分配(malloc,new)都作了十分詳細的說明。這些東西都是我們編寫平常程序的時候經常要做的事情,但是我們卻少去探求其內部是如何完成。 關於中間代碼生成,代碼生成,代碼優化部分的內容就實在不好說了。國內很多教材到了這部分都會很簡單地走馬觀花講過去,學生聽了也只是作為了解,不知道如何運用。不過這部分內容的東西如果要認真講,單獨開一學期的課程都講不完。在《編譯原理及實踐》的書上,對於這部分的講解就恰到好處。作者主要講解的還是一種以堆棧為基礎的指令代碼,十分通俗易懂,讓人看了後,很容易模仿,自己下來後就可以寫自己的代碼生成。當然,對於其它代碼生成技術,代碼優化技術的講解就十分簡單了。如果要仔細研究代碼生成技術,其實另外還有本叫做《》,那本書現在由機械工業出版社引進的,十分厚重,而且是英文原版。不過這本書我沒有把它列為推薦書給大家,畢竟能把龍書的內容搞清楚,在中國已經就算很不錯的高手了,到那個時候再看這本《》也不遲。代碼優化部分在大學本科教學中還是一個不太重要的部分,就是算是實踐過程中,相信大家也不太運用得到。畢竟,自己做的編譯器能正確生成執行代碼已經很不錯了,還談什麼優化呢? 編譯原理的課程畢竟還只是講解原理的課程,不是專門的編譯技術課程。這兩門課程是有很大的區別的。編譯技術更關注實際的編寫編譯器過程中運用到的技術,而原理的課
『陸』 編譯原理的內容簡介
本書介紹編譯器構造的一般原理和基本實現方法,主要內容包括詞法分析、語法分析、語義分析、中間代碼生成、代碼優化和目標代碼生成等。除了介紹命令式編程語言的編譯技術外,本書還介紹面向對象語言和函數式編程語言的實現技術。本書還強調一些相關的理論知識,如形式語言和自動機理論、語法制導的定義和屬性文法、類型論和類型系統等。
本書取材廣泛新穎、圖文並茂,注意理論聯系實際。本書可作為高等學校計算機科學及相關專業的教材,也可供計算機軟體工程技術人員參考使用。
『柒』 編譯原理
C語言編譯過程詳解
C語言的編譯鏈接過程是要把我們編寫的一個C程序(源代碼)轉換成可以在硬體上運行的程序(可執行代碼),需要進行編譯和鏈接。編譯就是把文本形式源代碼翻譯為機器語言形式的目標文件的過程。鏈接是把目標文件、操作系統的啟動代碼和用到的庫文件進行組織形成最終生成可執行代碼的過程。過程圖解如下:
從圖上可以看到,整個代碼的編譯過程分為編譯和鏈接兩個過程,編譯對應圖中的大括弧括起的部分,其餘則為鏈接過程。
一、編譯過程
編譯過程又可以分成兩個階段:編譯和匯編。
1、編譯
編譯是讀取源程序(字元流),對之進行詞法和語法的分析,將高級語言指令轉換為功能等效的匯編代碼,源文件的編譯過程包含兩個主要階段:
第一個階段是預處理階段,在正式的編譯階段之前進行。預處理階段將根據已放置在文件中的預處理指令來修改源文件的內容。如#include指令就是一個預處理指令,它把頭文件的內容添加到.cpp文件中。這個在編譯之前修改源文件的方式提供了很大的靈活性,以適應不同的計算機和操作系統環境的限制。一個環境需要的代碼跟另一個環境所需的代碼可能有所不同,因為可用的硬體或操作系統是不同的。在許多情況下,可以把用於不同環境的代碼放在同一個文件中,再在預處理階段修改代碼,使之適應當前的環境。
主要是以下幾方面的處理:
(1)宏定義指令,如 #define a b。
對於這種偽指令,預編譯所要做的是將程序中的所有a用b替換,但作為字元串常量的 a則不被替換。還有 #undef,則將取消對某個宏的定義,使以後該串的出現不再被替換。
(2)條件編譯指令,如#ifdef,#ifndef,#else,#elif,#endif等。
這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯程序對哪些代碼進行處理。預編譯程序將根據有關的文件,將那些不必要的代碼過濾掉
(3) 頭文件包含指令,如#include "FileName"或者#include <FileName>等。
在頭文件中一般用偽指令#define定義了大量的宏(最常見的是字元常量),同時包含有各種外部符號的聲明。採用頭文件的目的主要是為了使某些定義可以供多個不同的C源程序使用。因為在需要用到這些定義的C源程序中,只需加上一條#include語句即可,而不必再在此文件中將這些定義重復一遍。預編譯程序將把頭文件中的定義統統都加入到它所產生的輸出文件中,以供編譯程序對之進行處理。包含到C源程序中的頭文件可以是系統提供的,這些頭文件一般被放在/usr/include目錄下。在程序中#include它們要使用尖括弧(<>)。另外開發人員也可以定義自己的頭文件,這些文件一般與C源程序放在同一目錄下,此時在#include中要用雙引號("")。
(4)特殊符號,預編譯程序可以識別一些特殊的符號。
例如在源程序中出現的LINE標識將被解釋為當前行號(十進制數),FILE則被解釋為當前被編譯的C源程序的名稱。預編譯程序對於在源程序中出現的這些串將用合適的值進行替換。
預編譯程序所完成的基本上是對源程序的「替代」工作。經過此種替代,生成一個沒有宏定義、沒有條件編譯指令、沒有特殊符號的輸出文件。這個文件的含義同沒有經過預處理的源文件是相同的,但內容有所不同。下一步,此輸出文件將作為編譯程序的輸出而被翻譯成為機器指令。
第二個階段編譯、優化階段。經過預編譯得到的輸出文件中,只有常量;如數字、字元串、變數的定義,以及C語言的關鍵字,如main,if,else,for,while,{,}, +,-,*,\等等。
編譯程序所要作得工作就是通過詞法分析和語法分析,在確認所有的指令都符合語法規則之後,將其翻譯成等價的中間代碼表示或匯編代碼。
優化處理是編譯系統中一項比較艱深的技術。它涉及到的問題不僅同編譯技術本身有關,而且同機器的硬體環境也有很大的關系。優化一部分是對中間代碼的優化。這種優化不依賴於具體的計算機。另一種優化則主要針對目標代碼的生成而進行的。
對於前一種優化,主要的工作是刪除公共表達式、循環優化(代碼外提、強度削弱、變換循環控制條件、已知量的合並等)、復寫傳播,以及無用賦值的刪除,等等。
後一種類型的優化同機器的硬體結構密切相關,最主要的是考慮是如何充分利用機器的各個硬體寄存器存放的有關變數的值,以減少對於內存的訪問次數。另外,如何根據機器硬體執行指令的特點(如流水線、RISC、CISC、VLIW等)而對指令進行一些調整使目標代碼比較短,執行的效率比較高,也是一個重要的研究課題。
2、匯編
匯編實際上指把匯編語言代碼翻譯成目標機器指令的過程。對於被翻譯系統處理的每一個C語言源程序,都將最終經過這一處理而得到相應的目標文件。目標文件中所存放的也就是與源程序等效的目標的機器語言代碼。目標文件由段組成。通常一個目標文件中至少有兩個段:
代碼段:該段中所包含的主要是程序的指令。該段一般是可讀和可執行的,但一般卻不可寫。
數據段:主要存放程序中要用到的各種全局變數或靜態的數據。一般數據段都是可讀,可寫,可執行的。
UNIX環境下主要有三種類型的目標文件:
(1)可重定位文件
其中包含有適合於其它目標文件鏈接來創建一個可執行的或者共享的目標文件的代碼和數據。
(2)共享的目標文件
這種文件存放了適合於在兩種上下文里鏈接的代碼和數據。
第一種是鏈接程序可把它與其它可重定位文件及共享的目標文件一起處理來創建另一個 目標文件;
第二種是動態鏈接程序將它與另一個可執行文件及其它的共享目標文件結合到一起,創建一個進程映象。
(3)可執行文件
它包含了一個可以被操作系統創建一個進程來執行之的文件。匯編程序生成的實際上是第一種類型的目標文件。對於後兩種還需要其他的一些處理方能得到,這個就是鏈接程序的工作了。
二、鏈接過程
由匯編程序生成的目標文件並不能立即就被執行,其中可能還有許多沒有解決的問題。
例如,某個源文件中的函數可能引用了另一個源文件中定義的某個符號(如變數或者函數調用等);在程序中可能調用了某個庫文件中的函數,等等。所有的這些問題,都需要經鏈接程序的處理方能得以解決。
鏈接程序的主要工作就是將有關的目標文件彼此相連接,也即將在一個文件中引用的符號同該符號在另外一個文件中的定義連接起來,使得所有的這些目標文件成為一個能夠被操作系統裝入執行的統一整體。
根據開發人員指定的同庫函數的鏈接方式的不同,鏈接處理可分為兩種:
(1)靜態鏈接
在這種鏈接方式下,函數的代碼將從其所在地靜態鏈接庫中被拷貝到最終的可執行程序中。這樣該程序在被執行時這些代碼將被裝入到該進程的虛擬地址空間中。靜態鏈接庫實際上是一個目標文件的集合,其中的每個文件含有庫中的一個或者一組相關函數的代碼。
(2) 動態鏈接
在此種方式下,函數的代碼被放到稱作是動態鏈接庫或共享對象的某個目標文件中。鏈接程序此時所作的只是在最終的可執行程序中記錄下共享對象的名字以及其它少量的登記信息。在此可執行文件被執行時,動態鏈接庫的全部內容將被映射到運行時相應進程的虛地址空間。動態鏈接程序將根據可執行程序中記錄的信息找到相應的函數代碼。
對於可執行文件中的函數調用,可分別採用動態鏈接或靜態鏈接的方法。使用動態鏈接能夠使最終的可執行文件比較短小,並且當共享對象被多個進程使用時能節約一些內存,因為在內存中只需要保存一份此共享對象的代碼。但並不是使用動態鏈接就一定比使用靜態鏈接要優越。在某些情況下動態鏈接可能帶來一些性能上損害。
我們在linux使用的gcc編譯器便是把以上的幾個過程進行捆綁,使用戶只使用一次命令就把編譯工作完成,這的確方便了編譯工作,但對於初學者了解編譯過程就很不利了,下圖便是gcc代理的編譯過程:
從上圖可以看到:
預編譯
將.c 文件轉化成 .i文件
使用的gcc命令是:gcc –E
對應於預處理命令cpp
編譯
將.c/.h文件轉換成.s文件
使用的gcc命令是:gcc –S
對應於編譯命令 cc –S
匯編
將.s 文件轉化成 .o文件
使用的gcc 命令是:gcc –c
對應於匯編命令是 as
鏈接
將.o文件轉化成可執行程序
使用的gcc 命令是: gcc
對應於鏈接命令是 ld
總結起來編譯過程就上面的四個過程:預編譯、編譯、匯編、鏈接。了解這四個過程中所做的工作,對我們理解頭文件、庫等的工作過程是有幫助的,而且清楚的了解編譯鏈接過程還對我們在編程時定位錯誤,以及編程時盡量調動編譯器的檢測錯誤會有很大的幫助的。
是否可以解決您的問題?
『捌』 編譯器的工作分為哪幾個階段
編譯器就是一個普通程序,沒什麼大不了的
什麼是編譯器?
編譯器是一個將高級語言翻譯為低級語言的程序。
首先我們一定要意識到編譯器就是一個普通程序,沒什麼大不了的。
在沒有弄明白編譯器如何工作之前你可以簡單的把編譯器當做一個黑盒子,其作用就是輸入一個文本文件輸出一個二進制文件。
基本上編譯器經過了以下幾個階段,等等,這句話教科書上也有,但是我相信很多同學其實並沒有真正理解這幾個步驟到底在說些什麼,為了讓你徹底理解這幾個步驟,我們用一個簡單的例子來講解。
假定我們有一段程序:
while (y < z) {
int x = a + b;
y += x;
}
那麼編譯器是怎樣把這一段程序人類認識的程序轉換為CPU認識的二進制機器指令呢?
提取出每一個單詞:詞法分析
首先編譯器要把源代碼中的每個「單詞」提取出來,在編譯技術中「單詞」被稱為token。其實不只是每個單詞被稱為一個token,除去單詞之外的比如左括弧、右括弧、賦值操作符等都被稱為token。
從源代碼中提取出token的過程就被稱為詞法分析,Lexical Analysis。
經過一遍詞法分析,編譯器得到了以下token:
T_While while
T_LeftParen (
T_Identifier y
T_Less <
T_Identifier z
T_RightParen )
T_OpenBrace {
T_Int int
T_Identifier x
T_Assign =
T_Identifier a
T_Plus +
T_Identifier b
T_Semicolon ;
T_Identifier y
T_PlusAssign +=
T_Identifier x
T_Semicolon ;
T_CloseBrace }
就這樣一個磁碟中保存的字元串源代碼文件就轉換為了一個個的token。
這些token想表達什麼意思:語法分析
有了這些token之後編譯器就可以根據語言定義的語法恢復其原本的結構,怎麼恢復呢?
原來,編譯器在掃描出各個token後根據規則將其用樹的形式表示出來,這顆樹就被稱為語法樹。
語法樹是不是合理的:語義分析
有了語法樹後我們還要檢查這棵樹是不是合法的,比如我們不能把一個整數和一個字元串相加、比較符左右兩邊的數據類型要相同,等等。
這一步通過後就證明了程序合法,不會有編譯錯誤。
『玖』 編譯原理及編譯程序構造課後習題答案 薛聯鳳
您好,《普通高校計算機專業精品教材系列:編譯原理及編譯程序構造(第2版)》介紹編譯理論基礎及其實現方法,強調語言的形式化定義、編譯技術的各種概念及實現過程的具體方法。介紹過程以演算法為核心,力求簡單明了地反映編譯的基礎知識。從形式語言理論角度討論詞法分析和語法分析技術,為計算機軟體工作者開發大型軟體打下良好基礎。《普通高校計算機專業精品教材系列:編譯原理及編譯程序構造(第2版)》以理論聯系實際為宗旨,內容深入淺出,重點突出,並結合構造el語言的編譯程序介紹一種常用而又簡單的編譯方法。