編譯原理概述

1.1語言處理器

編譯器和解釋器

  • 第一類:編譯器
    • 將某一種語言(源語言)程序,發一次一個等價的、用另外一種語言(目標語言)編寫的程序。
    • 若是目標語言是一個可執行的機器語言程序,那麼它就能夠被用戶調用,處理輸入併產生輸出。
    • 效率高

輸入圖片說明

  • 第二類:解釋器
    • 不經過翻譯的方式生成目標程序。
    • 解釋器利用用戶提供的輸入執行源程序中指定的操做。
    • 效率低

輸入圖片說明

  • 第三類:混合結構
    • java源程序先被編譯成一個字節碼(bytecode)的中間形式。
    • 由一個虛擬機對字節碼加以解釋執行。
    • 及時編譯器(just in time) 將字節碼翻譯成機器語言,加快執行。

輸入圖片說明

1.2 編譯器結構

輸入圖片說明

  • 詞法分析(lexical analysis):讀入源程序的字符流,將他們組成有意義的詞素(lexeme)的序列。
    • 每一個詞素,分析器產生以下形式的詞法單元(taken):<token-name,attribute-value>
      • token-name:抽象符號
      • attribute-value:符號表中的條目
      • position = initial + rate *60 | -- <id,1><=><id,2><+><id,3><><60>
        • 詞素-- position<id,1>
        • 詞素-- =:<=>
        • 詞素-- initial<id,2>
        • 詞素-- +:<+>
        • 詞素-- rate<id,3>
        • 詞素-- :<>
        • 詞素-- 60:<60>
  • 語法分析(syntax analysis):將詞法單元建立一個語法樹(syntax tree)
  • 語義分析(semantic analyzer):檢測源程序和語言定義的語義是否一致
    • 類型檢測(type checking)
    • 自動類型轉換(coercion),動態類型
  • 中間代碼生成: 將語法樹編譯成一個明確的低級或累積起語言的中間表示。
  • 代碼優化:將機器無關的代碼優化,以便生成更好的目標代碼。
  • 代碼生成:以中間表示形式做爲輸入,並把它映射到目標語言。
    • 若是目標語言是機器代碼,那麼就必須爲程序使用的每一個變量選擇寄存器或內存位置,中間指令被翻譯成爲可以完成相同任務的機器指令序列
    • 合理分配寄存器以存放變量的值

輸入圖片說明

  • 符號表管理
    • 符號表數據結構爲每一個變量名字建立一個記錄條目,記錄的字段是名字的各個屬性。
      • 容許編譯器迅速查找到每一個名字的記錄,冰箱記錄中快速存放獲取記錄的數據。
  • 將多個步驟組合
    • 前端和後端
      • 前端步驟:詞法分析、語法分析、語義分析,中間代碼生成
      • 代碼優化可選
      • 後端步驟:代碼生成
    • 有些編譯器集合是圍繞一組靜心設計的中間表示形式而建立的,這些中間表示形式使得咱們能夠把特定語言的前端和特色目標機的後端相節後。
      • 不一樣的前端和某個目標機的後端結合起來,爲不一樣的源語言創建該目標機器上的編譯器
      • 一個前端和不一樣後端結合,創建針對不一樣目標機器的編譯器
  • 編譯器構造工具
    • 語法分析器的生成器:能夠根據一個程序設計語言的語法描述自動生成語法分析器。
    • 掃描的生成器:能夠根據一個語言的語法單元的正則表達式描述生成詞法分析器。
    • 語法知道的翻譯引擎:能夠生成一組用於變量分析樹並生成中間代碼的例程。
    • 代碼生成器的生成器:依據一組關於如何把中間語言的每一個運算翻譯成目標機上的機器語言的規則,生成一個代碼生成器。
    • 數據流分析引擎:能夠幫助手機數據流信息,即程序中的值如何從程序的一個部分傳遞到另外一部分。數據流分析是代碼優化的重要部分
    • 編譯器構造工具:提供了可用於構造編譯器的不一樣階段的例程的完整集合。數據流分析是代碼優化的重要部分

1.3 編譯器結構

語言的發展

  • 按代劃分
    • 第一代:機器預研
    • 第二代:彙編語言
    • 第三代:Fortran、Cobol、Lisp、C、C++、C#、Java
    • 第四代:特定應用設計的語言
      • 生成報告:NOMAD
      • 數據庫查詢:SQL
      • 文本排版:Postscript
    • 第五代:基於邏輯和約束。Prolog和OPS5
  • 完成計算機任務
    • 強制式(imperative):C、C++、C#、Java
    • 聲明式(declarative):ML、Haskell、Prolog

