本書的出版具有里程碑意義:它第一次讓編譯原理不再像是一門高深晦澀的“數學課”,而是一個可以調試、可以接觸、可以真切感受的理論體系。本書用1140余幅信息量巨大的運行時結構圖和視頻動畫取代了同類書中復雜枯燥的數學公式,更加立體和直觀,生動地將編譯后的執行程序在內存中的運行時結構圖展現了出來;它第一次將GCC源代碼、編譯原理、運行時結構、編譯系統原理(包含匯編與鏈接)的內在關系、邏輯與原理梳理清楚了,并將它們結合成一個整體。真正能夠讓讀者透徹掌握編譯器如何運行和如何設計,以及為什么要這么設計;它是第一本系統解讀著名商用編譯器GCC核心源代碼的著作,GCC源代碼一共有600萬行,為了便于講解和閱讀,本書進行了取舍和裁剪,講解了與編譯本質相關的最核心的60萬行代碼。
目 錄
作者簡介
前 言
第1章 運行時結構及編譯過程概述 1
1.1 一個簡單C程序的運行時結構 1
1.2 更為復雜C程序的運行時結構 16
1.3 編譯過程概述 25
1.3.1 詞法分析 25
1.3.2 語法分析 26
1.3.3 從語法樹到中間代碼再到目標代碼 26
第2章 詞法分析 28
2.1 詞法分析概要說明 28
2.2 詞法分析過程 31
2.3 狀態轉換圖 36
2.3.1 狀態轉換圖總體介紹 36
2.3.2 依托狀態轉換圖展現詞法分析過程 42
2.4 GCC實現詞法分析的源代碼 55
2.4.1 詞法分析源代碼總覽 55
2.4.2 結合GCC源代碼講解詞法分析過程 55
2.4.3 標識符、數字、字符和字符串的詳細分析過程 65
第3章 語法分析 74
3.1 語法分析綜述 74
3.2 語法分析思路 74
3.3 產生式 78
3.3.1 什么是產生式 78
3.3.2 產生式的具體示例 80
3.4 匹配產生式,消除左遞歸 89
3.4.1 用標準產生式做匹配,出現左遞歸 89
3.4.2 消除左遞歸 93
3.4.3 產生式的工作效率 97
3.5 提取左公因子,消除回溯 100
3.5.1 對“直接聲明符”的產生式提取左公因子 100
3.5.2 用提取過左公因子的產生式再去匹配 102
3.5.3 對其他產生式都提取左公因子 103
3.5.4 函數聲明和定義兩部分產生式的合并 105
3.6 語法分析結果:語法樹 107
3.7 GCC關于語法分析的源代碼解析 112
3.7.1 GCC語法分析函數調用圖 112
3.7.2 全部語句的語法分析 115
第4章 語法樹到目標代碼 217
4.1 總述語法樹到中間代碼的轉化過程 217
4.2 目標代碼到運行時結構的映射 224
4.3 語法樹轉高端gimple 232
4.3.1 語法樹到高端gimple的總體步驟及運行時 236
4.3.2 高端gimple的實際數據結構 241
4.3.3 語法樹轉高端gimple的GCC源代碼解析 246
4.4 高端gimple到低端gimple 286
4.4.1 高端gimple轉低端gimple概述 286
4.4.2 高端gimple轉化低端gimple的GCC代碼解析 293
4.5 低端gimple到cfg 297
4.5.1 低端gimple到cfg的轉化概述 297
4.5.2 低端gimple轉cfg的實際過程 300
4.6 cfg轉ssa 301
4.7 生成RTL 305
4.7.1 為何要有RTL 305
4.7.2 轉化RTL階段的主要步驟 306
4.7.3 確定初始RTL中的運行時信息 320
4.8 RTL生成目標代碼(匯編) 332
4.8.1 匯編文件介紹 332
4.8.2 創建匯編文件 334
4.8.3 輸出匯編文件總入口 334
4.8.4 全局變量寫入匯編文件 335
4.8.5 函數寫入匯編文件 340
第5章 語句拓展案例的編譯過程 353
5.1 總述各個語句拓展案例的編譯過程 353
5.2 if語句的語法分析 376
5.2.1 多個變量的聲明語句語法分析 376
5.2.2 if語句的語法分析過程 381
5.2.3 if...else if語句的語法分析過程 387
5.3 帶標號語句的語法分析 395
5.4 switch...case、goto、break語句的語法分析過程 399
5.4.1 switch...case 語句 399
5.4.2 goto語句 407
5.4.3 分析break語句 409
5.5 do...while、while、for語句的語法分析過程 420
5.5.1 do...while語句的語法分析 424
5.5.2 while語句的語法分析過程 433
5.5.3 for語句的語法分析過程 444
5.6 各種語句嵌套組合的語法分析過程 472
5.6.1 兩條變量聲明語句分析的結果 477
5.6.2 分析while循環語句 477
5.6.3 進入if進行分析 480
5.6.4 進入else進行分析 485
5.7 所有案例語法樹轉中間結構的過程 516
5.7.1 案例1的語法樹轉高端gimple的總體介紹 516
5.7.2 案例1的語法樹轉高端gimple的代碼分析 528
5.7.3 案例1的高端gimple轉低端gimple 552
5.7.4 案例1的低端gimple到cfg 552
5.7.5 轉化RTL階段的主要步驟 562
5.7.6 案例2的語法樹轉高端gimple 587
5.7.7 案例3的語法樹轉高端gimple 596
第6章 數據拓展案例的編譯過程 612
6.1 數據拓展案例的編譯過程總述 612
6.1.1 基礎類型數據總述 612
6.1.2 用戶自定義類型數據總述 617
6.1.3 指針類型數據總述 626
6.1.4 作用域和生存期總述 640
6.1.5 表達式總述 645
6.2 基礎類型數據的語法分析過程 652
6.2.1 非浮點型數據的語法分析 653
6.2.2 浮點型數據的語法分析 662
6.3 復合類型數據的語法分析過程 670
6.3.1 數組的語法分析 670
6.3.2 枚舉類型數據的語法分析 675
6.3.3 struct類型數據的語法分析 678
6.3.4 union類型數據的語法分析 683
6.3.5 自定義數據聲明和使用的語法分析 684
6.4 指針類型數據的語法分析過程 693
6.4.1 對swap_point函數中指針的語法分析 693
6.4.2 對指針使用的語法分析 696
6.5 關于作用域和生存期的語法分析過程 705
6.5.1 C語言作用域和生存期概述 705
6.5.2 全局變量data語法分析中作用域相關處理過程 706
6.5.3 fun函數定義的語法分析中作用域相關處理 709
6.5.4 main函數定義中局部變量聲明data作用域處理過程 716
6.5.5 main函數內部語句塊中變量nCount作用域處理過程 719
6.5.6 main函數中引用變量data時選擇相應聲明節點的過程分析 719
6.5.7 main函數中引用變量nCount時選擇相應聲明節點的過程分析 720
6.5.8 main函數中退出內部語句塊時更新變量作用域過程分析 721
6.5.9 fun函數中靜態變量temp生存期信息的語法分析 726
6.6 表達式的語法分析過程 728
6.6.1 if條件中的表達式語法分析 728
6.6.2 if條件下面“語句”部分的表達式語法分析 740
6.7 所有案例語法樹轉中間結構(RTL)的過程 754
6.7.1 基礎類型數據語法樹轉高端gimple的過程 754
6.7.2 用戶自定義數據語法樹轉高端gimple的過程 794
6.7.3 指針類型數據語法樹轉高端gimple的過程 838
6.7.4 作用域和生存期案例語法樹轉高端gimple的過程 878
6.7.5 復雜表達式案例的語法樹轉高端gimple的過程 887
第7章 匯編與鏈接 934
7.1 匯編器 934
7.1.1 詳細介紹匯編指令到機器指令的轉化 934
7.1.2 .o文件格式總體情況介紹 953
7.1.3 代碼段、數據段以及其他各個表項間的關系 962
7.1.4 從匯編文件到目標文件的實現 967
7.1.5 匯編器處理的源代碼分析 973
7.2 鏈接器 985
7.2.1 .o文件鏈接總體介紹 985
7.2.2 多個.o文件鏈接時通過符號表建立關系 989
7.2.3 鏈接時統一計算地址并回填 997
7.2.4 鏈接器源代碼介紹 999
7.2.5 庫函數的鏈接 1002
7.2.6 動態鏈接 1002
第8章 預處理 1012
8.1 文件包含 1012
8.2 宏定義 1017
8.3 條件編譯 1019
8.4 帶參數的宏定義 1022
附錄 RTX定義 1031
作者的話 1039