[編譯原理讀書筆記][第一章 引論]

[編譯原理讀書筆記][第一章 引論]

標籤(空格分隔): 未分類前端


第一章 引論

1.1 語言處理器

簡單的說,一個編譯器就是一個程序,它能夠閱讀以某一種語言(源語言)編寫的程序,並把該程序翻譯稱爲一個等價的,用另外一種(目標語言)編寫的程序。正則表達式

  • 編譯器的重要任務之一是報告它在翻譯過程當中發現的錯誤。數據庫

  • 解釋器(interpreter)是另外一種常見的語言處理器。直接利用源代碼和輸入來產生輸出。後端

Java 結合了編譯解釋過程。緩存

  • Java源代碼首先被編譯成一個稱爲字節碼(bytecode)的中間表現形式。
  • 而後JVM對獲得的字節碼加以解釋和執行。
    image_1ash6u5ln1od61c16166mo3a14so9.png-15kB

爲了更快地完成輸入和輸出的處理,有些被稱爲即便(just in time,JIT)編譯器的JAVA編譯器在運行中間程序處理輸入的那一刻,首先把字節碼翻譯爲機器語言,而不用解釋器,這樣能加快速度。安全

具體過程

出了編譯器以外,建立一個可執行的目標程序還須要一些其餘程序。數據結構

image_1ash7d7l4gum1id9ddl1ia0jljm.png-36.8kB

  • 預處理器:一個程序可能被分爲多個模塊,存放於獨立的文件中。把源程序聚合在一塊兒的任務會由一個被稱爲預處理器(preprocessor)的程序獨立完成。
    • 預處理器還負責把宏的轉爲實際的語句。
  • 編譯器:預處理後的源程序經編譯器可能產生一個彙編語言做爲輸出。
    • 由於彙編語言容易調試和輸出。
  • 彙編器:彙編語言程序由彙編器(assembler)的程序進行處理,生成可重定位的機器代碼
  • 連接器/加載器:大型程序常常被分爲多個部分進行編譯。所以,可重定位的機器代碼有必要和其餘可重定位的目標文件以及庫文件鏈接到一塊兒,造成真正運行的代碼。
    • 連接器(linker)解決外部內存地址的問題。
    • 加載器(loader)把全部的可執行目標文件加載進內存執行。

1.2 一個編譯器的結構

編譯器由兩部分組成:分析部分綜合部分架構

分析部分簡述

分析(analysis)部分把源程序分解爲多個組成要素,並在這些要素之上加入語法結構。而後,它使用這個結構來建立該源程序的一個中間表示前後端分離

  • 若是分析部分檢查出源程序有錯誤,必須提供有用的信息供用戶修改。
  • 分析部分還會收集源程序的信息,並存到符號表(symbol table)的數據結構中。

符號表中間表現形式一塊兒傳送給綜合部分函數

綜合部分簡述

綜合(synthesis)部分根據中間表示和符號表中的信息構造用戶期待的目標程序。

編譯器詳細過程簡述

image_1ash8more3doggm1ct7d2upeh1g.png-63kB

  • 分析部分常常被稱爲編譯器的前端,而綜合部分被稱爲後端
  • 有些編譯器在前端和後端之間有一個與機器無關的優化步驟,是可選的。

1.2.1 詞法分析

編譯器的第一個步驟稱爲詞法分析(lexical analysis)掃描(scanning)

詞法分析器讀入組成源程序的字符流,而且將它們組織成爲有意義的詞素(lexeme)的序列

  • 對於每一個詞素,詞法分析器產生以下形式的詞法單元(token)
    <token-name,attribute-value>

例子: position = initial + rate * 60

通過詞法分析後轉變爲<id,1> <=> <id,2> <+> <id,3> <*> <60>

從技術上講,60應該被描述爲<number,4>,4指向符號表中對應於60的條目。

image_1ashb8teb1umj1jdeee51q9s1btc2q.png-63.9kB

1.2.2 語法分析

語法分析(syntax analysis)解析(parsing)

根據詞法分析的結果,進行語法分析,結果通常是一顆語法樹等語法結構,如圖1-7

編譯器的後續步驟使用這個語法結構來幫助分析源程序,並生成目標程序。在第四章,咱們將使用上下文無關文法來描述程序設計語言的語法結構

1.2.3 語義分析

語義分析器(semantic analyzer)使用語法樹和符號表中的信息來檢查源程序是否和語言定義的語義一致。同時收集類型信息,並把信息存放在語法樹或符號表中,以便在隨後的中間代碼中使用。

類型檢查與自動類型轉換

這就是語義分析中一個十分重要的功能,具體例子就是圖中的inttofloat

咱們將在第六章詳細介紹。

1.2.4 中間代碼生成

將語法樹等中間形式翻譯爲三地址代碼的中間形式。

第六章咱們將將詳細介紹。

1.2.5 代碼優化

機器無關的代碼優化步驟試圖改進中間代碼,以便生成更好的目標代碼。
如下是個簡單的例子

image_1avquqeg2vqlvevcmq162d138i9.png-7.3kB
優化爲
image_1avquqpkje131fon1eu019s0b57m.png-4.3kB
第八章咱們將詳細討論。

1.2.6 代碼生成

生成類彙編語言的目標語言,

image_1avqvsaee7h177p14a7978st81j.png-14.5kB
在第八章中詳細討論

