跳到主要内容

认识

一、认识


编译的基本任务就是将源语言程序翻译成等价的目标语言程序,编译的整个工作流程如下:

  • 1. 词法分析
  • 2. 语法分析
  • 3. 语义分析
  • 4. 生成中间代码
  • 5. 中间代码优化
  • 6. 生成目标代码
  • 7. 优化目标代码

二、词法分析 Lexer


词法分析 是一个分词断句+判断词性的过程,将源代码的字符流转成符号流(英文Token,也叫词法单元,数学上称为元祖)。类似于词性标注,每个符号是一个元祖,元祖应该至少包括一个字符串和一个词性描述

词法分析符号类型

  • Keyword(关键字)
  • Variable(变量)
  • Operator(操作符)
  • Bracket(括号)
  • String(字符串)
  • Float(浮点数)
  • Boolean(布尔)

三、语法分析 Parser


语法分析词法分析中得到的Token转化为抽象语法树

四、语义分析 Semantic


提示

并不是所有的编译器都有语义分析,比如 Babel 就没有。不过对于其它大部分编程语言(包括 TypeScript)的编译器来说,是有语义分析这一步骤的,特别是静态类型语言类型检查就属于语义分析的其中一个步骤

语义分析阶段 编译器开始对 AST 进行一次或多次的遍历,检查程序的语义规则。主要包括声明检查类型检查语义检查的步骤和人对源代码的阅读和理解的步骤差不多,一般都是在遍历 AST 的过程中,遇到变量声明函数声明时,则将变量名--类型函数名--返回类型--参数数量及类型等信息保存到符号表里,当遇到使用变量函数的地方,则根据名称符号表查找检查,查找该名称是否被声明过,该名称的类型是否被正确的使用等等。语义检查时,也会对语法树进行一些优化,比如将只含常量的表达式先计算出来

语义分析完成后,源代码的结构解析就已经完成了,所有编译期错误都已被排除,所有使用到的变量名函数名都绑定到其声明位置(地址)了,至此编译器可以说是真正理解了源代码,可以开始进行代码生成和代码优化了。

五、生成中间代码


六、中间代码优化


七、生成目标代码


八、优化目标代码


参考资料


JavaScript 编译原理