第1章 引论

1.1 什么是编译程序

编译程序又称编译器,是语言的翻译器,将高级语言的源程序翻译成低级语言的目标程序,使编程者不必考虑与机器有关的细节。

1.2 编译过程和编译程序的结构

1.2.1 编译过程概述

词法分析的任务是从左到右读入源程序的每个字符,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也叫单词符号或符号)。单词是具有独立意义的最小语法单位,如:标识符、保留字(关键字或基本字)、算符、界符、常数等。

语法分析的任务是依据语言的语法规则,确定源程序的输入串是否构成一个语法上正确的程序。语法是由程序语言基本符号组成程序中各个语法成分的一组规则。一般语法规则是由单词符号构成语法成分的规则;词法规则是由基本符号构成的符号书写规则。

语义分析的任务是审查源程序有无语义错误,为代码生成阶段收集类型信息。 主要功能:类型检查、报语义错误、类型转换等。语义是程序设计语言中按语法规则构成的各个语法成分的意义。静态语义是编译时刻即可确定的语法成分含义;动态语义是运行时刻才能确定的语法成分含义。

中间代码生成的任务是在语法和语义分析之后,将源程序变成一种”内部表示形式“。

中间代码:一种结构简单、含义明确的记号系统。

特征:结构简单、含义明确;复杂性介于源语言和机器语言之间;容易生成;容易将它翻译成目标代码。

四元式:(运算符,运算对象1,运算对象2,结果)

代码优化的任务是对中间代码进行变换或改造,使之更为高效(时间、空间)。

目标代码生成的任务是把中间代码变换成特定机器上的绝对指令代码或可重定位的机器指令代码或汇编指令代码。

特点:与硬件系统结构和指令含义有关,涉及到硬件系统功能部件的运用、机器指令的选择、各种数据类型变量的存储空间分配以及寄存器和后缓寄存器的调度等;高级语言到低级语言转换是基于语义的等价变换,不是结构上的变换。

表格管理的任务是用于保存源程序的各种信息。因为上述各阶段工作均需要查找、更新、构造表格。

出错处理的任务是报告源程序中错误的性质、地点,将错误所造成的影响限制在尽可能小的范围。有些编译程序还可以自动纠错。一个程序是正确的,说明书写正确(合乎语法规则),含义正确(合乎语义规则)。

多数实用的编译程序都采用以上几个阶段的工作过程,有些编译程序没有“中间代码生成”和“代码优化”。

1.2.2 编译程序的结构

1.2.3 编译阶段的组合

前端:主要依赖于源语言而与目标机器无关的编译阶段。如:词法分析、语法分析、语义分析、中间代码生成、部分代码优化、与前端有关的出错处理工作和表格管理工作。

后端:依赖于目标机而一般不依赖于源语言,只与中间代码有关的编译阶段。如:目标代码生成,以及相关出错处理和表格处理。

遍(趟):对源程序或其等价的中间语言程序从头到尾扫视并完成规定任务的过程。每一遍扫视可完成编译的一个阶段或多个阶段工作。

多遍编译:占内存少,逻辑结构清晰,耗时长。

一遍编译:占内存多,逻辑结构不清晰,耗时短。

1.3 解释程序和一些软件工具

1.3.1 解释程序

解释程序接受高级语言程序,并立即运行这个源程序。例如:BASIC语言解释程序,LISP解释程序,SQL解释程序,Java语言中的BYTECODE解释程序。

编译与解释的根本区别:是否生成目标代码。

解释程序的优点是可移植性较好;缺点是速度慢,空间开销大

有些语言既有编译程序,又有解释程序。

1.3.2 处理源程序的软件工具

语言的结构化编辑器

– 正文编辑、修改

– 对源程序正文进行分析(检查用户输入是否正确、自动提供关键字、检查括号的匹配情况)

语言程序的调试工具

– 了解程序执行的结果与编程人员的意图是否一致

– 允许用户一行一行跟踪程序,查看变量值的变化

程序格式化工具

– 分析源程序,并使程序结构变得清晰可读(如缩排)

语言程序测试工具

– 静态分析器:不运行源程序,就可以发现其中潜藏的错误或异常。

– 动态分析器:对源程序进行分析,把记录和显示程序执行轨迹的语句或函数插入源程序,将运行结果与期望结果进行比较和分析。

程序理解工具

– 对程序进行分析,确定模块间的调用关系,并画出控制流程图。

高级语言之间的转换工具

– 将一种高级语言程序转换成另一种高级语言程序

1.4 程序设计语言范型

一、强制式语言(过程式语言、命令式语言)

由一系列的语句组成,每个语句的执行引起若干存储单元中值的改变。如:C,Fortran,Pascal。

二、函数式语言(应用式语言)

从前面已有的函数出发构造出更复杂的函数。Function n(…Function 2(Function 1(data))…)。如:ML,LISP

三、基于规则的语言(基于逻辑的语言)

检查一定的使能条件,当它满足时,则执行适当的动作。条件$\rightarrow$动作。如:PROLOG

四、面向对象语言

提供抽象数据类型,支持封装性、继承性和多态性。如:Ada,C++,Java。