1.1 语言处理器

处理器 Compilers Interpreters
执行模式 将源代码翻译成目标语言编写的程序后再执行输入,产生输出
image.png
不翻译,直接利用输入执行源程序


image.png
执行速度 远快于解释器 较慢
错误诊断 弱于解释器 更好,因为逐个语句地执行源程序
语言代表 Python
优点 经过“翻译”后,目标程序的执行速度更快

- 逐句执行,对源程序的错误诊断效果更好
- 更好的支持多平台,只需要不同平台的不同解释器就能跨平台的运行源程序

混合编译的语言: Java

  1. Java程序先被compiled成字节码(bytecode)作为中间形式
  2. 之后由不同平台的JVM将其interpret,直接根据输入产生输出,从而保证了Java程序可以跨平台执行

1.2 编译器的结构

编译主要分为7个阶段
image.png

词法分析

Lexical analysis,也称为scanning
输入: 源程序的字符流
转换: 有意义的词法单元(token),形式如下:<token-name, attribute-value>
image.png

语法分析

Syntax analysis,也称parsing
输入: token
输出: 分析树parse tree或语法树syntax tree
image.png

语义分析

| Semantic analysis
输入: 语法树和符号表中信息
执行:
- 类型检查: 比如数组下标一定为int
- 类型转换: 比如int和float一起运算,int->float
👉右图即为检查过程 | image.png | | —- | :—-: |

中间代码生成

| Intermediate code generation
输入: 通过了syntax analysis和semantic analysis的源程序
输出: 明确的低级或类机器码的表示
👉右图以三地址码为例,每条指令最多三个运算分量,一个运算符 |
image.png | | —- | :—-: |

(机器无关)优化

| machine-independent optimization
- 机器无关的代码优化,只和源码有关
输入: 中间代码
输出: 优化后代码
👉右图进行常数折叠(机器无关) | image.png | | —- | :—-: |

代码生成

Code generation
输入: 中间代码
执行: 例如为变量选择寄存器或内存位置
输出: 可完成任务的机器指令(目标代码)
image.png

(机器相关)优化

| machine-dependent optimization
- 机器相关的代码优化,和目标代码有关
输入: 目标代码
输出: 优化后代码
👉右图进行指令优化 | image.png | | —- | :—-: |


1.3 其余概念

前端/后端

根据当前操作的依赖,可把编译过程分为前后端

前端 后端
取决于”源代码”,包括:
- 词法分析
- 语法分析
- 语义分析
- 中间代码生成
- 机器无关优化
取决于”目标语言”,包括:
- 代码生成
- 机器相关优化

前后端中介: “中间代码” |

符号表

记录变量名和与之相关信息,如”类型,作用域,参数类型,参数数量,传参方法,返回类型”

遍(Pass)

将源码生成最终目标代码前的多次重复称为遍(pass),多个编译步骤组合成一遍,每遍一个输入文件,一个输出文件,大多数编译器使用不只一遍(比如前端步骤可以组合为一趟,后端步骤组合为一遍)