编译器构造——C语言描述
作者 : Charles N.Fischer, Richard J.LeBlanc,Jr.
译者 : 郑启龙 姚震
丛书名 : 计算机科学丛书
出版日期 : 2005-07-29
ISBN : 7-111-16474-1
定价 : 65.00元
教辅资源下载
扩展信息
语种 : 简体中文
页数 : 531
开本 : 16开
原书名 : Crafting A Compiler with C
原出版社: Addison-Wesley
属性分类: 教材
包含CD :
绝版 :
图书简介

本书是一本优秀的编译器构造方面的教材,适合高等院校计算机专业的学生及专业程序员使用,已经被国际上多所大学或学院选作教材。本书提供了创新的编译器构造方法,通过大量的示例和练习,描述如何从头至尾设计一个可用的编译器。书中均衡覆盖了编译器设计中的理论与实现两大部分,详细讨论了标准编译器设计的相关主题 (如自顶向下和自底向上的语法分析、语义分析、中间表示和代码生成)。本书中所有的程序均采用易读的基于C语言的代码来表示。
  本书特色:
  ●均衡讨论了编译器设计的理论与实现两大部分,既很好地介绍了编译器理论,又提供了大量的编译器设计示例和练习。
  ●强调使用可以生成语法分析器和词法分析器的编译器工具。
  ●彻底讨论LR语法分析和归约技术。
  ●介绍了FLex和ScanGen。
  ●在每章末尾包含可选的高级主题。

图书特色

图书前言

本书以作者实现编译器和开发编译器构造课程的经验为基础,介绍了编译器构造的实际方法。其宗旨是使读者不仅能够对编译器的所有组件有深入的理解,而且能够对编译器的各组件如何实际组合、构成一个可以工作的编译器有感性认识。我们相信这种理念是本书一个与众不同的特色。因为我们专注于对现代编译器构造技术的介绍,所以强调尽可能地使用编译器工具生成编译器的组件。(附录B~F中所述工具的源代码,可以从出版社网站下载。)
  本书和Crafting a Compiler一书基本相同,只是其中的算法和伪代码示例使用C而不是Ada语法。由于C语言在编译器课程中广泛使用,因此许多教师认为这样的版本会很有价值。为使所有伪代码即使对于那些不是C语言专家的读者也尽可能易读,我们使用了一些标准C语法的扩展(在下面描述),而且并不总是使用通用的C语言惯用法。由于本书作者均不是熟练的C程序员,因此我们感谢Arnold Robbins对本书做了从Ada语言到C语言的转换工作,并给出很多编辑上的建议。

教科书和参考书
  作为教学用书,本书主要面向近15年来我们开发的一种课程组织结构。但是,本书的使用可以非常灵活,已经用于从为期10周的3学分高年级本科生课程到为期3个月的6学分研究生课程教学中。本书也可作为一本有价值的专业参考书,因为它完整覆盖了对编译器编写者和设计者有着重要实际意义的技术。

课程设计方法
  本书全面地覆盖了与构造编译器相关的理论主题。而且,一个密切相关的课程设计实现也是我们课程组织的重要组成部分。因此,本书也是面向课程设计的。附录A包含一个称为 Ada/CS的语言定义,它主要是Ada程序设计语言的一个重要子集。但出于教学目的,这里介绍的Ada/CS并非Ada程序设计语言的一个严格子集。针对使用本书的课程,我们建议的课程设计可以涉及部分或完整的Ada/CS实现,具体情况要根据课程的长度、层次以及授课教师的要求来定。
  本书第2章介绍并讨论一个针对非常简单的Ada/CS子集的递归下降编译器。将上述课程设计实施为该编译器的扩充,可以让学生即使在短到一个学期的课程中也能完成一个较大的课程设计。在时间充裕的情况下,这种扩充方法同样有价值。要求学生阅读并扩充一个实际的程序,可使他们获得在许多计算机科学课程中难以得到的重要经验。这也教会他们如何将编译器的各部分组合起来,而这种知识是难以用其他任何方式来讲授的。

