| ISBN | 出版时间 | 包装 | 开本 | 页数 | 字数 |
|---|---|---|---|---|---|
| 未知 | 暂无 | 暂无 | 未知 | 0 | 暂无 |
出版者的话
专家指导委员会
译者序
前言
第1章
编译简介
1
1.1
编译器
1
1.1.1
编译的分析-综合模型
1
1.1.2
编译器的前驱与后继
3
1.2
源程序分析
3
1.2.1
词法分析
3
1.2.2
语法分析
3
1.2.3
语义分析
5
1.2.4
文本格式器中的分析
5
1.3
编译器的各阶段
6
1.3.1
符号表管理
7
1.3.2
错误检测与报告
7
1.3.3
各分析阶段
7
1.3.4
中间代码生成
9
1.3.5
代码优化
9
1.3.6
代码生成
10
1.4
编译器的伙伴
10
1.4.1
预处理器
10
1.4.2
汇编器
11
1.4.3
两遍汇编
12
1.4.4
装配器和连接编辑器
12
1.5
编译器各阶段的分组
13
1.5.1
前端与后端
13
1.5.2
编译器的遍
13
1.5.3
减少编译的遍数
14
1.6
编译器的构造工具
14
参考文献注释
15
第2章
简单的一遍编译器
17
2.1
概述
17
2.2
语法定义
17
2.2.1
分析树
19
2.2.2
二义性
20
2.2.3
操作符的结合规则
20
2.2.4
操作符的优先级
21
2.3
语法制导翻译
22
2.3.1
后缀表示
22
2.3.2
语法制导定义
22
2.3.3
综合属性
23
2.3.4
深度优先遍历
24
2.3.5
翻译模式
25
2.3.6
翻译的输出
25
2.4
语法分析
26
2.4.1
自顶向下语法分析
27
2.4.2
预测分析法
29
2.4.3
何时使用产生式
30
2.4.4
设计一个预测语法分析器
30
2.4.5
左递归
31
2.5
简单表达式的翻译器
32
2.5.1
抽象语法和具体语法
32
2.5.2
调整翻译模式
33
2.5.3
非终结符expr.
term
和rest
的过程
33
2.5.4
翻译器的优化
35
2.5.5
完整程序
35
2.6
词法分析
37
2.6.1
剔除空白符和注释
37
2.6.2
常数
37
2.6.3
识别标识符和关键字
37
2.6.4
词法分析器的接口
38
2.6.5
词法分析器
38
2.7
符号表
40
2.7.1
符号表接口
40
2.7.2
处理保留的关键字
41
2.7.3
符号表的实现方法
41
2.8
抽象堆栈机
42
2.8.1
算术指令
42
2.8.2
左值和右值
43
2.8.3
堆栈操作
43
2.8.4
表达式的翻译
43
2.8.5
控制流
44
2.8.6
语句的翻译
44
2.8.7
输出一个翻译
45
2.9
技术的综合
46
2.9.1
翻译器的描述
46
2.9.2
词法分析器模块lexer.c
47
2.9.3
语法分析器模块parser.c
48
2.9.4
输出模块emitter.c
48
2.9.5
符号表模块symbol.c和init.c
48
2.9.6
错误处理模块error.c
48
2.9.7
编译器的建立
48
2.9.8
程序清单
49
练习
53
编程练习
54
参考文献注释
55
第3章
词法分析
57
3.1
词法分析器的作用
57
3.1.1
词法分析中的问题
58
3.1.2
记号.
模式.
词素
58
3.1.3
记号的属性
59
3.1.4
词法错误
60
3.2
输入缓冲
60
3.2.1
双缓冲区
61
3.2.2
标志
62
3.3
记号的描述
62
3.3.1
串和语言
62
3.3.2
语言上的运算
63
3.3.3
正规表达式
64
3.3.4
正规定义
65
3.3.5
缩写表示法
66
3.3.6
非正规集
66
3.4
记号的识别
67
3.4.1
状态转换图
68
3.4.2
状态转换图的实现
70
3.5
词法分析器描述语言
72
3.5.1
Lex说明
72
3.5.2
超前扫描操作
75
3.6
有穷自动机
76
3.6.1
不确定的有穷自动机
77
3.6.2
确定的有穷自动机
78
3.6.3
从NFA到DFA的变换
79
3.7
从正规表达式到NFA
81
3.7.1
从正规表达式构造NFA
81
3.7.2
NFA的双堆栈模拟
84
3.7.3
时间空间的权衡
85
3.8
设计词法分析器的生成器
85
3.8.1
基于NFA的模式匹配
86
3.8.2
词法分析器的DFA
88
3.8.3
实现超前扫描操作
88
3.9
基于DFA的模式匹配器的优化
89
3.9.1
NFA的重要状态
89
3.9.2
从正规表达式到DFA
89
3.9.3
最小化DFA的状态数
93
3.9.4
词法分析器的状态最小化
95
3.9.5
表压缩方法
95
练习
97
编程练习
103
参考文献注释
103
第4章
语法分析
105
4.1
语法分析器的作用
105
4.1.1
语法错误的处理
106
4.1.2
错误恢复策略
108
4.2
上下文无关文法
109
4.2.1
符号的使用约定
110
4.2.2
推导
110
4.2.3
分析树和推导
112
4.2.4
二义性
113
4.3
文法的编写
113
4.3.1
正规表达式和上下文无关文法的
比较
114
4.3.2
验证文法所产生的语言
114
4.3.3
消除二义性
115
4.3.4
消除左递归
116
4.3.5
提取左因子
117
4.3.6
非上下文无关语言的结构
118
4.4
自顶向下语法分析
120
4.4.1
递归下降语法分析法
120
4.4.2
预测语法分析器
121
4.4.3
预测语法分析器的状态转换图
121
4.4.4
非递归的预测分析
123
4.4.5
FIRST和FOLLOW
124
4.4.6
预测分析表的构造
125
4.4.7
LL(1)文法
126
4.4.8
预测分析的错误恢复
127
4.5
自底向上语法分析
128
4.5.1
句柄
129
4.5.2
句柄裁剪
130
4.5.3
用栈实现移动归约分析
131
4.5.4
活前缀
133
4.5.5
移动归约分析过程中的冲突
133
4.6
算符优先分析法
134
4.6.1
使用算符优先关系
135
4.6.2
从结合律和优先级获得算符优先
关系
136
4.6.3
处理一元操作符
137
4.6.4
优先函数
137
4.6.5
算符优先分析中的错误恢复
139
4.7
LR语法分析器
142
4.7.1
LR语法分析算法
142
4.7.2
LR文法
145
4.7.3
构造SLR语法分析表
146
4.7.4
构造规范LR语法分析表
151
4.7.5
构造LALR语法分析表
155
4.7.6
LALR语法分析表的有效构造
方法
158
4.7.7
LR语法分析表的压缩
161
4.8
二义文法的应用
163
4.8.1
使用优先级和结合规则来解决分析
动作的冲突
163
4.8.2
悬空else的二义性
164
4.8.3
特例产生式引起的二义性
165
4.8.4
LR语法分析中的错误恢复
167
4.9
语法分析器的生成器
168
4.9.1
语法分析器的生成器Yacc
169
4.9.2
用Yacc处理二义文法
171
4.9.3
用Lex建立Yacc的词法分析器
173
4.9.4
Yacc的错误恢复
174
练习
174
参考文献注释
182
第5章
语法制导翻译
185
5.1
语法制导定义
185
5.1.1
语法制导定义的形式
186
5.1.2
综合属性
186
5.1.3
继承属性
187
5.1.4
依赖图
187
5.1.5
计算顺序
189
5.2
语法树的构造
189
5.2.1
语法树
190
5.2.2
构造表达式的语法树
190
5.2.3
构造语法树的语法制导定义
191
5.2.4
表达式的无环有向图
192
5.3
自底向上计算S属性定义
194
5.4
L属性定义
195
5.4.1
L属性定义
196
5.4.2
翻译模式
196
5.5
自顶向下翻译
198
5.5.1
从翻译模式中消除左递归
198
5.5.2
预测翻译器的设计
201
5.6
自底向上计算继承属性
202
5.6.1
删除嵌入在翻译模式中的动作
202
5.6.2
分析栈中的继承属性
203
5.6.3
模拟继承属性的计算
204
5.6.4
用综合属性代替继承属性
206
5.6.5
一个难计算的语法制导定义
207
5.7
递归计算
207
5.7.1
从左到右遍历
207
5.7.2
其他遍历方法
208
5.8
编译时属性值的空间分配
209
5.8.1
在编译时为属性分配空间
209
5.8.2
避免复制
211
5.9
编译器构造时的空间分配
211
5.9.1
从文法中预知生存期
212
5.9.2
不相重叠的生存期
214
5.10
语法制导定义的分析
215
5.10.1
属性的递归计算
216
5.10.2
强无环的语法制导定义
216
5.10.3
环形检测
217
练习
219
参考文献注释
221
第6章
类型检查
223
6.1
类型系统
224
6.1.1
类型表达式
224
6.1.2
类型系统
225
6.1.3
静态和动态类型检查
226
6.1.4
错误恢复
226
6.2
一个简单的类型检查器的说明
226
6.2.1
一种简单语言
226
6.2.2
表达式的类型检查
227
6.2.3
语句的类型检查
228
6.2.4
函数的类型检查
228
6.3
类型表达式的等价
229
6.3.1
类型表达式的结构等价
229
6.3.2
类型表达式的名字
231
6.3.3
类型表示中的环
232
6.4
类型转换
233
6.5
函数和运算符的重载
234
6.5.1
子表达式的可能类型的集合
235
6.5.2
缩小可能类型的集合
236
6.6
多态函数
237
6.6.1
为什么要使用多态函数
237
6.6.2
类型变量
238
6.6.3
包含多态函数的语言
239
6.6.4
代换.
实例和合一
240
6.6.5
多态函数的检查
241
6.7
合一算法
244
练习
247
参考文献注释
251
第7章
运行时环境
253
7.1
源语言问题
253
7.1.1
过程
253
7.1.2
活动树
253
7.1.3
控制栈
255
7.1.4
声明的作用域
256
7.1.5
名字的绑定
256
7.1.6
一些问题
257
7.2
存储组织
257
7.2.1
运行时内存的划分
257
7.2.2
活动记录
258
7.2.3
编译时的局部数据布局
259
7.3
存储分配策略
260
7.3.1
静态存储分配
260
7.3.2
栈式存储分配
262
7.3.3
悬空引用
265
7.3.4
堆式存储分配
265
7.4
对非局部名字的访问
266
7.4.1
程序块
267
7.4.2
无嵌套过程的词法作用域
268
7.4.3
包含嵌套过程的词法作用域
269
7.4.4
动态作用域
274
7.5
参数传递
275
7.5.1
传值调用
275
7.5.2
引用调用
276
7.5.3
复制-恢复
277
7.5.4
传名调用
277
7.6
符号表
278
7.6.1
符号表表项
278
7.6.2
名字中的字符
279
7.6.3
存储分配信息
280
7.6.4
符号表的线性表数据结构
280
7.6.5
散列表
281
7.6.6
表示作用域的信息
283
7.7
支持动态存储分配的语言措施
285
7.7.1
垃圾单元
285
7.7.2
悬空引用
286
7.8
动态存储分配技术
287
7.8.1
固定块的显式分配
287
7.8.2
变长块的显式分配
287
7.8.3
隐式存储释放
288
7.9
Fortran语言的存储分配
288
7.9.1
COMMON区域中的数据
289
7.9.2
一个简单的等价算法
290
7.9.3
Fortran语言的等价算法
292
7.9.4
映射数据区
294
练习
294
参考文献注释
298
第8章
中间代码生成
299
8.1
中间语言
299
8.1.1
图表示
299
8.1.2
三地址码
300
8.1.3
三地址语句的类型
301
8.1.4
语法制导翻译生成三地址码
302
8.1.5
三地址语句的实现
303
8.1.6
表示方法比较:间址的使用
305
8.2
声明语句
305
8.2.1
过程中的声明语句
305
8.2.2
跟踪作用域信息
306
8.2.3
记录中的域名
308
8.3
赋值语句
309
8.3.1
符号表中的名字
309
8.3.2
临时名字的重用
310
8.3.3
寻址数组元素
311
8.3.4
数组元素寻址的翻译模式
312
8.3.5
赋值语句中的类型转换
314
8.3.6
记录域的访问
315
8.4
布尔表达式
315
8.4.1
翻译布尔表达式的方法
316
8.4.2
数值表示
316
8.4.3
短路代码
317
8.4.4
控制流语句
317
8.4.5
布尔表达式的控制流翻译
319
8.4.6
混合模式的布尔表达式
321
8.5
case语句
321
8.6
回填
323
8.6.1
布尔表达式
323
8.6.2
控制流语句
326
8.6.3
翻译的实现方案
326
8.6.4
标号和goto
327
8.7
过程调用
328
8.7.1
调用序列
328
8.7.2
一个简单的例子
328
练习
329
参考文献注释
331
第9章
代码生成
333
9.1
代码生成器设计中的问题
333
9.1.1
代码生成器的输入
333
9.1.2
目标程序
334
9.1.3
存储管理
334
9.1.4
指令选择
334
9.1.5
寄存器分配
335
9.1.6
计算次序的选择
336
9.1.7
代码生成方法
336
9.2
目标机器
336
9.3
运行时存储管理
338
9.3.1
静态分配
339
9.3.2
栈式分配
340
9.3.3
名字的运行地址
342
9.4
基本块和流图
343
9.4.1
基本块
343
9.4.2
基本块的变换
344
9.4.3
保结构变换
344
9.4.4
代数变换
345
9.4.5
流图
345
9.4.6
基本块的表示
345
9.4.7
循环
346
9.5
下次引用信息
346
9.5.1
计算下次引用信息
346
9.5.2
临时名字的存储分配
347
9.6
一个简单的代码生成器
347
9.6.1
寄存器描述符和地址描述符
348
9.6.2
代码生成算法
348
9.6.3
函数getreg
349
9.6.4
为其他类型的语句生成代码
350
9.6.5
条件语句
351
9.7
寄存器分配与指派
351
9.7.1
全局寄存器分配
352
9.7.2
引用计数
352
9.7.3
外层循环的寄存器指派
353
9.7.4
图染色法寄存器分配
354
9.8
基本块的dag表示法
354
9.8.1
dag的构造
355
9.8.2
dag的应用
357
9.8.3
数组.
指针和过程调用
358
9.9
窥孔优化
359
9.9.1
冗余加载与保存
360
9.9.2
不可达代码
360
9.9.3
控制流优化
361
9.9.4
代数化简
361
9.9.5
强度削弱
361
9.9.6
机器语言的使用
362
9.10
从dag生成代码
362
9.10.1
重排序
362
9.10.2
对dag的启发式排序
362
9.10.3
树的最优排序
363
9.10.4
标记算法
364
9.10.5
从标记树中产生代码
364
9.10.6
多寄存器操作
367
9.10.7
代数性质
367
9.10.8
公共子表达式
368
9.11
动态规划代码生成算法
368
9.11.1
一种寄存器计算机
368
9.11.2
动态规划的原理
369
9.11.3
邻近计算
369
9.11.4
动态规划算法
369
9.12
代码生成器的生成器
371
9.12.1
采用重写树技术的代码生成
371
9.12.2
借助语法分析的模式匹配
375
9.12.3
用于语义检查的例程
376
练习
376
参考文献注释
378
第10章
代码优化
381
10.1
引言
381
10.1.1
代码改进变换的准则
381
10.1.2
性能的提高
382
10.1.3
优化编译器的组织
383
10.2
优化的主要种类
384
10.2.1
保持功能变换
385
10.2.2
公共子表达式
386
10.2.3
复制传播
387
10.2.4
无用代码删除
387
10.2.5
循环优化
388
10.2.6
代码外提
388
10.2.7
归纳变量和强度削弱
388
10.3
基本块的优化
390
10.4
流图中的循环
392
10.4.1
支配节点
392
10.4.2
自然循环
393
10.4.3
内循环
393
10.4.4
前置首节点
394
10.4.5
可约流图
394
10.5
全局数据流分析介绍
395
10.5.1
点和路径
396
10.5.2
到达定义
396
10.5.3
结构化程序的数据流分析
397
10.5.4
对数据流信息的保守估计
399
10.5.5
in
和
out
的计算
400
10.5.6
处理循环
401
10.5.7
集合的表示
402
10.5.8
局部到达定义
403
10.5.9
引用-定义链
404
10.5.10
计算顺序
404
10.5.11
一般控制流
404
10.6
数据流方程的迭代解
405
10.6.1
到达定义的迭代算法
406
10.6.2
可用表达式
408
10.6.3
活跃变量分析
410
10.6.4
定义-引用链
411
10.7
代码改进变换
412
10.7.1
全局公共子表达式删除
412
10.7.2
复制传播
413
10.7.3
循环不变计算的检测
415
10.7.4
代码外提
415
10.7.5
可选的代码外提方案
417
10.7.6
代码外提后对数据流信息的
维护
418
10.7.7
归纳变量删除
418
10.7.8
带有循环不变表达式的归纳
变量
421
10.8
处理别名
422
10.8.1
一种简单的指针语言
422
10.8.2
指针赋值的作用
422
10.8.3
利用指针信息
424
10.8.4
过程间的数据流分析
425
10.8.5
带有过程调用的代码模型
425
10.8.6
别名的计算
426
10.8.7
存在过程调用时的数据流分析
427
10.8.8
change信息的用途
428
10.9
结构化流图的数据流分析
429
10.9.1
深度优先搜索
429
10.9.2
流图的深度优先表示中的边
431
10.9.3
流图的深度
431
10.9.4
区间
432
10.9.5
区间划分
432
10.9.6
区间图
433
10.9.7
节点分裂
433
10.9.8
T1-T2
分析
434
10.9.9
区域
434
10.9.10
寻找支配节点
435
10.10
高效数据流算法
436
10.10.1
迭代算法中的深度优先顺序
436
10.10.2
基于结构的数据流分析
437
10.10.3
对基于结构的算法的一些速度上
的改进
440
10.10.4
处理不可约流图
441
10.11
一个数据流分析工具
441
10.11.1
数据流分析框架
442
10.11.2
数据流分析框架的公理
443
10.11.3
单调性和分配性
444
10.11.4
数据流问题的聚合路径解
447
10.11.5
流问题的保守解
447
10.11.6
通用框架的迭代算法
448
10.11.7
一个数据流分析工具
448
10.11.8
算法10.18的性质
449
10.11.9
算法10.18的收敛性
449
10.11.10
初始化的修正
450
10.12
类型估计
450
10.12.1
处理无穷类型集
451
10.12.2
一个简单的类型系统
452
10.12.3
前向方案
452
10.12.4
后向方案
453
10.13
优化代码的符号调试
455
10.13.1
基本块中变量值的推断
456
10.13.2
全局优化的影响
459
10.13.3
归纳变量删除
459
10.13.4
全局公共子表达式删除
459
10.13.5
代码外提
459
练习
460
参考文献注释
465
第11章
编写一个编译器
469
11.1
编译器设计
469
11.1.1
源语言问题
469
11.1.2
目标语言问题
469
11.1.3
性能标准
469
11.2
编译器开发方法
470
11.3
编译器开发环境
472
11.4
测试与维护
474
第12章
编译器实例
475
12.1
数学排版预处理器EQN
475
12.2
Pascal编译器
475
12.3
C编译器
476
12.4
Fortran
H编译器
477
12.4.1
Fortran
H中的代码优化
478
12.4.2
代数优化
478
12.4.3
寄存器优化
478
12.5
BLISS/11编译器
479
12.6
Modula-2优化编译器
480
附录
一个程序设计项目
483
参考文献
489
索引