编译程序对源程序进行处理并生成目标程序的典型流程,各阶段的具体作用如下:
- 词法分析:输入源程序(字符序列),依据程序设计语言的词法规则,对构成源程序的字符串进行扫描和分解,识别出一个个单词符号,例如将
for i=1 to 100 do分解为for(保留字)、i(标识符)、=(运算符)、1(整数)、to(保留字)、100(整数)、do(保留字)等单词。 - 语法分析:以词法分析得到的单词符号序列为输入,根据语言的语法规则(通常是上下文无关文法),判断这些单词能否组成合法的语句、分程序,最终构成完整的程序,本质上是针对描述该语言的文法进行句型分析,可通过推导序列、归约序列或语法树(如推导树)来描述分析过程,例如判断
i=1是否是合法的赋值语句。 - 语义分析:在语法分析的基础上,对高级语言程序中的声明语句和可执行语句进行语义检查与分析。对于声明语句,收集标识符的属性信息,包括总数(如简单变量、复合变量、过程等)、类型(如整型、实型、字符型等)、存储位置和长度等;对于可执行语句,构建标识符的语义词典(符号表)并构造语义树,以确定语法结构的语义信息,例如分析
int a,b;中a和b的类型为整型,为其分配存储位置和长度。 - 中间代码生成:将源程序翻译成一种介于源程序和目标程序之间的内部表示形式(中间代码),其形式简单、语义明确且不依赖于具体目标机器,例如Java编译时产生的字节码、三地址码(如说明类型
var x、运算类型x = y + z等)。中间代码的优点包括便于表达语义、便于优化、便于移植,能使编译程序的逻辑结构更清晰,可在中间代码上进行与机器无关的优化,减轻编译后端的工作强度。 - 代码优化:在不改变程序运行效果的前提下,对中间代码或目标代码进行等价变换,以生成更高效(时空效率更高,如代码更短、运行时间更短、占用空间更小)的代码。优化可在编译的多个阶段进行,主要对中间代码进行优化,分为局部优化(在基本块内,如基本块内的语句序列,有唯一入口和出口,语句执行次数相同)和全局优化(在基本块外),例如将
x = y + z; t = x;优化为x = y + z;,减少语句数量。 - 目标代码生成:将优化后的中间代码变换成特定机器上的目标代码,目标代码有三种形式:
- 汇编指令代码:需汇编器将其翻译成机器指令才能执行,例如生成8086汇编语言代码。
- 绝对指令代码:即机器语言程序,可直接执行,指令的地址部分是绝对地址,变量在存储单元的地址固定,常用于嵌入式程序设计,可直接烧录到芯片中。
- 可重新定位指令代码:代码中的地址是相对地址,能从内存中的任何位置开始装载,装载时将相对地址加上装入的起始地址得到绝对地址,支持模块化软件开发,可通过链接程序将各个独立开发和编译的程序模块连接成可执行程序,例如多个模块通过链接生成可执行程序。
总结来说,这个流程清晰地展示了编译程序如何将源程序逐步转换为可在特定机器上执行的目标程序,每个阶段都有其特定的任务和作用,共同确保了编译的正确性和高效性。
词法分析常见的方法主要有以下两种:
- 手工设计与实现词法分析器:
- 原理:程序员根据程序设计语言的词法规则,手动编写代码来实现词法分析的功能。具体来说,就是从源程序的字符序列中,按照词法规则逐个字符地扫描,识别出一个个单词符号,例如关键字、标识符、常数、运算符、界符等。
- 示例:对于一个简单的程序设计语言,如只包含关键字(如
if、else)、标识符(如变量名)、整型常数(如123)、运算符(如+、-)和界符(如;、(、))的语言,程序员可以编写代码,通过判断字符的类型(如字母开头的可能是关键字或标识符,数字开头的可能是常数等)来识别不同的单词。例如,当扫描到以字母开头的字符序列时,判断是否为关键字,如果不是则作为标识符;当扫描到以数字开头的字符序列时,识别为整型常数。 - 优点:可以根据具体的需求和语言特点进行灵活的设计和优化,对目标机器的资源使用可以进行更精细的控制。
- 缺点:实现过程相对繁琐,特别是对于复杂的程序设计语言,需要处理大量的词法规则和各种特殊情况,开发周期较长,且维护成本较高。
- 基于正规表达式与有限自动机的自动生成方法:
- 原理:利用正规文法与有限自动机(包括确定有限自动机(DFA)和非确定有限自动机(NFA))的等价性,首先用正规表达式来描述程序设计语言的词法规则,然后将正规表达式转换为NFA,再将NFA确定化为DFA,最后对DFA进行最小化,得到一个最简的DFA。基于这个最简的DFA,就可以自动生成词法分析器。
- 示例:以识别标识符(以字母开头的字母数字串)为例,其正规表达式可以表示为
[a-zA-Z]([a-zA-Z0-9])*。首先将这个正规表达式转换为NFA,然后通过子集构造法将NFA确定化为DFA,再对DFA进行最小化。最终得到的DFA就可以用来识别所有符合该规则的标识符。在生成词法分析器时,就可以根据这个DFA来编写代码,实现对标识符的识别。 - 优点:可以快速、高效地生成词法分析器,特别是对于复杂的词法规则,能够避免手工设计的繁琐过程,提高开发效率。同时,基于正规表达式和有限自动机的理论,生成的词法分析器具有良好的理论基础和正确性保证。
- 缺点:对于一些特殊的、复杂的词法规则,可能需要对正规表达式进行适当的扩展或调整,以满足实际需求。此外,自动生成的词法分析器可能在性能优化方面不如手工设计的灵活。
总结来说,手工设计方法灵活但开发繁琐,自动生成方法高效但对特殊规则处理可能受限,在实际应用中,可根据具体的语言特点、开发周期和性能要求等因素选择合适的词法分析方法,也可以结合两种方法的优点,例如先通过自动生成方法得到一个基本的词法分析器,再根据需要进行手工优化。