産品特色
編輯推薦
貫穿編譯、匯編、鏈接、加載的全過程!
比“龍書”更具實踐性!
1.實戰
通過實際動手製作一個精簡版C語言編譯器,讓讀者深入瞭解C語言程序編譯、運行背後的細節。
2.全麵
不僅限於編譯器,對以編譯器為中心的編程語言的運行環境,即編譯器、匯編器、鏈接器、硬件以及運行時環境等,均有所涉及。
3.傑齣
日本知名技術書作傢青木峰郎耗時3年精心打造,通過具體的例子講解概念,通俗易懂,更適閤入門。
內容簡介
本書將帶領讀者從頭開始製作一門語言的編譯器。筆者特意為本書設計瞭C?語言,C?可以說是C語言的子集,實現瞭包括指針運算等在內的C語言的主要部分。本書所實現的編譯器就是C?語言的編譯器, 是實實在在的編譯器,而非有諸多限製的玩具。另外,除編譯器之外,本書對以編譯器為中心的編程語言的運行環境,即編譯器、匯編器、鏈接器、硬件、運行時環境等都有所提及,介紹瞭程序運行的所有環節。
作者簡介
青木峰郎(作者)
程序員,著有《Ruby程序設計268技(第2版)》《Ruby源代碼完全解說》《Linux程序設計》等多部編程相關著作,並積極參與標準庫維護、文檔維護等各種各樣的活動。
嚴聖逸(譯者)
畢業於上海交通大學。8年軟件開發經驗,期間赴日本工作。現就職於想能信息科技(上海)有限公司,從事基於雲平颱的客戶關係管理及各類營銷自動化係統的開發工作。譯有《高效團隊開發:工具與方法》。
絕雲(譯者)
畢業於清華大學軟件學院。曾在日本創意公司KAYAC從事即時通信軟件及社交遊戲的開發工作,現任螞蟻金服前端架構專傢。譯有《寫給大傢看的算法書》等圖書,曾參與《像外行一樣思考,像專傢一樣實踐(修訂版)》的審校。
目錄
第1章
開始製作編譯器 1
1.1 本書的概要 2
本書的主題 2
本書製作的編譯器 2
編譯示例 2
可執行文件 3
編譯 4
程序運行環境 6
1.2 編譯過程 8
編譯的4個階段 8
語法分析 8
語義分析 9
生成中間代碼 9
代碼生成 10
優化 10
總結 10
1.3 使用C?編譯器進行編譯 11
C?編譯器的必要環境 11
安裝C?編譯器 11
C?的Hello, World! 12
第2章
C?和cbc 13
2.1 C?語言的概要 14
C?的Hello, World! 14
C?中刪減的功能 14
import關鍵字 15
導入文件的規範 16
2.2 C?編譯器cbc的構成 17
cbc的代碼樹 17
cbc的包 18
compiler包中的類群 18
main函數的實現 19
commandMain函數的實現 19
Java5泛型 20
build函數的實現 20
Java 5的foreach語句 21
compile函數的實現 21
第1部分 代碼分析
第3章
語法分析的概要 24
3.1 語法分析的方法 25
代碼分析中的問題點 25
代碼分析的一般規律 25
詞法分析、語法分析、語義分析 25
掃描器的動作 26
單詞的種類和語義值 27
token 28
抽象語法樹和節點 29
3.2 解析器生成器 30
什麼是解析器生成器 30
解析器生成器的種類 30
解析器生成器的選擇 31
3.3 JavaCC的概要 33
什麼是JavaCC 33
語法描述文件 33
語法描述文件的例子 34
運行JavaCC 35
啓動JavaCC所生成的解析器 36
中文的處理 37
第4章
詞法分析 39
4.1 基於JavaCC的掃描器的描述 40
本章的目的 40
JavaCC的正則錶達式 40
固定字符串 41
連接 41
字符組 41
排除型字符組 41
重復1次或多次 42
重復0次或多次 42
重復n次到m次 42
正好重復n次 43
可以省略 43
選擇 43
4.2 掃描沒有結構的單詞 44
TOKEN命令 44
掃描標識符和保留字 44
選擇匹配規則 45
掃描數值 46
4.3 掃描不生成token的單詞 48
SKIP命令和SPECIAL_TOKEN命令 48
跳過空白符 48
跳過行注釋 49
4.4 掃描具有結構的單詞 50
最長匹配原則和它的問題 50
基於狀態遷移的掃描 50
MORE命令 51
跳過塊注釋 52
掃描字符串字麵量 53
掃描字符字麵量 53
第5章
基於JavaCC的解析器的描述 55
5.1 基於EBNF語法的描述 56
本章的目的 56
基於JavaCC的語法描述 56
終端符和非終端符 57
JavaCC的EBNF錶示法 58
連接 58
重復0次或多次 59
重復1次或多次 59
選擇 60
可以省略 60
5.2 語法的二義性和token的超前掃描 61
語法的二義性 61
JavaCC的局限性 62
提取左側共通部分 63
token的超前掃描 63
可以省略的規則和衝突 64
重復和衝突 65
更靈活的超前掃描 66
超前掃描的相關注意事項 66
第6章
語法分析 68
6.1 定義的分析 69
錶示程序整體的符號 69
語法的單位 69
import聲明的語法 70
各類定義的語法 71
變量定義的語法 72
函數定義的語法 73
結構體定義和聯閤體定義的語法 74
結構體成員和聯閤體成員的語法 75
typedef語句的語法 76
類型的語法 76
C語言和C?在變量定義上的區彆 77
基本類型的語法 77
6.2 語句的分析 79
語句的語法 79
if語句的語法 80
省略if語句和大括號 80
while語句的語法 81
for語句的語法 81
各類跳轉語句的語法 82
6.3 錶達式的分析 83
錶達式的整體結構 83
expr的規則 83
條件錶達式 84
二元運算符 85
6.4 項的分析 88
項的規則 88
前置運算符的規則 88
後置運算符的規則 89
字麵量的規則 89
第2部分 抽象語法樹和中間代碼
第7章
JavaCC的action和抽象語法樹 92
7.1 JavaCC的action 93
本章的目的 93
簡單的action 93
執行action的時間點 93
返迴語義值的action 95
獲取終端符號的語義值 95
Token類的屬性 96
獲取非終端符號的語義值 98
語法樹的結構 99
選擇和action 99
重復和action 100
本節總結 102
7.2 抽象語法樹和節點 103
Node類群 103
Node類的定義 105
抽象語法樹的錶示 105
基於節點錶示錶達式的例子 107
第8章
抽象語法樹的生成 110
8.1 錶達式的抽象語法樹 111
字麵量的抽象語法樹 111
類型的錶示 112
為什麼需要TypeRef類 113
一元運算的抽象語法樹 114
二元運算的抽象語法樹 116
條件錶達式的抽象語法樹 117
賦值錶達式的抽象語法樹 118
8.2 語句的抽象語法樹 121
if語句的抽象語法樹 121
while語句的抽象語法樹 122
程序塊的抽象語法樹 123
8.3 聲明的抽象語法樹 125
變量聲明列錶的抽象語法樹 125
函數定義的抽象語法樹 126
錶示聲明列錶的抽象語法樹 127
錶示程序整體的抽象語法樹 128
外部符號的import 128
總結 129
8.4 cbc 的解析器的啓動 132
Parser對象的生成 132
文件的解析 133
解析器的啓動 134
第9章
語義分析(1)引用的消解 135
9.1 語義分析的概要 136
本章目的 136
抽象語法樹的遍曆 137
不使用Visitor模式的抽象語法樹的處理 137
基於Visitor模式的抽象語法樹的處理 138
Vistor模式的一般化 140
cbc中Visitor模式的實現 141
語義分析相關的cbc的類 142
9.2 變量引用的消解 144
問題概要 144
實現的概要 144
Scope樹的結構 145
LocalResolver類的屬性 146
LocalResolver類的啓動 146
變量定義的添加 147
函數定義的處理 148
pushScope方法 149
currentScope方法 149
popScope方法 150
添加臨時作用域 150
建立VariableNode和變量定義的關聯 151
從作用域樹取得變量定義 151
9.3 類型名稱的消解 153
問題概要 153
實現的概要 153
TypeResolver類的屬性 153
TypeResolver類的啓動 154
類型的聲明 154
類型和抽象語法樹的遍曆 155
變量定義的類型消解 156
函數定義的類型消解 157
第10章
語義分析(2)靜態類型檢查 159
10.1 類型定義的檢查 160
問題概要 160
實現的概要 161
檢測有嚮圖中的閉環的算法 162
結構體、聯閤體的循環定義檢查 163
10.2 錶達式的有效性檢查 165
問題概要 165
實現的概要 165
DereferenceChecker類的啓動 166
SemanticError異常的捕獲 167
非指針類型取值操作的檢查 167
獲取非左值錶達式地址的檢查 168
隱式的指針生成 169
10.3 靜態類型檢查 170
問題概要 170
實現的概要 170
C?中操作數的類型 171
隱式類型轉換 172
TyperChecker類的啓動 173
二元運算符的類型檢查 174
隱式類型轉換的實現 175
第11章
中間代碼的轉換 178
11.1 cbc的中間代碼 179
組成中間代碼的類 180
中間代碼節點類的屬性 181
中間代碼的運算符和類型 182
各類中間代碼 183
中間代碼的意義 184
11.2 IRGenerator類的概要 185
抽象語法樹的遍曆和返迴值 185
IRGenerator類的啓動 185
函數本體的轉換 186
作為語句的錶達式的判彆 187
11.3 流程控製語句的轉換 189
if語句的轉換(1)概要 189
if語句的轉換(2)沒有else部分的情況 190
if語句的轉換(3)存在else部分的情況 191
while語句的轉換 191
break語句的轉換(1)問題的定義 192
break語句的轉換(2)實現的方針 193
break語句的轉換(3)實現 194
11.4 沒有副作用的錶達式的轉換 196
UnaryOpNode對象的轉換 196
BinaryOpNode對象的轉換 197
指針加減運算的轉換 198
11.5 左值的轉換 200
左邊和右邊 200
左值和右值 200
cbc中左值的錶現 201
結構體成員的偏移 202
成員引用(expr.memb)的轉換 203
左值轉換的例外:數組和函數 204
成員引用的錶達式(ptr->memb)的轉換 205
11.6 存在副作用的錶達式的轉換 206
錶達式的副作用 206
有副作用的錶達式的轉換方針 206
簡單賦值錶達式的轉換(1)語句 207
臨時變量的引入 208
簡單賦值錶達式的轉換(2)錶達式 209
後置自增的轉換 210
第3部分 匯編代碼
第12章
x86架構的概要 214
12.1 計算機的係統結構 215
CPU和存儲器 215
寄存器 215
地址 216
物理地址和虛擬地址 216
各類設備 217
緩存 218
12.2 x86係列CPU的曆史 220
x86係列CPU 220
32位CPU 220
指令集 221
IA-32的變遷 222
IA-32的64位擴展——AMD64 222
12.3 IA-32的概要 224
IA-32的寄存器 224
通用寄存器 225
機器棧 226
機器棧的操作 227
機器棧的用途 227
棧幀 228
指令指針 229
標誌寄存器 229
12.4 數據的錶現形式和格式 231
無符號整數的錶現形式 231
有符號整數的錶現形式 231
負整數的錶現形式和二進製補碼 232
字節序 233
對齊 233
結構體的錶現形式 234
第13章
x86匯編器編程 236
13.1 基於GNU匯編器的編程 237
GNU匯編器 237
匯編語言的Hello, World! 237
基於GNU匯編器的匯編代碼 238
13.2 GNU匯編器的語法 240
匯編版的Hello, World! 240
指令 241
匯編僞操作 241
標簽 241
注釋 242
助記符後綴 242
各種各樣的操作數 243
間接內存引用 244
x86指令集的概要 245
13.3 傳輸指令 246
mov指令 246
push指令和pop指令 247
lea指令 248
movsx指令和movzx指令 249
符號擴展和零擴展 250
13.4 算術運算指令 251
add指令 251
進位標誌 252
sub指令 252
imul指令 252
idiv指令和div指令 253
inc指令 254
dec指令 255
neg指令 255
13.5 位運算指令 256
and指令 256
or指令 257
xor指令 257
not指令 257
sal指令 258
sar指令 258
shr指令 259
13.6 流程的控製 260
jmp指令 260
條件跳轉指令(jz、jnz、je、jne、……) 261
cmp指令 262
test指令 263
標誌位獲取指令(SETcc) 263
call指令 264
ret指令 265
第14章
函數和變量 266
14.1 程序調用約定 267
什麼是程序調用約定 267
Linux/x86下的程序調用約定 267
14.2 Linux/x86下的函數調用 269
到函數調用完成為止 269
到函數開始執行為止 270
到返迴原處理流程為止 271
到清理操作完成為止 271
函數調用總結 272
14.3 Linux/x86下函數調用的細節 274
寄存器的保存和復原 274
caller-save寄存器和callee-save寄存器 274
caller-save寄存器和callee-save寄存器的靈活應用 275
大數值和浮點數的返迴方法 276
其他平颱的程序調用約定 277
第15章
編譯錶達式和語句 278
15.1 確認編譯結果 279
利用cbc進行確認的方法 279
利用gcc進行確認的方法 280
15.2 x86匯編的對象與DSL 282
錶示匯編的類 282
錶示匯編對象 283
15.3 cbc的x86匯編DSL 285
利用DSL生成匯編對象 285
錶示寄存器 286
錶示立即數和內存引用 287
錶示指令 287
錶示匯編僞操作、標簽和注釋 288
15.4 CodeGenerator類的概要 290
CodeGenerator類的字段 290
CodeGenerator類的處理概述 290
實現compileStmts方法 291
cbc的編譯策略 292
15.5 編譯單純的錶達式 294
編譯Int節點 294
編譯Str節點 294
編譯Uni節點(1)按位取反 295
編譯Uni節點(2)邏輯非 297
15.6 編譯二元運算 298
編譯Bin節點 298
實現compileBinaryOp方法 299
實現除法和餘數 300
實現比較運算 300
15.7 引用變量和賦值 301
編譯Var節點 301
編譯Addr節點 302
編譯Mem節點 303
編譯Assign節點 303
15.8 編譯jump語句 305
編譯LabelStmt節點 305
編譯Jump節點 305
編譯CJump節點 305
編譯Call節點 306
編譯Return節點 307
第16章
分配棧幀 308
16.1 操作棧 309
cbc中的棧幀 309
棧指針操作原則 310
函數體編譯順序 310
16.2 參數和局部變量的內存分配 312
本節概述 312
參數的內存分配 312
局部變量的
自製編譯器 下載 mobi epub pdf txt 電子書