一个典型的编译器分成一下几个部分:
- Scanner:读入源代码,借助正则表达式完成词法分析,输出Tokens或报告错误的词法输入。如
goouojd
并是一个有效的英文单词,就会被报告为错误。 - Parser:读入Tokens,通过上下文无关文法完成语法分析,构建抽象语法树或报告错误的语法输入。如
Like your hair I
就不符合英语语法,会被报告为错误。 - Type Checker:读入抽象语法树,以属性文法进行语义分析并检查类型兼容性等,输出Decorated AST或报告错误的语义。如
Apples eat you
在语法上正确,但不可能有苹果会吃人,这是语义上的错误。 - Translater:读入Decorated AST,通过遍历Decorated AST将树型IR(AST)翻译为线型IR(通常是三地址码的形式)。然后可以通过静态分析进行机器无关的代码优化。
- Code Generator:读入线型IR,并根据指定的CPU指令集将机器无法直接执行的IR转换为机器可直接执行的机器代码。
AST:
- high-level and closed to grammar structure
- usually language dependent
- suitable for fast type checking
- lack of control flow information
即:
- 更接近于语法规定的结构
- 通常与语言有关
- 适于快速类型检查
- 没有控制流信息
IR:
- low-level and closed to machine code
- usually language independent
- compact and uniform
- contains control flow info
- usually considered as the basis for static analysis
即:
- 更接近于机器码
- 通常与语言无关
- 紧凑而通用
- 包含控制流信息
- 通常被视为静态分析的基础
总的来说,线型IR更适合静态分析。线型IR没有固定的定义,实际使用中常用三地址码。
在计算机领域,直接用英文常常更容易将概念表达清楚,如果有读者认为有更好的翻译,可以联系作者(邮箱或github issue都可以)
Definition: Each 3AC contains at most 3 addresses (name, constant, temporary)
定义:每一条三地址码最多包含3个地址(地址包括程序员显式定义的有名字变量,常量和临时变量) 一些形式
TBD