认识
一、认识
编译的基本任务就是将源语言程序
翻译成等价的目标语言程序
,编译的整个工作流程如下:
- 1. 词法分析
- 2. 语法分析
- 3. 语义分析
- 4. 生成中间代码
- 5. 中间代码优化
- 6. 生成目标代码
- 7. 优化目标代码
二、词法分析 Lexer
词法分析 是一个分词断句
+判断词性
的过程,将源代码的字符流转成符号流(英文Token
,也叫词法单元
,数学上称为元祖
)。类似于词性标注,每个符号是一个元祖,元祖应该至少包括一个字符串和一个词性描述。
词法分析符号类型
- Keyword(关键字)
- Variable(变量)
- Operator(操作符)
- Bracket(括号)
- String(字符串)
- Float(浮点数)
- Boolean(布尔)
三、语法分析 Parser
语法分析 将词法分析中得到的Token
转化为抽象语法树
四、语义分析 Semantic
提示
并不是所有的编译器都有语义分析,比如 Babel
就没有。不过对于其它大部分编程语言(包括 TypeScript
)的编译器来说,是有语义分析这一步骤的,特别是静态类型语言
,类型检查
就属于语义分析的其中一个步骤
语义分析阶段 编译器开始对 AST
进行一次或多次的遍历,检查程序的语义规则
。主要包括声明检查
和类型检查
。 语义检查的步骤和人对源代码的阅读和理解的步骤差不多,一般都是在遍历 AST
的过程中,遇到变量声明
和函数声明
时,则将变量名--类型
、函数名--返回类型--参数数量及类型
等信息保存到符号表
里,当遇到使用变量
和函数
的地方,则根据名称
在符号表
中查找
和检查
,查找该名称
是否被声明
过,该名称的类型是否被正确的使用
等等。语义检查时,也会对语法树进行一些优化,比如将只含常量的表达式先计算出来
语义分析完成后,源代码的结构解析就已经完成了,所有编译期错误都已被排除,所有使用到的变量名
和函数名
都绑定到其声明位置
(地址)了,至此编译器可以说是真正理解了源代码,可以开始进行代码生成和代码优化了。