《深入Python虚拟机》笔记5-编译器基本知识(非原文内容)

编译程序是较为复杂的翻译程序

  • 需要对源程序进行分析(Analysis),识别源程序的结构信息,理解源程序的语义信息, 反馈出错的语法、语义信息
  • 根据分析结果进行综合(Synthesis),生成语义上等价于源程序的目标程序

编译程序通常是从较高级语言的程序翻译至较低级语言的程序,例如:

  • c代码被翻译成汇编语言
  • c++代码被翻译成c代码
  • java代码被翻译成字节码

经编译程序生成的目标语言程序可以在支持该目标语言的虚拟机上执行,例如:

  • 汇编代码通过汇编程序生成目标代码,目标代码和库代码通过链接程序生成可执行的目标代码,最后在汇编语言虚拟机上执行。
  • c代码通过c编译器,经过若干步骤,最后在c语言虚拟机上执行
  • 字节码通过字节码解释程序,经过若干步骤,最后在java虚拟机上执行

编译程序的工作逻辑上可分为两个阶段

– 分析(Analysis)阶段: 理解源程序,挖掘源程序的语义

– 综合(Synthesis)阶段:生成与源程序语义上等价的目标程序

编译程序的前端和后端:

– 前端(Front End):实现分析阶段的任务(含中间代码生成和优化),传统上,前端不涉及目标程序及其虚拟机的任何信息

– 后端(Back End): 实现综合阶段的任务(目标代码生成和优化),后端的设计与目标程序及其虚拟机密切相关

典型编译程序的逻辑过程

– 前端:字符流->词法分析->单词流->词法分析->语法分析树->语义分析和中间代码生成->中间表示->中间代码优化->优化的中间表示

– 后端:优化的中间表示->目标代码生成->目标代码->目标代码优化->优化的目标代码

词法分析:扫描源程序字符流,识别出有词法意义的单词,返回单词的类别和单词的值,或词法错误信息

语法分析:从左至右扫描构成源程序的单词流,返回语法分析结果(语法分析树,推导或归约过程)或语法错误信息

语义分析:对语法分析后的程序进行语义分析,不符合语义规则时给出语义错误信息

符号表:收集每个名字的各种属性用于语义分析及后续各阶段

中间代码生成:等价于源程序的各类中间表示形式,其作用主要是建立源语言和目标语言之间的桥梁,避开二者之间较大的语义跨度,利于相关分析和综合过程中各遍的实现

中间表示的形式有:抽象语法树(AST), 三地址码(TAC)

解释程序(Interpreter)

– 不产生目标程序文件

– 不区别翻译阶段和执行阶段

– 翻译源程序的每条语句后直接执行

– 程序执行期间一直有解释程序守候

– 常用于实现虚拟机

预处理程序(Preprocessor)

– 支持宏定义(Macro definition): 如C源程序中 #define 行的处理

– 支持文件包含(File inclusion): 如C源程序中 #include 行的处理

– 支持其他更复杂的源程序扩展信息

汇编程序(Assembler)

– 翻译汇编语言程序至可重定位的(Relocatable) 机器语言程序

装入和连接程序(Loader and Link-editor)

– 装入程序对可重定位机器语言程序进行修改, 将相对地址变换为机器绝对地址

– 连接程序合并多个可重定位机器语言程序文件到同一个程序

– 装入和连接程序产生最终可执行的机器语言程序