1.4 編譯器的相關科學

  • 編譯器設計和實現的建模:如何設計正確的數學模型和選擇正確算法的研究。
  • 代碼優化科學:
    • 優化必須是正確的,也就是說,不能改變編譯器程序的含義
    • 優化必須嫩鞏固改善不少程序的性能
    • 優化所需的時間必須保持在合理的範圍內
    • 所需的工程方面的工做必須是可管理的

1.5 編譯技術的應用

  • 高級程序設計語言的實現:
    • 高級語言用低層次內存寄存器控制,極可能會損失性能,特別是目標機器不一樣,編譯後的目標程序效率更低
  • 針對計算機體系結構的優化:
    • 並行性:全部如今微處理器都採用了指令級並行性,多處理器日益流行
    • 內存層次結構:若是一個程序的大部份內存訪問都可以由層次結構中最快的知足,那麼程序的平均內存訪問時間就會下降。
  • 新計算機體系結構的設計
    • RISC(精簡指令集計算機):Reduced Instruction-Set Computer
    • CISC(複雜指令集計算機):Complex Instruction-Set computer
    • 專用體系結構:數據量集羣、向量機、VLIW(很是長指令字)機器、SIMD(單指令,多數據)處理器陣列、心動陣列(systolic array)、共享內存的多處理器、分佈式內存的多處理器。
  • 程序翻譯
    • 二進制翻譯:把一個機器的二進制代碼翻譯成另外一個機器的二進制代碼
    • 硬件合成:Verilog和VHDL
    • 數據查詢解釋器:SQL
    • 編譯後模擬:編譯後的模擬運行科比基於解釋器的方法快借個數量級。(Verilog和VHDL)
  • 軟件生產工具:
    • 數據流分析:能夠在全部可能的執行路徑上找錯誤,而不是像程序測試的時候所在的那樣,僅僅在那些由輸入數據組合執行的路徑上找錯誤。
    • 類型檢查:用於捕捉陳翔的不一致性
    • 邊界檢查:檢查數據不越界
    • 內存管理工具:垃圾輝煌蒐集只是在效率和易編譯及軟件可靠性之間進行折衷處理的例子。

1.6 程序設計預研基礎

  • 靜態和動態區別
    • 靜態策略(編譯時策略):一個語言使用的策略支持編譯器靜態決定某個問題 。
      • 靜態做用域(static scope):變量類型直接聲明 。C/Java
    • 動態策略(運行時策略):一個只容許在運行程序的時候作出決定的策略 。
      • 動態做用域(static scope):當程序運行時,x能夠指向x的幾個聲明中的一個。
  • 環境與狀態(做用域)
    • 環境:從一個名字 (變量名) 到存儲位置的映射。從名字到變量名的映射C語言中的左值
    • 狀態:從內存位置到它們值的映射。C語言:把左值映射到它們的相應的右值
      • 環境的改變要遵照語言的做用域規則。
        • 當f() 運行時,環境相應的調整,是的名字i指向哪一個爲局部變量

輸入圖片說明

...
int i;  /**全局i*/
...
void f(..){
    int i;  /**局部i*/
    ...
    i = 3; /**對局部i的使用*/
    ...
}

...
 x = i+1;   /**對全局i的使用*/
  • 靜態做用域和塊結構
    • :C使用 {和} 來界定一個快,由用 beginend
      • 塊是一種語句
      • 一個塊包含了一個聲明的序列,而後在跟着一個語句序列。
    • C語言的靜態做用域
      • 一個C程序由一個頂層的變量和函數聲明的序列組成。
      • 函數內部能夠聲明變量,變量包括局部變量和參數,每一個這樣的聲明做用域唄限制在它們所出現的那個函數內。
      • 名字x的一個頂層聲明的做用域包括其後的全部程序,作個一個函數中也有一個x的聲明,那麼函數中的x再也不頂層聲明的做用域中。
  • 顯示訪問控制
    • C++/JAVApublic、private、protected
  • 動態做用域
    • 對一個名字x的變量的使用,指向的最近被調用且生命沒有終止。
      • C預處理器中的宏擴展
        • 以下僞碼:當b()執行的時候,會用(X+1) 替換掉a
      • 面向對象編程中的方法解析
        • 動態做用域解析對多臺過程是必不可少的。多態:指對於同一個名字根據參數類型具備兩個或多個定義的過程
#define a (x+1)
int x = 2;

void b() {int x =1 ; printf("%d\n",a) ;}

void c() {print("%d",a);}

void main() {b() ; c();}
  • 參數傳遞機制:實參和形參關聯。
    • 值傳遞、引用傳遞
    • 值調用(call-by-value):調用過程所作的全部關於形式參數的計算都侷限於這個過程,相應的實參不會唄改變。能夠經過傳入一個指針,來改變實參
    • 引用調用(call-by-reference):實參的地址做爲相應的形參值傳遞給了調用者。
  • 別名:多個變量都指向同一個位置
相關文章
相關標籤/搜索