上面代碼忽略了對源程序中的標示符進行存儲分配的重要問題。
咱們將在第七章看到,編譯器在中間代碼生成或代碼生成階段對有關存儲器分配的決定,和運行時刻的存儲組織方式依賴於被編譯的語言。

1.2.7 符號表管理

符號表管理記錄源程序變量過程的各類信息

  • 屬性的存儲分配,類型,做用域等信息
  • 過程的參數數量,類型,每一個參數的傳遞方式以及返回類型等。

符號表的數據結構

相似與平衡樹紅黑樹之類的數據結構,便於查詢。

1.2.8 將多個步驟組合爲趟

(其實就是所謂的先後端分離的意思)

前端步驟能夠當作一趟,根據中間代碼生成目標代碼的後端也能夠看作一趟。

前端趟和後端趟根據目標自由搭配。

1.2.9 編譯器構造工具。

  • 語法分析器的生成器:根據程序語言的語法描述生成語法分析器
  • 掃描器的生成器:能夠根據一個語言的語法單元的正則表達式描述生成詞法分析器。
  • 語法制導的翻譯程序:能夠生成一組用於遍歷分析樹並生成中間代碼的例程。
  • 代碼生成器的生成器:依據一組關於如何把中間語言的每一個運算翻譯爲目標機上的機器語言規則,生成一個代碼生成器。
  • 數據流分析引擎: 能夠幫助收集數據流信息,即程序中的值若是從程序的一個部分傳遞到另外一個部分。數據流分析是代碼優化的一個重要部分。
  • 編譯器構造工具集:
    提供了可用於構造編譯器的不一樣階段的例程的完整集合。

1.3 程序設計語言的發展歷史

1.3.1 走向高級程序設計語言

按時代分類

  • 第一代語言:機器語言
  • 第二代語言:彙編語言
  • 第三代語言:高級程序設計語言
  • 第四代語言:特定應用設計語言:生成報告的NOMAD,用於數據庫查詢的SQL
  • 第五代語言:基於邏輯與約束語言:PrologOPS5

    按如何完成一個計算任務

  • 強制式語言:
  • 聲明式語言:函數式語言約束邏輯式語言屬於此類。

其餘分類

  • 過程式語言(馮諾伊曼語言)
  • 面嚮對象語言
  • 腳本語言

1.3.2 對編譯器的影響

複雜多變的程序設計語言,對編譯器及編譯器設計人員也提出了極大的考驗。
本書將會告訴咱們編譯器設計的根本思想和方法論。

1.4 構建一個編譯器的相關科學

接收一個問題,抓住問題的關鍵特性的數學抽象表示,並用數學方法解決他。

1.4.1 編譯器設計和實現中的建模

基本的幾個模型

  • 有窮狀態自動機 *第三章
  • 正則表達式 *第三章
  • 上下文無關法 *第四章
  • 樹形結構 *第五章

1.4.2 代碼優化的科學

  • 優化是必須正確的
  • 優化必須能改善程序的性能
  • 優化須要的時間在合理範圍內
  • 所須要的工程方面的工做是須要可管理的

1.5 編譯技術的應用

1.5.1 高級程序設計語言的實現

1.5.2 針對計算機體系的優化

並行和內存層次結構

  • 並行性友好和緩存友好的代碼。

1.5.3 新計算機體系結構的設計

RISC

  • RISC 是將來的趨勢,更加有利於編譯器的優化,和處理器的優化。
  • 對於CISC的X86 使用其精簡指令是最高效的方法。

專用體系架構

  • 百花齊放,須要更加好的編譯技術爲架構語言設計編譯器。

1.5.4 程序翻譯

二進制翻譯

編譯器技術能夠用於把一個機器的二進制代碼翻譯成另外一個機器的二進制代碼,使得能夠在一個機器上運行本來爲另外一個指令集編譯的程序。

  • 增長可用軟件
  • 提供向後兼容性

硬件合成

不只僅大部分軟件是用高級語言描述。大部分硬件設計也是使用高級硬件描述語言描述的。這些語言有VerilogVHDL. 硬件設計一般一般是在寄存器傳輸層(Register Transfer Level,RTL)描述.

數據查詢解釋器

編譯而後模擬

1.5.5 軟件生產效率工具

  • 數據流分析技術靜態的定位錯誤
  • 錯誤探測器能夠是不健全的.

類型檢查

  • 運算被做用在錯誤類型的對象上.
  • 傳遞給一個過程的參數和該過程的範型不匹配
  • 經過分析數據流,還能發現空指針被釋放.
  • 用來捕捉安全漏洞

邊界檢查

  • 通常在較低級語言更容易犯

內存管理工具

1.6 程序設計語言基礎

1.6.1 靜態和動態的區別

  • 靜態策略:若是一個語言使用的策略支持編譯器決定某個問題.
  • 動態策略:只容許在運行程序的時候作出決定的策略.

1.6.2 環境與狀態

image_1b02c9m1ffe7aq4g1n1bc86479.png-17.3kB

1.6.3 靜態做用域和塊結構

  • begin end
  • { }

1.6.4 顯示訪問控制

  • public,private,protecte

1.6.5 動態做用域

  • x.m();

1.6.6 參數傳遞機制

  • 值調用
  • 引用調用
  • 名調用: Algol 60使用

1.6.7 別名

相關文章
相關標籤/搜索