编译概览

词法分析

词法分析器读入一个个的字符,并将他们组合成单词,也就是程序中最小的有意义的单位。词法分析器的主要作用就是为了简化分析器的工作,它能减小输入的规模并删除额外的字符。词法分析器通常还要删去注释,如果需要就生成一个表格,给各个单词做好行列位置标记,以便后续阶段能更容易生成好的诊断信息。

语法分析

语法分析阶段会将词法分析阶段得到的单词组织为一棵语法分析树,这棵树用程序的各个组成部分标明其高层结构。
这些部分的组合方式是通过一组可能递归的规则定义的,这样的一组规则称为一个上下文无关文法
我们说这种上下文文法定义了语言的语法形式,因此分析过程也就是做语法分析。

在词法分析和语法分析的过程中,编译器需要检查程序里的所有单词是否都构造良好,单词序列是否符合上下文无关文法所定义的语法。
任何畸形的单词都应导致扫描器产生错误信息,任何不符合语法的单词序列应该导致语法分析器产生错误信息。

语义分析

语义分析也就是确定程序的意义。
编译的语义分析阶段需要识别出什么时候同一单词的多个出现引用的是同一个程序实体,并且要保证这些使用的相容性。
在大部分语言里,语义分析器需要跟踪标识符和表达式的类型,这既是为了验证使用的相容性,也用于指导后面阶段中的代码生成。
为了支持所需的工作,语义分析器通常构造并维护着一个符号表数据结构,符号表把每个标识符映射到有关它的已知信息。这些信息包括各个标识符的类型信息、内部结构,以及作用域。
利用这一符号表,语义分析器就能贯彻执行许多语义分析规则,这些规则是上下文无关文法和语法分析树无法表示的。
在许多编译器里,语义分析的工作通过一组语义动作子程序的形式表示,当语法分析器识别出自己当时到达了某个产生式里的一个特定点时,就会去调用其中的某个子程序。
当然,并不是所有语义规则都能在编译时检查,能在编译时检查的称为语言的静态语义,必须在运行时检查的就称为语言的动态语义。
当编译器无法静态地贯彻某些规则时,通常它就会产生一些代码,让这些代码在运行中执行适当的检查,如果某个检查失败,这个程序就会终止或者产生一个异常。
不幸的是,有些规则的贯彻可能带来极高的、根本无法接受的代价,或者根本就是不可能贯彻的,这时语言的实现有可能根本不去检查他们。

语法分析树有时也称为具体语法树,因为这种树中的一切都是明示的,完全而又具体,显示了如何根据相应上下无关文法推导出特定的单词序列。
在我们知道了一个单词序列为合法之后,后续的编译阶段就不再需要语法分析树上的许多信息了。

在静态检查语义规则的过程中,语义分析器通常还同时把这种语法分析树转换为一颗抽象语法树,删除树内部的大部分人为结点。
语义分析器还为剩下的结点标注有用的信息,例如加入从标识符到对应符号表项的指针。附在特定结点上的标注被称为它的属性。

中间代码生成

在许多编译器里,带标注的语法树就是从前端传递到后端的中间形式,而在另一些编译器里,语义分析器最后还要遍历这棵树,生成某种另外的中间形式。
这一形式通常类似于某种特别简单的理想机器的汇编语言。
对于一组相关的编译器,几种语言的前端和为几种机器服务的后端可能共享着同一种中间形式。

目标代码生成

编译器的代码生成阶段把中间形式翻译到目标语言。
有了语法树中所包含的各种信息,生成正确的代码一般来说并不是很困难的工作。为了生成汇编或者机器语言,代码生成器需要整个符号表,给每个变量指定位置;还要遍历语法树,生成对这些变量的装入和保存动作,插入适当的算术运算、检测和分支。

代码生成器常常把符号表也保存起来,以便后面的符号排错程序使用。
例如可以将符号表包含在目标代码里,作为注释或者其他非执行的部分。

专门针对机器的代码改进

代码改进通常被说成是优化,虽然从所有绝对的意义上看,它都很难将任何东西做成最优的。这是编译过程中一个可选的阶段,其目标就是把程序变换到一个新版本,该版本能更有效地计算出同样的结果——速度更快或者使用的更少的存储,或者两方面都更好。

有些改进是与机器无关的,可以在中间形式上通过一些变换完成。
另外一些改进则需要深入了解目标机器(了解目标语言里的程序如何执行),必须通过对目标语言的变换完成。
这样,代码改进将表现为编译过程里的另外两个阶段,一个在刚刚做完语义分析和中间代码生成之后,另一个在做完目标代码生成之后。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值