C程序设计语言
  本书中的示例伪代码采用基于ANSI C的语法编写。从PC机到大型机直到超级计算机,C语言在许多计算环境中都是流行的语言,它小巧且富于表达力、高效,同时通常具有很好的可移植性。C语言最近已成为美国国家标准(ANSI 1989)。支持标准C语法的编译器也已广泛可用,而且将会更加普及。因此,我们选择为示例程序使用ANSI语法而不是在Kernighan and Ritchie(1978)中描述的更广为人知的语法。而Kernighan和Ritchie的新书(1988)则是ANSI C的优秀参考书。
  为了将算法尽可能以最易读的方式描述(而不关注语法细节),我们以几种方式扩充了C语言。首先,在正文的几个地方使用了匿名联合(anonymous union),该特性借用自C++(Stroustrup 1986)。一个匿名联合看起来像这样。
  注意:该结构的union成员没有名字,联合中的元素作为结构的元素被直接引用。在传统的C语言中,同样的行为通常通过宏预处理器获得。
  其次,从第10章开始,使用匿名结构(anonymous structure)作为匿名联合的成员。实际编程中,这些结构需要通过上面描述的预处理器方案实现。
  最后,在许多高层伪代码示例中,使用下列构造函数(constructor)机制来创建结构表达式。尽管这种结构不能使用宏来代替,但其含义显而易见。
  一般情况下,在使用高层伪代码而不是正规C语言时,我们将这些图标记为“算法”而不是“程序”。
  与Crafting a Compiler一样,在使用本书的课程中不必使用任何特定的语言来实现课程设计。不论选择哪种实现语言,伪代码都是极佳的设计描述手段。此外,我们提供的词法分析器和语法分析器生成工具生成的是表格而不是程序,因此它们可用于任何语言环境中。为了那些使用C语言实现课程设计的读者,我们也讨论Lex和Yacc的使用。

Ada的角色
  我们所建议的课程设计和对语言特性的讨论都基于Ada语言,因为它事实上包含了在语义分析部分我们希望讨论的所有语言特性。假如选择任何其他语言作为基础(例如Modular-2),就必须描述很多扩充以讨论编译这些东西(比如exit语句、异常处理和操作符重载)的技术。
  使用本书的学生当然不必熟悉Ada语言。附录A中的Ada/CS介绍可以作为在语义分析部分所讨论的Ada语言特性的教程。在适当的情况下,我们也考虑从其他语言(包括Modula-2、Pascal、C、ALGOL-60、ALGOL-68以及Simula)中抽取的语言特性的翻译。

各章描述
  本书作为入门课程,可以讲授第1~4章、第5章或第6章、第7章以及第8~13章和第15章的部分内容。
  本书作为高级课程,可以包含讲述语法分析的各章(第5~6章)的内容,以及第8~13章和第15章加上第14、16和17章的高级主题部分。
  第1章  绪论
  在本书的一开始概述编译过程,强调从一组组件构造编译器的概念,介绍使用工具生成其中一些组件的思想。
  第2章  一个简单编译器
  介绍一个非常简单的语言Micro,讨论编译Micro的编译器的每个组件。本章包含Micro编译器的部分文本(用Ada语言编写)。而对更全面的Ada子集的语言特性的编译则引出了以下各章所介绍的技术。
  第3章  词法分析——理论与实践
