编译程序,编译过程。
编译程序的功能是把某高级语言的书写的源程序翻译成与之等价的目标程序(汇编语言或者机器语言)。汇编程序的工作过程可以分为6个阶段,如下图所示:
当然,下面只是简单的介绍下每一部分的实现逻辑,要做的工作,如果想要真正弄懂每一步的逻辑,小小的一篇博文篇幅是说不完的,比如文法、正规式、有限自动机、语法制导翻译等等。
1、词法分析
源程序可以简单地被看成是一个多行的字符串。词法分析阶段是编译过程的第一阶段,这个阶段的任务是对源程序从前到后(左到右)逐个字符的扫描,从中识别出一个个“单词”符号。“单词”符号是程序设计语言的基本语法单位,如关键字(或称保留字)、标识符、常数、运算符、分隔符等。词法分析程序输出的“单词”常以二元组的方式输出,即单词种别和单词自身的值。
2、语法分析
语法分析的任务是在词法分析的基础上,根据语言 的语法规则将单词符号序列分解成各类语法单位,如“表达式”“语句”和“程序”等。语法规则就是各类语法单位的构成规则。如果源程序中没有语法错误,语法分析后就能正确地构造出其语法树;否则指出语法错误。
词法分析和语法分析本质上都是对源程序的结构进行分析。
3、语义分析
语义分析阶段分析各语法结构的含义,检查源程序是否包含静态语义错误,并收集类型信息供后面的代码生成阶段使用。只有语法和语义都正确的源程序才能翻译成正确的目标代码。
4、中间代码生成
中间代码生成阶段的工作时根据语义分析的输出生成中间代码。“中间代码”是一种简单且含义明确的记号系统,可以由若干种形式,它们的共同特征是与具体的机器无关。最常用的一种中间代码是与汇编语言的指令非常相似的三地址码,其实现方式常采用四元式。四元式的形式为:
(运算符,运算对象1,运算对象2,运算结果)
例如:对于语句X:=Y+Z*60,可以生成以下四元式序列:
(inttoreal,60,-,t1)
(*,id3,t1,t2)
(+,id2,t2,t3)
(:=,t3,-,id1)
其中,t1,t2,t3是编译程序生成的临时变量,用于存放临时的变量结果。
语义分析和中间代码生成所依据的是语言的语义规则。
5、代码优化
由于编译器将源程序翻译成中间胆码的工作时机械的、按固定,模式进行的,因此生成的中间代码往往在时间上喝空间上有较大的浪费。当需要生成高效的目标代码时,必须进行优化。优化过程可以在中间代码生成阶段进行也可以在目标代码生成阶段进行。依据的原则是等价变换规则。
6、目标代码生成
目标代码的生成是编译器工作的最后一个阶段。这一阶段的任务是把中间代码变换成特定机器上的绝对指令代码、可重定位的指令代码或者汇编指令代码,这个阶段的巩固走与具体的机器密切相关。
7、符号表的管理
符号表的作用是记录源程序中各个符号的必要信息,以辅助语义的正确性检查和代码生成,在编译过程中需要对符号表进行快速有效地查找、插入、修改和删除等操作。符号表的建立可以始于词法分析阶段,也可以放到语法分析阶段和语义分析阶段,但是符号表的使用有时会延续到目标代码的运行阶段。
8、出错处理
用户编写的源程序会不可避免地有一些初五,这些错误大致可分为静态错误和动态错误,动态错误也称动态语义错误,它们发生在程序运行时,例如变量取零时做除数。静态的话就是在编译阶段就可以检测出来的错误,比如括号缺失等等。
在编译时发现程序错误后,编译程序应采用适当的策略修复它们,使得分析过程能够继续下去,以便在一次编译过程中尽可能多地找出程序中的错误。
对于编译过程的各个阶段,在逻辑上可以把它们划分为前端和后端两部分。前段包括从词法分析到中间代码生成各个阶段的工作,后端包括中间代码优化和目标代码的生成、优化等阶段。这样,以中间代码为分水岭,把编译器分为了与机器有关的部分和与机器无关的部分。如此一来,对于同一种程序设计语言和编译器,开发出一个前端后,就可以针对不同的机器开发相应的后端,前、后端有机结合后就形成了该余元的一个编译器。当语言改动时,只会设计前端部分的维护。
补充
词法分析的基础是正规式和优先自动机的理论。构造词法分析器的一般步骤如下:
- 用正规式描述语言中的单词构成规则。
- 为每一个正规式构造一个NFA(不确定的有限自动机),它识别正规式所表示的正规集。
- 将构造出的NFA转换成等价的DFA(确定的有限自动机)
- 对DFA进行最小化处理,使其最简。
- 从DFA构造词法分析器
目前应用最广泛的静态语义分析方法是语法制导翻译。
常用的中间代码有:后缀式(逆波兰式)、三元式、四元式和树等形式。树和后缀表示形式适用于解释器,而编译器多采用与机器指令格式比较接近的四元式形式。
总结
再次发出感叹,果然是一环扣一环,没有文法,没有正规式没有后面的各种NFA,DFA,根本就不可能后后面的代码生成,而且,没有门技术都可以研究很久很久。作为一个java高级语言开发者,了解就好。