本书全面地介绍了现代编译技术,结构上分为通用编译技术和高级编译技术两大部分。第一部分介绍通用的编译程序实现技术,包括词法和语法分析、上下文处理、代码生成以及存储器管理的一般方法。第二部分介绍特定范型语言的高级编译技术,包括命令式语言、面向对象语言、逻辑式语言、函数式语言及并行 / 分布式语言的上下文处理和代码生成等内容。本书注重编译程序的具体实现和优化技术,实例丰富,具有很强的可读性和实用性。\r\n\r\n 本书可作为高校计算机专业本科和研究生编译程序设计课程的教科书,也可供从事计算机软件开发的人员参 \r\n
\r\n
第1章 导论 1 \r\n\r\n 1.1 为什么学习编译程序构造 4 \r\n\r\n 1.1.1 编译程序构造是非常成功的 4 \r\n\r\n 1.1.2 编译程序构造的广泛应用 6 \r\n\r\n 1.1.3 编译程序包含普遍适用的算法 6 \r\n\r\n 1.2 一个简单的传统的模块化编译程序/解释程序 6 \r\n\r\n 1.2.1 抽象语法树 7 \r\n\r\n 1.2.2 范例编译程序的结构 8 \r\n\r\n 1.2.3 范例编译程序的语言 9 \r\n\r\n 1.2.4 范例编译程序的词法分析 10 \r\n\r\n 1.2.5 范例编译程序的语法分析 11 \r\n\r\n 1.2.6 范例编译程序的上下文处理 14 \r\n\r\n 1.2.7 范例编译程序的代码生成 14 \r\n\r\n 1.2.8 范例编译程序的解释程序 15 \r\n\r\n 1.3 一个更接近于实际的编译程序的结构 16 \r\n\r\n 1.3.1 结构 17 \r\n\r\n 1.3.2 运行时系统 18 \r\n\r\n 1.3.3 捷径 18 \r\n\r\n 1.4 编译程序体系结构 18 \r\n\r\n 1.4.1 编译程序的宽度 19 \r\n\r\n 1.4.2 谁主控 20 \r\n\r\n 1.5 一个优秀编译程序的特性 22 \r\n\r\n 1.6 可移植性和可重定目标性 23 \r\n\r\n 1.7 优化的位置和效用 23 \r\n\r\n 1.8 编译程序构造简史 24 \r\n\r\n 1.8.1 1945~1960年:代码生成 24 \r\n\r\n 1.8.2 1960~1975年:分析 24 \r\n\r\n 1.8.3 1975年至今:代码生成和代码优化, 范型 24 \r\n\r\n 1.9 文法 25 \r\n\r\n 1.9.1 文法形式 25 \r\n\r\n 1.9.2 产生式过程 25 \r\n\r\n 1.9.3 文法的扩展形式 27 \r\n\r\n 1.9.4 文法特性 27 \r\n\r\n 1.9.5 文法形式化方法 28 \r\n\r\n 1.10 闭包算法 29 \r\n\r\n 1.10.1 闭包算法的迭代实现 31 \r\n\r\n 1.11 本书使用的概要代码 33 \r\n\r\n 1.12 小结 33 \r\n\r\n 第2章 从程序文本到抽象语法树 38 \r\n\r\n 2.1 从程序文本到记号——词法结构 41 \r\n\r\n 2.1.1 读程序文本 41 \r\n\r\n 2.1.2 词法分析与语法分析 42 \r\n\r\n 2.1.3 正则表达式和正则描述 43 \r\n\r\n 2.1.4 词法分析 44 \r\n\r\n 2.1.5 手动产生词法分析程序 45 \r\n\r\n 2.1.6 自动产生词法分析程序 50 \r\n\r\n 2.1.7 转换表压缩 63 \r\n\r\n 2.1.8 词法分析程序的错误处理 68 \r\n\r\n 2.1.9 一个传统的词法分析程序产生器——lex 69 \r\n\r\n 2.1.10 记号的词法识别 70 \r\n\r\n 2.1.11 符号表 72 \r\n\r\n 2.1.12 宏处理和文件包含 76 \r\n\r\n 2.1.13 小结 80 \r\n\r\n 2.2 从记号到语法树——语法分析 81 \r\n\r\n 2.2.1 语法分析的两种方法 82 \r\n\r\n 2.2.2 错误检测和错误恢复 84 \r\n\r\n 2.2.3 手工生成一个自顶向下的语法分析程序 86 \r\n\r\n 2.2.4 自动生成一个自顶向下的语法分析程序 88 \r\n\r\n 2.2.5 自动创建一个自底向上的语法分析程序 111 \r\n\r\n 2.3 小结 132 \r\n\r\n 第3章 注释抽象语法树--上下文 142 \r\n\r\n 3.1 属性文法 143 \r\n\r\n 3.1.1 依赖图 146 \r\n\r\n 3.1.2 属性计算 147 \r\n\r\n 3.1.3 循环处理 153 \r\n\r\n 3.1.4 属性分配 158 \r\n\r\n 3.1.5 多次访问属性文法 158 \r\n\r\n 3.1.6 属性文法类型的总结 167 \r\n\r\n 3.1.7 L-属性文法 167 \r\n\r\n 3.1.8 S-属性文法 170 \r\n\r\n 3.1.9 L-属性文法与S-属性文法的等价性 171 \r\n\r\n 3.1.10 扩展的文法符号和属性文法 172 \r\n\r\n 3.1.11 小结 173 \r\n\r\n 3.2 手工方法 173 \r\n\r\n 3.2.1 线性化AST 174 \r\n\r\n 3.2.2 符号解释 178 \r\n\r\n 3.2.3 数据流方程 184 \r\n\r\n 3.2.4 过程间的数据流分析 188 \r\n\r\n 3.2.5 上传信息流——活跃分析 189 \r\n\r\n 3.2.6 符号解释和数据流方程的比较 194 \r\n\r\n 3.3 小结 194 \r\n\r\n 第4章 处理中间代码 202 \r\n\r\n 4.1 解释 203 \r\n\r\n 4.1.1 递归解释 203 \r\n\r\n 4.1.2 迭代解释 207 \r\n\r\n 4.2 代码生成 210 \r\n\r\n 4.2.1 避免完全的代码生成 213 \r\n\r\n 4.2.2 开始点 214 \r\n\r\n 4.2.3 直接代码生成 214 \r\n\r\n 4.2.4 简单代码生成 218 \r\n\r\n 4.2.5 基本块的代码生成 230 \r\n\r\n 4.2.6 BURS代码生成和动态程序设计 241 \r\n\r\n 4.2.7 通过图着色的寄存器分配 255 \r\n\r\n 4.2.8 超级编译 259 \r\n\r\n 4.2.9 代码生成技术的评价 261 \r\n\r\n 4.2.10 代码优化器的调试 261 \r\n\r\n 4.2.11 预处理中间代码 262 \r\n\r\n 4.2.12 后处理目标代码 265 \r\n\r\n 4.2.13 机器代码生成 267 \r\n\r\n 4.3 汇编程序. 连接程序和装入程序 268 \r\n\r\n 4.3.1 汇编程序设计问题 270 \r\n\r\n 4.3.2 连接程序设计问题 272 \r\n\r\n 4.4 小结 273 \r\n\r\n 第5章 存储管理 283 \r\n\r\n 5.1 显式回收的数据空间分配 284 \r\n\r\n 5.1.1 基本存储空间分配 285 \r\n\r\n 5.1.2 链表 288 \r\n\r\n 5.1.3 可扩展数组 290 \r\n\r\n 5.2 隐式回收的数据空间分配 291 \r\n\r\n 5.2.1 基本垃圾收集算法 291 \r\n\r\n 5.2.2 背景预备 292 \r\n\r\n 5.2.3 引用计数 297 \r\n\r\n 5.2.4 标记和扫描 300 \r\n\r\n 5.2.5 两空间复制 303 \r\n\r\n 5.2.6 紧缩 306 \r\n\r\n 5.2.7 世代垃圾收集 307 \r\n\r\n 5.3 小结 307 \r\n\r\n 第6章 命令式和面向对象程序 313 \r\n\r\n 6.1 上下文处理 314 \r\n\r\n 6.1.1 识别 315 \r\n\r\n 6.1.2 类型检查 321 \r\n\r\n 6.1.3 小结 328 \r\n\r\n 6.2 源语言数据表示和处理 328 \r\n\r\n 6.2.1 基本类型 329 \r\n\r\n 6.2.2 枚举类型 329 \r\n\r\n 6.2.3 指针类型 329 \r\n\r\n 6.2.4 记录类型 332 \r\n\r\n 6.2.5 共用体类型 333 \r\n\r\n 6.2.6 数组类型 334 \r\n\r\n 6.2.7 集合类型 336 \r\n\r\n 6.2.8 例程类型 336 \r\n\r\n 6.2.9 对象类型 337 \r\n\r\n 6.2.10 接口类型 344 \r\n\r\n 6.3 例程及其活动 345 \r\n\r\n 6.3.1 活动记录 345 \r\n\r\n 6.3.2 例程 347 \r\n\r\n 6.3.3 例程上的操作 348 \r\n\r\n 6.3.4 非嵌套例程 350 \r\n\r\n 6.3.5 嵌套例程 352 \r\n\r\n 6.3.6 Lambda提升 357 \r\n\r\n 6.3.7 迭代器和协作例程 358 \r\n\r\n 6.4 控制流语句的代码生成 359 \r\n\r\n 6.4.1 局部控制流 359 \r\n\r\n 6.4.2 例程调用 366 \r\n\r\n 6.4.3 运行时错误处理 372 \r\n\r\n 6.5 模块的代码生成 374 \r\n\r\n 6.5.1 名字生成 375 \r\n\r\n 6.5.2 模块初始化 375 \r\n\r\n 6.5.3 泛型的代码生成 376 \r\n\r\n 6.6 小结 377 \r\n\r\n 第7章 函数式程序 386 \r\n\r\n 7.1 Haskell简介 387 \r\n\r\n 7.1.1 越位规则 387 \r\n\r\n 7.1.2 列表 388 \r\n\r\n 7.1.3 列表内涵 388 \r\n\r\n 7.1.4 模式匹配 389 \r\n\r\n 7.1.5 多态类型 390 \r\n\r\n 7.1.6 引用透明性 391 \r\n\r\n 7.1.7 高阶函数 391 \r\n\r\n 7.1.8 惰性计算 392 \r\n\r\n 7.2 编译函数式语言 393 \r\n\r\n 7.2.1 函数核 394 \r\n\r\n 7.3 多态类型检查 395 \r\n\r\n 7.3.1 多态函数应用 396 \r\n\r\n 7.4 脱糖 397 \r\n\r\n 7.4.1 列表的翻译 397 \r\n\r\n 7.4.2 模式匹配的翻译 397 \r\n\r\n 7.4.3 列表内涵的翻译 399 \r\n\r\n 7.4.4 嵌套函数的翻译 401 \r\n\r\n 7.5 图归约 402 \r\n\r\n 7.5.1 归约顺序 405 \r\n\r\n 7.5.2 归约引擎 406 \r\n\r\n 7.6 函数核程序的代码生成 409 \r\n\r\n 7.6.1 避免一些应用框架的构造 411 \r\n\r\n 7.7 优化函数核 412 \r\n\r\n 7.7.1 严格性分析 413 \r\n\r\n 7.7.2 装箱分析 417 \r\n\r\n 7.7.3 尾部调用 417 \r\n\r\n 7.7.4 累加器转换 419 \r\n\r\n 7.7.5 局限性 420 \r\n\r\n 7.8 高级图处理 421 \r\n\r\n 7.8.1 可变长度结点 421 \r\n\r\n 7.8.2 指针标记 421 \r\n\r\n 7.8.3 聚集结点分配 421 \r\n\r\n 7.8.4 向量应用结点 422 \r\n\r\n 7.9 小结 422 \r\n\r\n 第8章 逻辑式程序 427 \r\n\r\n 8.1 逻辑式程序设计模型 428 \r\n\r\n 8.1.1 构建模块 428 \r\n\r\n 8.1.2 推理机制 430 \r\n\r\n 8.2 解释的通用实现模型 431 \r\n\r\n 8.2.1 解释程序指令 432 \r\n\r\n 8.2.2 避免冗余目标列表 434 \r\n\r\n 8.2.3 避免复制目标列表尾部 434 \r\n\r\n 8.3 合一 435 \r\n\r\n 8.3.1 结构. 列表和集合的合一 435 \r\n\r\n 8.3.2 合一的实现 437 \r\n\r\n 8.3.3 两个自由变量的合一 440 \r\n\r\n 8.3.4 小结 441 \r\n\r\n 8.4 编译的通用实现模型 441 \r\n\r\n 8.4.1 列表程序 442 \r\n\r\n 8.4.2 编译子句的搜索和合一 444 \r\n\r\n 8.4.3 WAM中的优化子句选择 448 \r\n\r\n 8.4.4 应用“cut”机制 450 \r\n\r\n 8.4.5 谓词assert和retract的实现 452 \r\n\r\n 8.5 合一的编译代码 455 \r\n\r\n 8.5.1 WAM中的合一指令 456 \r\n\r\n 8.5.2 通过手工局部计算得到合一指令 457 \r\n\r\n 8.5.3 WAM中的结构合一 462 \r\n\r\n 8.5.4 一种优化:读/写模式 464 \r\n\r\n 8.5.5 WAM中合一结构的进一步优化 466 \r\n\r\n 8.5.6 小结 467 \r\n\r\n 第9章 并行和分布式程序 472 \r\n\r\n 9.1 并行程序设计模型 474 \r\n\r\n 9.1.1 共享变量和管程 474 \r\n\r\n 9.1.2 消息传递模型 476 \r\n\r\n 9.1.3 面向对象语言 477 \r\n\r\n 9.1.4 Linda元组空间 477 \r\n\r\n 9.1.5 数据并行语言 478 \r\n\r\n 9.2 进程和线程 479 \r\n\r\n 9.3 共享变量 481 \r\n\r\n 9.3.1 锁 481 \r\n\r\n 9.3.2 管程 481 \r\n\r\n 9.4 消息传递 482 \r\n\r\n 9.4.1 接收方定位 483 \r\n\r\n 9.4.2 编组 483 \r\n\r\n 9.4.3 消息的类型检查 484 \r\n\r\n 9.4.4 消息选择 484 \r\n\r\n 9.5 并行的面向对象语言 485 \r\n\r\n 9.5.1 对象定位 485 \r\n\r\n 9.5.2 对象迁移 486 \r\n\r\n 9.5.3 对象复制 487 \r\n\r\n 9.6 元组空间 488 \r\n\r\n 9.6.1 避免关联寻址的开销 488 \r\n\r\n 9.6.2 元组空间的分布实现 490 \r\n\r\n 9.7 自动并行 492 \r\n\r\n 9.7.1 自动地使用并行性 492 \r\n\r\n 9.7.2 数据依赖 494 \r\n\r\n 9.7.3 循环转换 495 \r\n\r\n 9.7.4 分布式存储器的自动并行 496 \r\n\r\n 9.8 小结 498 \r\n\r\n 附录A 一个简单的面向对象编译程序/解释程序 502 \r\n\r\n 附录B 练习答案 509 \r\n\r\n 附录C 参考文献 519 \r\n\r\n 附录D 术语表 527 \r\n
\r\n
编译程序是计算机系统软件中非常成功和最具活力的一个分支. 20世纪80年代以来, 计算机程序设计语言领域有了突飞猛进的发展, 程序语言已经不仅有传统的命令式范型, 而且包括了面向对象. 函数式. 逻辑式和并行/分布式范型. 新的程序语言的诞生, 推动了编译程序设计方法的研究, 并使新的编译技术不断引入. 新的程序语言要求有更加强大的运行时系统, 所幸的是, 计算机硬件发展水平——CPU的速度和存储容量为编译技术提供了强有力的支持.
虽然每一个计算机专业的学生未必都有机会亲自参与编译器的设计, 也没必要要求大家都具备编写编译器的能力, 但我仍然认为编译技术包含的软件设计思想和经典算法对于一个优秀的程序设计人员来说是必备的背景知识, 因此国内绝大部分的计算机专业仍然把编译原理作为必修课.
本书是迄今介绍编译程序设计方法最新. 最全面的著作之一, 可以毫不夸张地说, 该书是真正意义上的“现代编译程序设计”. 加上之前我国已经引进的两本编译技术方面的著作(Compilers Principles, Techniques, and Toolsl和Programming Languages:Design and lmplementation Fourth Edition), 这三本书对于改进我们的教学是十分有益的, 因为现在国内大多数有关编译程序设计的教材都只集中讲述C和Pascal那样的命令式语言的编译方法, 而这些书已充分注意到了进入网络时代之后程序设计语言的巨大变化, 因此书中不少内容是国内教材中十分鲜见的. 我认为这是本书中译本的最主要价值.
本书分为两部分:第一部分是第1章至第5章, 介绍传统的编译原理和技术, 包括词法分析. 语法分析. 上下文处理. 中间代码生成和优化. 存储器管理等, 第二部分是第6章至第9章, 介绍了面向对象. 函数式. 逻辑式. 并行/分布式语言中使用的特殊的编译技术. 该书作者是程序设计语言实现方面的专家, 且富有写作经验. 本书注重实现和优化技术, 增加了实用性同时提供了大量的实例说明, 大大降低了学习. 理解的难度.
本书可作为计算机专业本科生和研究生编译原理方面的教材或参考书, 也可作为软件人员从事软件开发的参考资料.
本书涉及的内容较新, 有些术语的译法还未见统一. 同时也限于译者水平, 对某些内容的理解可能有偏差. 在此预先向读者致歉, 并望广大师生不吝指正.
本书由冯博琴组织翻译并统稿. 参加翻译的人员有傅向华. 韩冰. 王自强. 何明. 张志刚. 曹博. 贺晓红. 范宁. 王静. 潘晓春. 薛亮. 汪齐名. 胡英萍. 夏虹. 傅蓉参加了校对工作, 傅向华做了大量的组织工作. 另外还要感谢吕军老师在翻译过程中所提供的帮助.
本书英文影印版《编译原理技术与工具》已由人民邮电出版社出版, 书号7—115—09916.
冯博琴
2003年7月20日
20世纪80年代至90年代, 当整个世界通过新闻报纸的头版目睹PC和Internet的兴起时, 编译程序设计方法也在悄悄地发展, 可以在技术刊物——更重要的是在当今软件使用的编译程序——上看出这种发展. 这种发展部分得益于新的程序设计方法, 部分得益于对代码生成技术的更好理解, 部分得益于更高速的大容量存储器机器的使用.
现在, 程序语言领域除包括传统的命令式范型之外, 还包括面向对象. 函数式. 逻辑式和并行/分布式范型, 这些都引入了新的编译技术, 而且常常比传统的命令式语言需要更好的运行时系统. BURS技术包含有强大的代码生成技术, 因而能极好地处理当今机器的复杂指令集. 现代机器的速度和存储器容量允许编译技术和程序语言拥有以前不可想像的特征. 现代编译程序设计方法就用于迎接这些挑战.
目标读者
我们面向的读者是即将毕业的学生, 他们至少曾使用过编译程序并且对编译的概念有一些了解. 当这些学生毕业后, 要使用现代技术, 他们就必须熟悉每一种现代范型的语言处理器. 尽管很多大学的课程要求滞后于这方面的考虑, 但即将进入人才市场的毕业生不能忽视这些发展.
经验表明, 在编译程序构造方面, 传统所教的大部分技术只是更基本技术的特例. 通常这些特殊的技术仅仅适用于命令式语言. 而更基本的技术有更广泛的应用. 例如, 在严格的后进先出语言中, 栈可以作为活动记录的优化表示. 因此, 本书:
● 集中讲述广泛应用的原理和技术, 谨慎地区分本质的东西(=对学生最有用的)和非本质的东西(=仅仅在特殊情况下对学生有用的):
● 提供直接的实现细节和优化,
● 给出进一步深入学习的阅读材料.
学完本书, 学生应该达到如下目标:
● 获得现代编译程序设计方法和构造的完整概念, 熟悉它们的实际应用,
● 通过很少的培训时间就能够开始参与每一种现代范型的语言处理器的构造,
● 能够阅读相关文献.
前两个方面为读者提供了坚实的基础, 第三个则提供了成长的潜力.
本书的结构
本书从概念上分为两大部分. 第一部分从第1章到第5章, 着眼于通
常的程序处理技术, 其中有一章存储器管理的内容, 涉及编译程序和生成代码的存储器管理. 第二部分从第6章到第9章, 覆盖了不同程序设计范型所需要的特殊技术. 本书各部分的相互关系可由下表来描述.
最左列表示了编译程序构造的4个阶段:分析. 上下文处理. 合成和运行时系统. 这一列列出的章节覆盖了相关软件的手工和自动生成, 重点是自动生成. 其余各列表示了本书的4种范型, 对每一种范型, 表中显示了在编译程序的每个阶段主要论述的一个例子. 这些章节(第6章到第9章)倾向于仅仅包括手工技术, 因为所有的自动技术已经在第2章到第4章中讨论了.
一般来讲, 理想的情况下这个表是四方的, 所有的单元格都填满——也就是说该表应该是很规则的, 但我们看到右上角几个单元格为空而左下角没有“运行时系统”的章节. 右上几格应当覆盖这样一些内容, 如逻辑式语言文本分析的特殊主题, 但是目前的文本分析技术已经足够强大和足够灵活——各种语言非常相似——以至于文本分析技术已经能处理所有的语言范型:由于没有什么问题需要解决, 我们对此不作讨论. 在左下角空缺的章节应该讨论产生运行时系统的手工和自动技术. 不幸的是很少有或者根本就没有关于这方面的文章:运行时系统仍然需由程序员在直觉基础上由手工来做:对这种情况, 由于缺乏一般的解决方案, 也不进行讨论.
第1章通过详细检查一个简单传统的模块化编译/解释程序向读者介绍编译程序设计的方法. 在介绍完关于编译程序构造的简单历史和形式文法后, 接着介绍几个关于编译程序构造的高级方面的内容.
第2章讨论编译的分析阶段:即将程序文本转化为抽象语法树. 讨论的是词法分析技术. 记号的词法识别以及语法分析等.
第3章涵盖了编译的第二个阶段:上下文处理. 讨论了几种上下文处理的方法:使用属性文法的自动上下文处理, 使用L-属性文法和S-属性文法的手工上下文处理, 使用符号解释和数据流分析的半自动上下文处理.
第4章讲述编译的合成阶段, 包含解释和代码生成. 代码生成部分主要是关于机器代码生成部分, 特定范型构造所需的中间代码在第6章到第9章讨论.
第5章关注的是存储器管理技术, 这些技术既可以用于编译程序又可用于编译程序生成的程序中.
第6章到第9章讨论的是在编译不同范型时遇到的特定问题, 这些范型包括命令式. 面向对象. 函数式. 逻辑式和并行/分布式. 命令式的编译程序和面向对象的编译程序很相似, 一起放在第6章中讨论.
附录A讨论一种可能的试验性的面向对象编译程序构造方法, 在这种方法里试图利用面向对象的概念来简化编译程序的设计.
本书中某些主题采用一种非传统的方式进行讨论, 并适当地采用了一些被证明是正确的用词.
词法分析与自底向上语法分析都基于加点项, 而不是基于Thompson的NFA结构. 在自底向上模式匹配. 统一词法分析. LR语法分析和自底向上代码生成中加点项是一个很重要的工具. 传统的词法分析算法只是项操作的低级实现. 我们认为, 词法分析与语法分析的不同处理是历史上人为造成的, 在现代软件中, 词法和语法层次之间的差异趋于消失.
尽管属性文法对编译程序设计的影响很有限, 但人们仍然对属性文法给予了相当多的注意. 它们仍然是自动上下文处理的唯一途径, 我们希望当前的讨论能够有助于降低它们应用的门槛.
与其他编译程序设计方法的书相比, 在本书中, 我们对作为重要数据的函数作了更深入的讨论. 自从在Algol60中有一个很好的开始后, 函数作为可操作的数据在诸如C. Pascal和Ada(尽管Ada95恢复了一些)等语言中的地位已经下降了很多. 然而, 一些现代概念的实现, 如函数式和逻辑式语言. 迭代器和继续(continuation), 都要求将函数作为一个一般的数据进行操作. 实现的基本内容在命令式和面向对象语言的章节涉及:更专门的内容部分在讲述其他范型的章节给出.
在1.11节中, 为便于理解, 我们对在本书中使用的概要代码进行了说明.
附加的材料, 包括习题的部分答案. 本书中所有的图和代码, 都可以通过John Wiley的Web页面访问到.
作为课程教材
本书比我们大学规定的每次两小时总共13次的编译设计方法课程包含了更多的内容, 因此必须有所取舍. 根据听课者的知识完备程度, 例如, 传统的介绍性的课程应该包括下面章节:
第1章,
第2章开始到2.1.7节:2.1.10节:2.1.11节:2.2节到2.2.4.5节:2.2.5节到2.2.5.7节:
第3章开始到3.1.2节:3.1.7节到3.1.10节, 3.2节到3.2.2.2节:3.2.3节,
第4章开始到4.1节:4.2节到4.2.4.3节:4.2.6节到4.2.6.4节:4.2.11节,
第5章开始到5.1.1.1节, 5.2节到5.2.4节,
第6章开始到6.2.3.2节:6.2.4节到6.2.10节:6.4节到6.4.2.3节.
更高级一点的课程应该包括第1章到第6章的所有的内容, 不含3.1节. 也可以包括第7章到第9章中的一章, 或许还可以加上附录A.
高级课程应当跳过大多数介绍性内容而把注意力集中于介绍性课程所忽略的部分:3.1节和第5章到第9章所有的内容, 并加上附录A.
致谢
我们对以下的人满怀感激:Miliam Bakker. Raoul Bhoedjang. Wilfred Dittmer. Thomer M.Gil. Ben N.Hasni. Bert Huijben. Jaco A.Imthorn. John Romein. Tim Ruhl和许多我们不知道其名字的审校者, 他们自愿花费时间和精力阅读本书的草稿并给出许多有用. 有时是非常详细的建议. 并感谢Ronald Veldema提供Pentium处理器的代码段.
感激Simon Plumtree. Gaynor Redvers-Mutton. Dawn Booth和John Wiley&Sons出版公司的Jane Kerr, 他们对本书的撰写过程给予了帮助和鼓励. Lambert Meertens热心地提供了关于老的ABC编译程序的信息, Ralph Griswold提供了Icon编译程序.
感谢Vrije大学的Faculteit Wiskunde en lnformatica(现在是Faculteit der Exacte Wetenschappen的一部分)提供的支持, 在本书编写过程中使用了他们的设备.
于阿姆斯特丹 2000年5月