1.引論
完成語言翻譯工作的軟件系統稱為編譯器()
1.1 語言處理器
一個編譯器就是一個程序
解釋器()是另一種常見的語言處理器,它并不通過翻譯的方式生成目標程序,從用戶角度看,解釋器直接利用用戶提供的輸入執行源程序中指定的操作。
鏈接器()能夠解決外部內存地址的問題
加載器()把所有的可執行目標文件放到內存中
1.2 編譯器結構
分析()把源程序分解為多個組成要素,并在這些要素之上加上語法結構
綜合()根據中間表示和符號表中的信息哎構造用戶期待的目標程序,分析部分一般稱為編譯器的前端(front end)而綜合部分被稱為后端(back end)
1.2.1 詞法分析
編譯器的第一個步驟稱為詞法分析( )或者掃描(),讀入組成源程序的字符流,并且將它們組織稱為有意義的詞素(),對于詞素,詞法分析器產生如下形式的詞法單元(token)
graph TD
字符流 --> 詞法分析器
詞法分析器 --> 符號流
符號流 --> 語法分析
語法分析 --> 語法樹
語法樹 --> 中間代碼生成器

中間代碼生成器 --> 中間表示形式
中間表示形式 --> 機器無關代碼優化器
機器無關代碼優化器 --> 中間表示形式
中間表示形式 --> 代碼生成器
代碼生成器 --> 目標機器語言
目標機器語言 --> 機器相關代碼優化器
機器相關代碼優化器 --> 目標機器語言
-->
1.2.2 語法分析
語法分析使用由詞法分析器生成的各個詞法單元的第一個分量來創建樹形的中間表示,該中間表示給出了詞法分析產生的詞法單元流的語法結構。
1.2.3 語義分析
語法分析( )使用語法樹和符號表中的信息來檢查源程序是否和語言定義的語法一致。
語義分析的一個重要部分是類型檢查。
1.2.4 中間代碼生成
編譯器可能在將源程序翻譯成目標代碼的過程中,翻譯出一個或者多個中間表示。
1.2.5 代碼優化
機器無關的代碼優化步驟試圖改進中間代碼語言翻譯器電路工作原理圖,以便生成更好的目標代碼。
1.2.6 代碼生成
代碼生成器以源程序的中間表示形式作為輸入,并把它映射到目標語言。代碼生成的一個只管中間的方面是合理分配寄存器以存放變量。
1.2.7 符號表管理
符號表數據結構為每個變量名字創建了一個記錄條目,記錄的字段就是名字的各個屬性,這個數據結構應該允許編譯器迅速查找到每個名字的記錄,并向記錄中快速存放和獲取記錄中的數據。
1.2.8 多個步驟組合
多個步驟的活動可以被組合成一趟,每趟讀取一個輸入文件并產生一個輸出文件。
1.2.9 編譯器構造工具
常用的編譯器構建工具包括:
1.語法分析器的生成器:可以根據一個程序設計語言的語法描述自動生成語法分析器;
2.掃描器的生成器:根據一個語言的語法單元的正則表達式描述生成詞法分析器;
3.語法制導的翻譯引擎:可以生成一組用于遍歷分析書并生成中間代碼的例程
4.代碼生成器的生成器:依據一組關于如何把中間語言的每個運算翻譯成目標機上的及其語言規則,生成一個代碼生成器;
5.數據流分析引擎:幫助收集數據流信息,即程序中的值如何從一個部分傳遞到另一部分,數據流分析的代碼優化的一個重要部分。
6.編譯器構造工具集:提供可以用于構造編譯器的不同階段的例程的完整集合。
1.3 程序設計語言的發展歷程 1.3.1 走向高級程序設計語言
第一代是及其語言,第二代是匯編語言,第三代是,Lisp,C ,C++,C#及Java這樣的高級程序設計語言。
另一種語言分類方式把程序中指明如何完成一個計算任務的語言稱為強制式()語言,把程序中指明要進行哪些計算的語言稱為聲明式()語言。
1.3.2 對編譯器的影響
編譯器必須能夠正切翻譯用源語言書寫的所有程序,這樣的程序集合通常是無窮的。
1.4構建一個編譯器的相關科學
編譯器必須接受所有遵循語言規范的源程序,源程序的集合是無窮的編譯器所做的任何翻譯工作都不能改變被編譯源程序的含義。
1.4.1 編譯器設計和實現中的建模
對編譯器的研究主要是有關如何設計正確的數學模型和選擇正確算法的研究。最基本的數學模型是有窮狀態自動機和正則表達式。
1.4.2代碼優化的科學
編譯器優化必須滿足下面的設計目標:
1.優化必須是正確的,也就是說,不能改變被編譯程序的含義;
2.優化必須能夠改變很多程序的性能;
3.優化所需的時間必須保持在合理的范圍內;
4.所需要的工程方面的工作必須是可管理的。
第二個目標是編譯器應該有效提高很多輸入程序的性能;
第三個要使編譯時間保持在較短的范圍內;
1.5編譯技術的應用
編譯器設計并不只是關于編譯器的,很多人用到了在學校里面研究編譯器時學到的技術
1.5.1高級程序設計語言的實現
一個高級程序設計語言定義了一個編程抽象,程序要使用這個語言表達算法語言翻譯器電路工作原理圖, 而編譯器必須要把這個程序翻譯成目標語言。
1.數據抽象
2.特性的繼承
1.5.2 針對計算機體系結構的優化
所有的高性能西戎都利用了兩種技術:并行()和內存層次結構( ),并行可以出現在多個層次上:在指令層次上,多個運算可以被同時執行 ,在處理層次上,同一個應用的多個不同線程在不同的處理器上運行。
并行性
指令級的并行也顯示地出現在指令集中,VLIW(Very Long Word,非常長指令字)機器用友可并行執行多個運算的指令。
內存層次結構
1.5.3 型計算機體系結構的設計
RISC
有關編譯器如何影響計算機體系結構設計的最有名的例子之一是RISC( Set ,精簡指令集計算機)在發明RISC之前,趨勢是開發的指令集越來越復雜。以使得匯編編程變得更容易,這些體系結構稱為CISC( Set ,復雜指令集計算機)
專用體系結構
過去的30年中包括:數據流機器,向量機,VLIW(非常長指令字)機器,SIMD(單指令,多數據)處理器陣列,心動陣列( array)共享內存的多處理器、分布式內存的多處理器
1.5.4程序翻譯
二進制翻譯
編譯器技術可以把一個機器的二進制翻譯成另一個機器的二進制代碼,使得可以在一個機器上運行原來為另一個指令集編譯的程序。二進制翻譯也可以用來提供向后兼容性。
硬件合成
和VDHL(Very High-speed ,甚高速集成電路硬件描述語言).硬件設計通常是在寄存器傳輸層( Level,RTL)上描述的
數據查詢解釋器
數據庫查詢由包含了關系和布爾運算符的斷言組成,它們可以被解釋,也可以編譯為代碼,以便在一個數據庫中搜索滿足這個斷言的記錄
編譯然后模擬
模擬是在很多科學和工程領域內使用的通用技術。
1.5.5 軟件生產率工具
類型檢查
類型檢查是一種有效的,且被充分研究的技術,它可以用來檢查一些錯誤,比如運算被作用于錯誤類型的對象上,或者傳遞一個過程的參數和該過程的泛型()不匹配。
邊界檢查
相對于教高級的程序設計語言而言,用較低級語言編程更加容易犯錯,
內管管理工具
垃圾收集機制是在效率和易編程及軟件可靠性之間進行折中處理的另一個極好的例子。
1.6程序設計語言基礎 1.6.1 靜態和動態的區別
編譯器能夠對一個程序作出那些判定,如果一個語言使用的策略支持編譯器靜態決定某個問題,那么我們說這個語言使用了一個靜態()策略,或者說這個問題可以在編譯時( time)決定,另一方面,一個只允許在運行程序的時候作出決定的策略被稱為動態策略( )。或者被認為需要在運行時刻(run time)作出決定。
大部分語言(C和Java)使用靜態作用域
1.6.2 環境與狀態
1.環境()是從一個從名字到存儲位置的映射,因為變量就是指內存位置,我們還可以換一種方法,把環境定義為從名字到變量的映射。
2.狀態(state)是從一個內存位置到它們的值的映射。
1.6.3靜態作用域和塊結構
C語言的作用域規則是基于程序結構的,一個聲明的作用 域又該聲明在程序中出現的位置隱含地決定
1.6.4 顯式訪問控制
通過 和這樣的關鍵字的使用,像C++和Java這樣的面向對象語言提供了對超累中的成員名字的顯示訪問控制。