言中对英文单词的拼写是十分类似的。扫描程序还可完成与识别记号一起执行的
其他操作,例如,可将相应的记号输入到对应的符号表中。
(2) 语法分析程序(parser)
语法分析程序从扫描程序中获取记号形式的代码,并完成定义程序结构的语
法分析(syntax analysis),根据语言的语法规则将上阶段产生的单词串分解成各
类语法单位(如表达式、语句、子过程等),这与自然语言中关于某篇文章的句
子的语法分析类似。语法分析定义了程序的结构元素及其关系。通常将语法分析
的结果表示为分析树或语法树。
(3) 语义分析程序(semantic analyzer)
程序的语义就是它的“意思”,程序如何运行以及运行结果都由它的语义来决
定。大多数程序设计语言具有在执行之前被确定语义的特征,这些特征不容易用
语法结构表示,更无法用词法分析程序进行分析,这些特征被称为静态语义。语
义分析程序的职责就是分析这样的语义,为代码生成阶段搜集相关的语义信息。
一般程序设计语言的典型静态语义有声明和类型检查。而在程序执行阶段才能确
定的程序特性称为动态语义,语义分析程序无法对这类特性做出分析。语义分析
程序还要计算被称为属性(attribute)的程序固有信息,如数据类型、值等。语义
分析程序通常将计算后的属性值添加到语法树中(也可将属性添加到符号表中)。
(4) 源代码优化程序(source code optimizer)
完善的编译器通常包括许多代码改进和优化步骤。这些优化和改进一般是在
语义分析之后完成的。在语法分析和语义分析的基础之上,将源程序变换为等价
的中间代码。所谓中间代码,是指一种结构简单、含义明确、形式多样化的记号
系 统 , 它 比 较 容 易 能 转 换 为 目 标 代 码 。 优 化 程 序 将 源 代 码 以 中 间 代 码
(intermediate code)的形式输出,进而完成对源代码的相应优化处理,目的是使
将来生成的目标代码更为高效(即省时间、省空间)。
(5) 代码生成器(code generator)
这是编译的最后必备阶段,它将中间代码(或经优化后的中间代码)转换成
特定机器上的绝对指令代码或可重新定位的指令代码或汇编指令代码。由于该阶
段的工作与硬件系统结构和机器指令含义有关,涉及到硬件系统功能部件的运用
机器指令的选择、各种数据的存储空间分配以及寄存器调度等,也就是说目标机
器的特性成为了主要因素,所以这个阶段的工作相当复杂。正是出于这点考虑,
本实验设计选择了面向 MM(Mini Machine)机的汇编指令代码作为 MINI C 编译
器的目标代码。
(6) 目标代码优化程序(target code optimizer)
在这个阶段中,编译器尝试着改进由代码生成器生成的目标代码。这种改进
包括对编址模式的选择、提高性能、将速度慢的指令更换成速度快的以及删除多
余的操作等。
除了这 6 个阶段,编译器通常还包含一张符号表和访问该表的若干例程,以
及针对编译过程中发现的各种错误进行检查和处理的错误处理程序,它们在编译
过程的所有阶段都会使用到。
上述编译过程的阶段划分只是一个典型模式,事实上并非所有的编译程序都
分成这 6 个阶段,有些编译程序并不生成中间代码,有些编译程序并不进行优化,