内容介绍
基本信息
| 书名: | 程序设计语言编译原理(D3版) |
| 作者: | 陈火旺//刘春林//谭庆平//赵克佳//刘越 | 开本: | |
| YJ: | 39 | 页数: | |
| 现价: | 见1;CY =CY部 | 出版时间 | 2014-12-01 |
| 书号: | 9787118022070 | 印刷时间: | |
| 出版社: | 国防工业出版社 | 版次: | |
| 商品类型: | 正版图书 | 印次: | |
内容提要 作者简介 精彩导读 D一章引论
1.1什么叫编译程序
使用过现代计算机的人都知道,多数用户是应用GJ语言来实现他们所需要的计算的。现代计算机系统一般都含有不止一个的GJ语言编译程序,对有些GJ语言甚至配置了几个不同性能的编译程序,供用户按不同需要进行选择。GJ语言编译程序是计算机系统软件Z重要的组成部分之一,也是用户Z直接关心的工具之一。
在计算机上执行一个GJ语言程序一般要分为两步:D一步,用一个编译程序把GJ语言翻译成机器语言程序;D二步,运行所得的机器语言程序求得计算结果。
通常所说的翻译程序是指这样的一个程序,它能够把某一种语言程序(称为源语言程序)转换成另一种语言程序(称为目标语言程序),而后者与前者在逻辑上是等价的。如果源语言是诸如FORTRAN、Pascal、C、Ada、Smalhalk或Java这样的“GJ语言”,而目标语言是诸如汇编语言或机器语言之类的“低级语言”,这样的一个翻译程序J称为编译程序。
GJ语言程序除了像上面所说的先编译后执行外,有时也可“解释’’执行。一个源语言的解释程序是这样的程序,它以该语言写的源程序作为输入,但不产生目标程序,而是边解释边执行源程序本身。本书将不对解释程序作专门的讨论。实际上,许多编译程序的构造与实现技术同样适用于解释程序。
根据不同的用途和侧重,编译程序还可进一步分类。专门用于帮助程序开发和调试的编译程序称为诊断编译程序(DiagDsticCompiler),着重于提高目标代码效率的编译程序”4优化编译程序(0ptiIIlizingCompiler)。现在很多编译程序同时提供了调试、优化等多种功能,用户可以通过“开关”进行选择。运行编译程序的计算机称宿主机,运行编译程序所产生目标代码的计算机称目标机。如果一个编译程序产生不同于其宿主机的机器代码,则称它为交叉编译程序(CrossCompiler)。如果不需重写编译程序中与机器无关的部分J能改变目标机,则称该编译程序为可变目标编译程序(RetargetableCompile,)。
SJ上D一个编译程序——FORrⅡ认N编译程序是20世纪50年代中期研制成功的。D时,人们普遍认为设计和实现编译程序是一件十分困难、令人生畏的事情。经过40年的努力,编译理论与技术得到迅速发展,现在已形成了一套比较成熟的、系统化的理论与方法,并且开发出了一些好的编译程序的实现语言、环境与工具。在此基础上设计并实现一个编译程序不再是高不可攀的事情。
本书主要介绍设计和构造编译程序的基本原理和方法。我们不想罗列太多细节性的材料,着重讲一些原理性的东西,但将反映一些ZX的进展。
…… 目录 D一章 引论 1.1 什么叫编译程序 1.2 编译过程概述 1.3 编译程序的结构 1.3.1 编译程序总框 1.3.2 表格与表格管理 I.3.3 出错处理 1.3.4 遍 1.3.5 编译前端与后端 1.4 编译程序与程序设计环境 1.5 编译程序的生成 D二章 GJ语言及其语法描述 2.1 程序语言的定义 2.1.1 语法 2.1.2 语义 2.2 GJ语言的一般特性 2.2.1 GJ语言的分类 2.2.2 程序结构 2.2.3 数据类型与操作 2.2.4 语句与控制结构 2.3 程序语言的语法描述 2.3.1 上下文无关文法 2.3.2 语法分析树与二义性 2.3.3 形式语言鸟瞰 练 习 D三章 词法分析 3.1 对于词法分析器的要求 3.1.1 词法分析器的功能和输出形式 3.1.2 词法分析器作为一个D立子程序 3.2 词法分析器的设计 3.2.1 输入、预处理 3.2.2 单词符号的识别:超前搜索 3.2.3 状态转换图 3.2.4 状态转换图的实现 3.3 正规表达式与有限自动机 3.3.1 正规式与正规集 3.3.2 确定有限自动机(DFA) 3.3.3 非确定有限自动机(NFA) 3.3.4 正规文法与有限自动机的等价性 3.3.5 正规式与有限自动机的等价性 3.3.6 确定有限自动机的化简 3.4 词法分析器的自动产生 3.4.1 语言LEX的一般描述 3.4.2 超前搜索 3.4.3 LEX的实现 练 习 D四章 语法分析——自上而下分析 4.1 语法分析器的功能 4.2 自上而下分析面临的问题 4.3 LL(1)分析法 4.3.1 左递归的消除 4.3.2 消除回溯、提左因子 4.3.3 LL(1)分析条件 4.4 递归下降分析程序构造 4.5 预测分析程序 4.5.1 预测分析程序工作过程 4.5.2 预测分析表的构造 4.6 LL(1)分析中的错误处理 练 习 D五章 语法分析——自下而上分析 5.1 自下而上分析基本问题 5.1.1 归约 5.1.2 规范归约简述 5.1.3 符号栈的使用与语法树的表示 5.2 算符优先分析 5.2.1 算符优先文法及优先表构造 5.2.2 算符优先分析算法 5.2.3 优先函数 5.2.4 算符优先分析中的出错处理 *5.3 LR分析法 5.3.1 LR分析器 5.3.2 LR(0)项目集族和LR(0)分析表的构造 5.3.3 SLR分析表的构造 5.3.4 规范LR分析表的构造 5.3.5 LALR分析表的构造 5.3.6 二义文法的应用 5.3.7 LR分析中的出错处理 5.4 语法分析器的自动产生工具YAcc 练 习 D六章 属性文法和语法制导翻译 6.1 属性文法 6.2 基于属性文法的处理方法 6.2.1 依赖图 6.2.2 树遍历的属性计算方法 6.2.3 一遍扫描的处理方法 6.2.4 抽象语法树 6.3 S一属性文法的自下而上计算 6.4 L一属性文法和自1;CY =CY向下翻译 6.4.1 翻译模式 6.4.2 自1;CY =CY向下翻译 6.4.3 递归下降翻译器的设计 6.5 自下而上计算继承属性 6.5.1 从翻译模式中去掉嵌入在产生式中间的动作一 6.5.2 分析栈中的继承属性 6.5.3 模拟继承属性的计算 6.5.4 用综合属性代替继承属性 练 习 D七章 语义分析和中间代码产生 7.1 中间语言 7.1.1 后缀式 7.1.2 图表示法 7.1.3 三地址代码 7.2 说明语句 7.2.1 过程中的说明语句 7.2.2 保留作用域信息 7.2.3 记录中的域名 7.3 赋值语句的翻译 7.3.1 简单算术表达式及赋值语句 7.3.2 数组元素的引用 7.3.3 记录中域的引用 7.4 布尔表达式的翻译 7.4.1 数值表示法 7.4.2 作为条件控制的布尔式翻译 7.5 控制语句的翻译 7.5.1 控制流语句 7.5.2 标号与got语句 7.5.3 CASE语句的翻译 7.6 过程调用的处理 7.7 类型检查 7.7.1 类型系统 7.7.2 类型检查器的规格说明 7.7.3 函数和运算符的重载 7.7.4 多态函数 练 习 D八章 符号表 8.1 符号表的组织与作用 8.1.1 符号表的作用 8.1.2 符号表的组织方式 8.2 整理与查找 8.2.1 线性表 8.2.2 对折查找与二叉树 8.2.3 杂凑技术 8.3 名字的作用范围 8.3.1 FORTRAN的符号表组织 8.3.2 Pascal的符号表组织 8.4 符号表的内容 练 习 D九章 运行时存储空间组织 9.1 目标程序运行时的活动 9.1.1 过程的活动 9.1.2 参数传递 9.2 运行时存储器的划分 9.2.1 运行时存储器的划分 9.2.2 活动记录 9.2.3 存储分配策略 9.3 静态存储分配 9.3.1 数据区 *9.3.2 公用语句的处理 *9.3.3 等价语句的处理 *9.3.4 地址分配 9.3.5 临时变量的地址分配 9.4 简单的栈式存储分配 9.4.1 C的活动记录 9.4.2 C的过程调用、过程进入、数组空间分配和过程返回 9.5 嵌套过程语言的栈式实现 9.5.1 非局部名字的访问的实现 9.5.2 参数传递的实现 9.6 堆式动态存储分配 9.6.1 堆式动态存储分配的实现 9.6.2 隐式存储回收 练 习 D十章 优化 10.1 概述 10.2 局部优化 10.2.1 基本块及流图 10.2.2 基本块的DAG表示及其应用. 10.3 循环优化 10.3.1 代码外提 10.3.2 强度削弱 10.3.3 删除归纳变量 *10.4 数据流分析 10.4.1 任意路径数据流分析 10.4.2 全路径数据流分析 10.4.3 数据流问题的分类 10.4.4 其它主要的数据流问题 10.4.5 利用数据流信息进行全局优化 练 习 D十一章 目标代码生成 11.1 基本问题 11.2 目标机器模型 11.3 一个简单的代码生成器 11.3.1 待用信息 11.3.2 寄存器描述和地址描述 11.3.3 代码生成算法 11.4 寄存器分配 11.5 DAG的目标代码 11.6 窥孔优化 练 习 D十二章 并行编译基础 12.1 并行计算机及其编译系统. 12.1.1 向量计算机 12.1.2 共享存储器多处理机 12.1.3 分布存储器大规模并行计算机 12.1.4 并行编译系统的结构 12.2 基本概念 12.2.1 向量与向量的次序 12.2.2 循环模型与索引空间 12.2.3 输入与输出集合 12.2.4 语句的执行顺序 12.3 依赖关系 12.3.1 依赖关系定义 12.3.2 语句依赖图 12.3.3 依赖距离、依赖方向与依赖层次 12.4 依赖关系问题 12.5 依赖关系测试 12.6 循环的向量化与并行化 12.7 循环变换技术 练 习 参考文献
目录
。。。。。。。。。。
《编译原理与技术实践:从抽象到执行的桥梁》 在信息技术日新月异的今天,各种编程语言层出不穷,它们以不同的语法、范式和抽象层次,极大地丰富了我们表达计算逻辑的手段。然而,计算机硬件本身只能理解机器码,那些我们用以指挥机器工作的“高级语言”是如何被转化为机器能够执行的指令的呢?这正是编译技术的核心课题。本书旨在深入剖析编译器的设计与实现原理,带领读者跨越从高级语言抽象表达到着计算机底层执行的鸿沟,构建一座坚实的桥梁。 内容概述: 本书系统地阐述了编译器的完整生命周期,从词法分析到最终代码生成的每一个环节,都进行了详尽的讲解和细致的剖析。我们不仅仅停留在理论层面,更注重将这些原理与实际的工程实践相结合,帮助读者理解如何在真实世界中构建一个功能完备的编译器。 第一部分:编译器的基础与前端(理解语言的结构) 导论:编译器的角色与组织结构 我们将首先探讨编译器的基本概念,理解它在软件开发流程中的关键作用。 深入分析一个典型的编译器是如何被分解为前端、后端和优化器等不同阶段的。 介绍编译过程的总体流程图,以及各个阶段之间的输入输出关系。 讨论不同类型的编译器(如解释器、虚拟机)与传统编译器的异同。 词法分析:语言的“字符流”到“标记流”的转换 本章将聚焦于编译器的第一个重要阶段——词法分析。 我们学习如何通过正则表达式精确描述编程语言的构成元素,如关键字、标识符、运算符、常量等。 深入理解有限自动机(Finite Automata)的工作原理,并学习如何从正则表达式自动生成识别这些模式的有限自动机。 讲解如何利用扫描器(Scanner)或词法分析器(Lexer)生成器工具(如Lex/Flex)来高效地实现词法分析。 通过具体的代码示例,演示如何处理输入源程序,将其分解为一系列有意义的“标记”(Tokens)。 语法分析:语言的“标记流”到“语法树”的构建 在词法分析的基础上,本章将深入探讨语法分析(Parsing)——将标记流转化为结构化表示的过程。 我们将学习上下文无关文法(Context-Free Grammars, CFG)作为描述编程语言语法的强大工具。 理解推导(Derivation)和规约(Reduction)的概念,以及它们在语法分析中的意义。 重点讲解两种主要的语法分析方法: 自顶向下分析: 包括递归下降分析(Recursive Descent Parsing)和LL(1)分析。我们将学习如何构建预测分析表,并分析其优缺点。 自底向上分析: 包括移入-规约分析(Shift-Reduce Parsing)、LR(0)、SLR(1)、LALR(1)和LR(1)分析。我们将详细讲解LR族分析的工作机制,以及如何生成LR分析表。 介绍语法制导翻译(Syntax-Directed Translation, SDT)的概念,它将语法分析与语义动作紧密结合。 通过实例演示如何构建抽象语法树(Abstract Syntax Tree, AST),这是后续语义分析和代码生成的基础。 语义分析:赋予语法结构以意义 语法树虽然描述了程序的结构,但并未包含其含义。本章将侧重于语义分析,为程序赋予意义。 类型检查(Type Checking): 学习如何验证程序中的类型兼容性,防止类型错误,并讨论隐式类型转换和显式类型转换。 作用域(Scope)和符号表(Symbol Table): 深入理解变量的作用域规则,以及如何设计和维护符号表来记录标识符的信息(如类型、作用域、存储位置等)。 其他语义规则: 讨论如赋值语句的合法性、函数调用的匹配性等其他重要的语义规则的检查。 介绍属性文法(Attribute Grammars)作为一种形式化描述语义规则的工具。 讲解如何通过遍历抽象语法树,执行相应的语义检查和属性计算。 第二部分:编译器的后端与优化(将中间表示转化为高效执行代码) 中间代码生成:独立于具体机器的表示 本章将探讨如何将经过语义分析的程序表示,转化为一种介于高级语言和机器码之间的中间表示(Intermediate Representation, IR)。 介绍几种常见的中间代码形式,如三地址码(Three-Address Code)、P-代码(P-Code)以及更现代的图表示(如控制流图、数据流图)。 讲解如何基于抽象语法树生成三地址码,并分析其结构优势。 讨论中间代码作为编译器前端和后端之间的桥梁,如何使得优化和代码生成工作更加模块化和高效。 代码优化:提升程序执行效率的艺术 优化是编译器提升程序性能的关键。本章将系统介绍各种常用的代码优化技术。 局部优化(Local Optimization): 常量折叠(Constant Folding): 在编译时计算常量表达式的值。 代数化简(Algebraic Simplification): 利用代数定律简化表达式。 公共子表达式消除(Common Subexpression Elimination, CSE): 避免重复计算相同的表达式。 全局优化(Global Optimization): 控制流分析: 构建和分析控制流图(Control Flow Graph, CFG),识别循环、基本块等结构。 数据流分析: 介绍到达定值(Reaching Definitions)、活跃变量(Live Variables)、常量传播(Constant Propagation)等数据流分析技术,以及它们在优化中的应用。 循环优化: 包括循环不变代码外提(Loop-Invariant Code Motion)、归纳变量消除(Induction Variable Elimination)等。 过程间优化(Interprocedural Optimization): 简要介绍函数调用链分析等。 过程优化: 内联(Inlining): 用函数体替换函数调用。 死代码消除(Dead Code Elimination): 移除永远不会被执行的代码。 目标代码生成:从中间表示到机器指令 这是编译器生成可执行代码的最后阶段。本章将深入讲解如何将中间表示转化为特定目标处理器的机器指令。 指令选择(Instruction Selection): 如何根据中间代码指令选择最优的目标机器指令序列。 寄存器分配(Register Allocation): 资源受限的处理器,高效利用寄存器至关重要。我们将学习图着色(Graph Coloring)等经典算法,以及实时寄存器分配的策略。 指令调度(Instruction Scheduling): 调整指令的执行顺序,以更好地利用处理器的流水线和并行能力。 介绍汇编器的作用,以及如何将生成的汇编代码翻译成机器码。 第三部分:高级话题与实践(深入理解与应用) 运行时系统:程序执行的环境支持 本章将探讨编译器生成的可执行程序如何在运行时环境中获得必要的支持。 内存管理: 堆(Heap)、栈(Stack)的使用,垃圾回收(Garbage Collection)机制的原理。 过程调用机制: 参数传递、栈帧(Stack Frame)的创建与销毁。 动态链接与加载: 如何处理对外部库的依赖。 特定语言的编译器设计考量 我们将讨论不同编程语言范式(如面向对象、函数式、命令式)对编译器设计的影响。 面向对象语言: 虚函数表(Virtual Table)、继承、多态的编译实现。 函数式语言: 闭包(Closure)、高阶函数、惰性求值(Lazy Evaluation)的编译挑战。 并发与并行: 线程、锁、并行执行模型相关的编译支持。 编译器开发工具与实践 介绍当前主流的编译器开发工具链,如GCC、LLVM等,并分析它们的架构和设计哲学。 LLVM的优越性: 深入探讨LLVM如何通过其优秀的中介表示(IR)和优化的强大能力,成为现代编译器开发的首选框架。 构建小型编译器实例: 引导读者使用现有的编译器框架(如LLVM)或从头开始,构建一个支持简单语言的编译器。 测试与调试: 强调编译器测试的重要性,以及常用的测试策略和调试技巧。 本书特色: 理论与实践并重: 紧密结合最新的理论研究成果与实际工程开发需求,提供可操作的指导。 循序渐进的结构: 从基础概念逐步深入,让读者能够清晰地理解编译过程的每一个细节。 丰富的示例: 配以大量的代码示例和图示,帮助读者直观理解抽象概念。 前沿技术的介绍: 重点关注LLVM等现代编译器架构,为读者提供面向未来的知识。 面向工程实践: 强调如何在实际项目中应用编译原理,培养解决实际问题的能力。 通过阅读本书,读者将能够: 深入理解编程语言是如何被机器执行的。 掌握编译器设计与实现的核心技术。 能够分析和改进现有编译器的性能。 为开发新的编程语言、优化工具或嵌入式系统打下坚实的基础。 本书适合计算机科学、软件工程专业的本科生、研究生,以及对编译器技术充满兴趣的广大开发者和研究人员。它将帮助您打开通往计算机底层工作机制的大门,深刻理解软件的本质。