介绍构造编译器词法分析组件的基本概念和技术。本章中的讨论既包括开发手写的词法分析器,又包括使用词法分析器生成工具实现表驱动的词法分析器。
  第4章  文法和语法分析
  介绍形式语言概念和文法的基本知识,包括上下文无关文法、BNF表示法、推导和语法分析树。由于在自顶向下和自底向上的语法分析技术的定义中都用到First和Follow集,本章也对它们进行了定义。本章还包括对语言和文法关系的讨论。
  第5章  LL(1)文法及分析器
  介绍语法分析的第一种方法—自顶向下的语法分析。讨论递归下降和LL(1),重点放在后者。语法分析器生成器的使用是本章的重点。
  第6章  LR分析
  介绍另一种语法分析方法—自底向上的语法分析。介绍LR、SLR和LALR语法分析概念及其与LL技术的比较。语法分析器生成器的使用也是本章的重点。
  第7章  语义处理
  本章结合自顶向下和自底向上语法分析器来介绍语义处理的基本原理。主题包括:不同编译器组织方式的比较,(在自顶向下的语法分析中)向文法增加动作符号,(在自底向上的语法分析中)为“语义钩子”(semantic hook)重写文法,定义语义记录和使用语义栈,检查语义正确性,产生中间代码。
  第8章  符号表
  本章强调符号表的使用,它作为一个抽象组件由编译器的其他组件通过精确定义的接口使用。本章介绍其可能的实现,随后讨论用符号表处理嵌套的作用域和其他用来定义可从外围作用域(例如记录和Ada中的包)访问的名字的语言特性。
  第9章  运行时存储组织
  介绍运行时存储管理的基本技术,包括静态分配、基于栈的分配和一般动态(堆)分配的讨论。
  第10章  处理声明
  讨论处理类型、变量和常量声明的基本技术。这些内容的组织基于处理特定语言特性的语义例程。
  第11章  处理表达式和数据结构引用
  概述处理变量引用和算术、布尔表达式的语义例程。在对变量引用的讨论中,包括针对数组元素和记录域的地址计算方法。在本章及随后两章中,强调检查语义正确性和产生被目标代码生成器使用的中间代码的技术。
  第12章  翻译控制结构
  本章的重点是针对像if语句、case语句和各种循环结构等特性的编译技术。强调使用语义栈或语法树简化这些结构的处理。这些结构可以嵌套并扩展到任意规模的程序文本中。学生应通过特定的方法来了解这种通用技术的优点。
  第13章  翻译过程和函数
  介绍处理子程序声明和调用的技术。由于这个主题的很多复杂性涉及参数,本章提供了很多材料来讲述创建参数描述、检查子程序调用中实际参数的正确性以及不同参数模式所需的代码生成技术。这里讨论运行时活动栈的概念,给出实现它所必需的支持例程。
  第14章  属性文法和多遍翻译
  多遍翻译由遍历中间代码形式模拟。本章强调信息流的属性模型。
  第15章  代码生成和局部代码优化
  介绍代码生成器,它作为一个独立组件,将语义例程生成的中间代码翻译为编译器最终的目标代码。介绍像指令选择、寄存器管理和寻址模式的使用等主题。本章还包括对基本块优化的讨论。
  第16章  全局优化
  本章的焦点是那些通过适度的努力可以生成有用代码改进的实用技术。因此,本章的主要部分包括全局数据流分析、优化子程序调用和优化循环。
  第17章  现实世界中的语法分析
  本章包括实现一个实际编译器必需的两个主要课题:语法错误处理和表压缩。错误处理部分介绍用于递归下降、LL和LR分析器的错误恢复和错误修复技术。表压缩技术用于LL和LR分析器,以及词法分析器表和任何其他需要用快速访问稀疏表中的元素来高效存储的场合。

致谢
  很多人为Crafting a Compiler和本书作出贡献。首先,感谢威斯康星大学麦迪逊分校CS 701/2和乔治亚理工学院ICS 4410中的许多学生,他们使用了本书最初版本和最终成为本书部分章节的讲义。此外,还要感谢两所学校里使用我们的讲义授课的许多教师。其中包括Raphael Finkel、Marvin Solomon和K. N. King,他们为我们的讲义贡献了部分材料;还有Nancy Lynch、Martin McKendry、Nancy Griffeth和David Pitts,他们也使用了我们的讲义。乔治亚理工学院的Arnold Robbins提供了正文中出现的所有C语言代码。他还提供了一些章节的习题、封面设计的想法以及许多对我们写作风格很有用的建议。G A Venkatesh、Will Winsborough和Felix Wu提供了大部分习题的参考答案。Jon Mauney、Gary Sevitsky、Robert Gray和Felix Wu开发了附录中描述的编译器工具。Kathy Schultz出色地完成了手稿的最终订正,Sheryl Pomraning出色地完成了美工工作。
  我们感谢 C. Wrandel Barth、Jean Gallier、James Harp、Harry Lewis、Eric Roberts和Henry Shapiro,他们对我们最初的提议和样章提供了有价值的反馈。我们非常感激Steve Allan、Henry Bauer、Roger Eggen、Norman Hutchinson、Sathis Menon、Jim Bitner、Charles Shipley、Donald K. Friesen、Donald Cooley、Susan Graham、Steve Zeigler,尤其是Paul Hilfinger和Alan Wendt—他们作为审阅者提供了大量意见,使我们在很长时间内忙于完成本书及其早期版本。
  特别感谢Alan Apt,我们杰出的编辑,感谢他的耐心和鼓励。同时感谢Benjamin/Cummings的所有员工,他们如此热情地支持我们的工作;感谢Todd Proebsting和Chris Sabooni,他们细心地检查我们的手稿;感谢Alyssa Weiner以及工作组的其他成员的细致工作;感谢Jane Rundell和Impressions的所有员工。
  最后,感谢Miriam Robbins,她在Arnold努力将大量的Ada算法转换为清晰而精确的C算法时表现出了极大的耐心。

作者简介

Charles N.Fischer, Richard J.LeBlanc,Jr.:Charles N.Fischer: Charles N. Fischer是威斯康星大学麦迪逊分校的计算机教授,他的研究兴趣主要包括编译器设计和实现等。Richard J. LeBlanc, Jr.是佐治亚理工学院计算学院的教授和副主任,ACM和IEEE计算机协会的会员,他的研究兴趣主要包括软件工程、编程语言设计和实现、编程环境等。
Richard J.LeBlanc,Jr.: 佐治亚理工学院计算学院的教授和副主任,ACM和IEEE计算机协会会员,他的研究兴趣主要包括软件工程、编程语言设计和实现、编程环境等。

译者简介

郑启龙 姚震:暂无简介

译者序

当今计算机体系结构正处于从32位向64位跨越的时代,除了硬件本身的革命性设计之外,要想充分发挥64位硬件计算平台的效率并以此提高应用软件的性能,编译器作为现代计算机中最重要的系统软件之一,其作用是无可替代的。因此,编译器的原理与设计应该是计算机专业学生所必须学习和掌握的一门重要的专业基础课。尽管最终从事编译器构造这种浩繁而艰巨的工程的人只是少数,但通过对编译器原理的学习、对其设计技巧的掌握,可以使学生对诸如程序设计语言、数据结构和算法设计与分析等诸多计算机专业基础课程有更加深入的理解与体会。通过对编译器这个沟通软硬件的“翻译”桥梁角色的认识,还可以让学生对计算机软、硬件的相互依存、相互支持的关系有更进一步的领悟与洞察。而这一切的获得往往开始于选择一本好的教材、一本有益的参考书。可以这么说,好的选择是成功道路上坚实的第一步。
  由Charles N. Fischer和Richard J. LeBlanc, Jr两位教授合著的本书就是一本这样的书。本书中文版的第一译者最早在11年前就接触了本书的原版,从中受益并采撷了部分知识用于当时的科研工作,之后在中国科学技术大学多次讲授“编译原理与技术”课程时也就一直把它作为重要的不可或缺的教学参考书。
  正如本书的书名首先让人想到的,它是一本告诉人们如何用C语言去实际地构造编译器的书,这正是本书的最大特色—完美而均衡地覆盖了编译器的理论和实现的相关议题。本书使读者在阅读深奥而枯燥的理论的同时,又能享受精妙而细致的实现,虽精巧但又不落于旁支细节,既可信手拈来又给人以启迪与思考的空间,在精彩或重要之处作者更是不惜笔墨。另外,本书还是一本编译器构造理论方面的有价值的专著,书中不乏围绕构造一个编译器而进行的系统全面、内容详实的理论介绍。全书正文共分17章,其中包括了从最基本的词法分析到语法分析,再到语义处理、运行时存储环境、代码生成和代码优化,从符号表的组织到程序错误的处理等编译器各个典型的组成部分的周到的分析与讨论;所涉及的程序设计语言从较早期的Algol 60、Modula-2到美国国防部专用的、功能丰富但也十分复杂的Ada语言,从简单的Pascal语言到灵活的C语言,再到时下流行的专业程序员首选的C++语言等。
  尽管本书反映的是截止到20世纪90年代初期的研究成果,但它精辟的理论分析和细致的实现描述却有力地影响着后来的编译器的设计与实现。本书译者曾在某国际著名软件公司的商用编译器所生成的目标代码中看到了本书所介绍的优化编译技术的踪影。对于这本内容丰富、理论与实践交融的专著,我们有理由相信它会成为对编译器感兴趣并有着不同需求的读者们的良师益友。
  本书中文版的翻译工作由郑启龙和姚震完成。其中:姚震负责完成前言、第1章~第7章、附录A~附录F的翻译工作,郑启龙负责第8章~第17章的翻译工作并校对了全部译稿。
  本书是两位译者第一次翻译国外计算机专业著作,由于水平有限,加之时间仓促,其中难免有这样或那样的错误与不当之处,恳请各位读者批评指正。

郑启龙  姚震
2005年4月于
中国科学技术大学

图书目录

第1章  绪论 1
1.1  概述和历史 1
1.2  编译器可以做什么 2
1.3  编译器结构 5
1.4  程序设计语言的语法和语义 8
1.5  编译器设计与程序设计语言设计 10
1.6  编译器分类 11
1.7  影响编译器设计的因素 12
练习 13
第2章  一个简单编译器 15
2.1  Micro编译器结构 15
2.2  Micro词法分析器 15
2.3  Micro 语法 19
2.4  递归下降语法分析 21
2.5  翻译 Micro 25
2.5.1  目标语言 25
2.5.2  临时变量 25
2.5.3  动作符号 25
2.5.4  语义信息 25
2.5.5  Micro动作符号 26
练习 31
第3章  词法分析—理论和实践 33
3.1  概述 33
3.2  正则表达式 34
3.3  有限自动机和词法分析器 35
3.4  使用词法分析器生成器 38
3.4.1  ScanGen 38
3.4.2  Lex 43
3.5  实现时考虑的问题 45
3.5.1  保留字 45
3.5.2  编译器指示与源程序行列表 47
3.5.3  符号表中的标识符条目 47
3.5.4  词法分析器的终止 48
3.5.5  多字符的超前搜索 48
3.5.6  词法错误恢复 49
3.6  将正则表达式转换为有限自动机 51
3.6.1  构造确定的有限自动机 52
3.6.2  优化有限自动机 54
练习 55
第4章  文法和语法分析 59
4.1  上下文无关文法:概念与记号 59
4.2  上下文无关文法中的错误 61
4.3  转换扩展 BNF文法 62
4.4  语法分析器与识别器 63
4.5  文法分析算法 64
练习 69
第5章  LL(1)文法及分析器 71
5.1  LL(1) Predict函数 71
5.2  LL(1)分析表 73
5.3  从LL(1)分析表构造递归下降分析器 74
5.4  LL(1)分析器驱动程序 77
5.5  LL(1)动作符号 77
5.6  文法的LL(1)化 78
5.7  LL(1)分析中的If-Then-Else问题 81
5.8  LLGen—LL(1)语法分析器生成器 82
5.9  LL(1)分析器的性质 85
5.10  LL(k)分析 85
练习 87
第6章  LR分析 89
6.1  移进-归约分析器 89
6.2  LR分析器 91
6.2.1  LR(0)分析 92
6.2.2  如何判定LR(0)分析程序工作的正确性 96
6.3  LR(1)分析 98
6.3.1  LR(1)分析的正确性 101
6.4  SLR(1)分析 102
6.4.1  SLR(1)分析的正确性 103
6.4.2  SLR(1)技术的局限性 104
6.5  LALR(1)分析 105
6.5.1  构造LALR(1)分析器 108
6.5.2  LALR(1)分析的正确性 112
6.6  在移进-归约分析器中调用语义例程 113
6.7  使用语法分析器生成器 114
6.7.1  LALRGen语法分析器生成器 114
6.7.2  Yacc 116
6.7.3  可控二义性的使用和误用 117
6.8  优化分析表 120
6.9  实用的LR(1)分析器 123
6.10  LR分析的性质 125
6.11  LL(1)和LALR(1)分析方法的比较 125
6.12  其他的移进-归约技术 128
6.12.1  扩展的超前搜索技术 128
6.12.2  优先级技术 128
6.12.3  一般的上下文无关分析器 130
练习 132
第7章  语义处理 137
7.1  语法制导翻译 137
7.1.1  使用分析的语法树表示 137
7.1.2  编译器组织的候选形式 138
7.1.3  一遍编译中的分析、检查和翻译 142
7.2  语义处理技术 143
7.2.1  LL分析器和动作符号 143
7.2.2  LR分析器和动作符号 143
7.2.3  语义记录表示 144
7.2.4  实现动作控制的语义栈 146
7.2.5  分析器控制的语义栈 149
7.3  中间表示和代码生成 155
7.3.1  比较中间表示和直接代码生成 155
7.3.2  中间表示的形式 155
7.3.3  一个元组语言 157
练习 157
第8章  符号表 161
8.1  符号表接口 161
8.2  基本实现技术 162
8.2.1  二叉搜索树 162
8.2.2  哈希表 163
8.2.3  串空间数组 164
8.3  块结构符号表 165
8.4  块结构符号表的扩展 169
8.4.1  域和记录 169
8.4.2  导出规则 170
8.4.3  导入规则 174
8.4.4  可更改的搜索规则 175
8.5  隐式声明 177
8.6  重载 177
8.7  前向引用 178
8.8  小结 180
练习 180
第9章  运行时存储组织 183
9.1  静态分配 183
9.2  栈分配 183
9.2.1  显示表 185
9.2.2  块级与过程级活动记录 187
9.3  堆分配 188
9.3.1  无空间释放 188
9.3.2  显式释放 188
9.3.3  隐式释放 189
9.3.4  管理堆空间 190
9.4  内存中的程序布局 191
9.5  静态链簇和动态链簇 193
9.6  形式过程 195
9.6.1  静态链簇 196
9.6.2  显示表 197
9.6.3  一些看法 198
练习 199
第10章  处理声明 203
10.1  声明处理的基本原则 203
10.1.1  符号表中的属性 203
10.1.2  类型描述符结构 204
10.1.3  语义栈中的列表结构 205
10.2  简单声明的动作例程 207
10.2.1  变量声明 207
10.2.2  类型定义、声明和引用 209
10.2.3  记录类型 212
10.2.4  静态数组 214
10.3  高级特性的动作例程 216
10.3.1  变量和常量声明 216
10.3.2  枚举类型 218
10.3.3  子类型 220
10.3.4  数组类型 221
10.3.5  变体记录 227
10.3.6  访问类型 232
10.3.7  包 233
10.3.8  attributes和semantics_record结构 236
练习 239
第11章  处理表达式和数据结构引用 241
11.1  概述 241
11.2  简单名字、表达式和数据结构的动作例程 242
11.2.1  处理简单标识符和文字常量 242
11.2.2  处理表达式 243
11.2.3  简单的记录和数组引用 246
11.2.4  记录和数组示例 249
11.2.5  串 250
11.3  高级特性的动作例程 250
11.3.1  多维数组的组织和引用 250
11.3.2  含动态对象的记录 258
11.3.3  变体记录 261
11.3.4  访问类型的引用 262
11.3.5  Ada中其他名字的使用 263
11.3.6  记录和数组聚合 265
11.3.7  重载解析 266
练习 269
第12章  翻译控制结构 271
12.1  if语句 271
12.2  循环 274
12.2.1  while循环 274
12.2.2  for循环 275
12.3  编译exit语句 280
12.4  case语句 282
12.5  编译goto语句 287
12.6  异常处理 290
12.7  短路计算布尔表达式 294
12.7.1  单地址短路计算 299
练习 305
第13章  翻译过程和函数 309
13.1  简单子程序 309
13.1.1  声明无参子程序 309
13.1.2  调用无参过程 311
13.2  向子程序传递参数 312
13.2.1  值、结果和值-结果参数 313
13.2.2  引用和只读参数 314
13.2.3  处理参数声明的语义例程 314
13.3  处理子程序调用和参数表 316
13.4  子程序调用 317
13.4.1  保存和恢复寄存器 317
13.4.2  子程序的入口和出口 318
13.5  标号参数 321
13.6  名字参数 323
练习 324
第14章  属性文法和多遍翻译 327
14.1  属性文法 327
14.1.1  简单赋值形式和动作符号 329
14.1.2  树遍历的属性计算程序 331
14.1.3  直接属性计算程序 335
14.1.4  属性文法示例 340
14.2  树结构的中间表示 342
14.2.1  抽象语法树接口 343
14.2.2  语法树抽象接口 344
14.2.3  实现树 348
练习 349
第15章  代码生成和局部代码优化 351
15.1  概述 351
15.2  寄存器和临时变量管理 352
15.2.1  临时变量的分类 353
15.2.2  分配和释放临时变量 353
15.3  简单的代码生成器 354
15.4  解释性代码生成 356
15.4.1  优化地址计算 357
15.4.2  避免冗余计算 359
15.4.3  寄存器追踪 361
15.5  窥孔优化 367
15.6  从树结构生成代码 368
15.7  从dag生成代码 371
15.7.1  别名 376
15.8  代码生成器的生成器 377
15.8.1  基于文法的代码生成器 380
15.8.2  在代码生成器中使用语义属性 382
15.8.3  生成窥孔优化器 385
15.8.4  基于树重写的代码生成器的生成器 387
练习 387
第16章  全局优化 393
16.1  概述—目标与限制 393
16.1.1  理想的优化编译器结构 394
16.1.2  优化展望 397
16.2  优化子程序调用 397
16.2.1  子程序调用的内联展开 397
16.2.2  优化对封闭子例程的调用 399
16.2.3  过程间数据流分析 402
16.3  循环优化 406
16.3.1  外提循环不变式 406
16.3.2  循环中强度削弱 409
16.4  全局数据流分析 411
16.4.1  单路径流分析 411
16.4.2  全路径流分析 415
16.4.3  数据流问题的分类 416
16.4.4  其他重要的数据流问题 416
16.4.5  使用数据流信息的全局优化 418
16.4.6  求解数据流方程 422
16.5  集成优化技术 430
练习 431
第17章  现实世界中的语法分析 437
17.1  压缩表 437
17.1.1  压缩LL(1)分析表 439
17.2  语法错误的恢复与修复 440
17.2.1  即时错误检测 442
17.2.2  递归下降分析器中的错误恢复 443
17.2.3  LL(1)分析器中的错误恢复 445
17.2.4  FMQ LL(1)错误修复算法 446
17.2.5  在FMQ修复算法中添加删除操作 449
17.2.6  FMQ算法的扩展 450
17.2.7  利用LLGen进行错误修复 454
17.2.8  LR错误恢复 455
17.2.9  Yacc中的错误恢复 455
17.2.10  自动生成的LR修复技术 456
17.2.11  利用LALRGen进行错误修复 462
17.2.12  其他LR错误修复技术 462
练习 463
附录A  Ada/CS语言定义 467
附录B  ScanGen 487
附录C  LLGen用户手册 493
附录D  LALRGen用户手册 499
附录E  LLGen和LALRGen错误修复特性 507
附录F  编译器开发实用工具 511
参考文献 517
索引 523

教学资源推荐
作者: 丁山 朱留存 编著
作者: (美)Bjarne Stroustrup 著
作者: [日]迈克尔·麦库尔(Michael McCool) [美]阿奇·D. 罗宾逊(Arch D. Robison) [美]仁达敬(James Reinders)著
作者: Brian W.Kernigham
参考读物推荐
作者: Eric Brechner
作者: 陶国荣 著
作者: 张文亮 编著