编译器执行原理

#

词法分析器 

词法分析器作用,是“分词”,将代码“一段一段“的切割,生成计算机可识别的代码,这些代码叫做“词法单元”。

var a = 3; // 会被解析器器识别为 var; a; =; 3

语法分析器

💡JavaScript语法分析器阶段,如果发现词法无法构造,就会提示语法错误、并结束构建语法树

#

语法分析器的作用,是将词法单元转换成AST抽象语法树“词法分析器”到“语法分析器”这个步骤是连续的。也就是说,“语法分析器”不需要等待“词法分析器”完成工作后在进行转换。“语法分析”的过程,就是把“词法分析”的结果生成“语法树”,且最终存储在内存中。

#

代码编译过程中的数据结构有两种,语法树”、符号表

  • 语法树:程序语法的树表示,用来生成中间代码。
  • 符号表:程序中用来存储所有符号的表,包括所有的字符串变量、直接量字符串、函数、类等。

语义检查器

语义检查器的作用,是负责对代码进行进一步的分析,以确保代码的逻辑正确性和一致性,例如类型匹配、参数匹配等。在强类型语言中,这种类型检查会更加严格,因为类型系统在编译期间会进行静态类型检查,而在弱类型语言(例如 JavaScript)中,类型检查通常是动态的,在运行时发生,所以JavaScript没有这个步骤。

中间码生成器 

中间码生成器的作用,是将“AST抽象语法树”转换成“中间码” 。以下罗列中间码带来的好处👍:

  • 中间码与平台架构无关,中间码可以为多种环境的目标机目标代码服务
  • 生成中间码,可以进行与平台架构无关的代码优化,提高目标代码质量。
  • 源程序映射成中间代码表示,再映射成目标代码的工作分在几个阶段进行,使编译算法加清晰。 对于中间语言,要求其不但与机器无关,而且有利于代码生成。

代码优化器

代码优化器的作用,是精简优化AST抽象语法树。以下罗列代码优化器步骤常见的优化点:

  • 🙋‍♂️ 常量折叠Constant Folding):

           计算常量表达式的值,并用结果替换表达式。

  • 🙋‍♂️ 死代码消除Dead Code Elimination

           删除不会被执行的代码,例如无法达到的分支或者未使用的变量。

  • 🙋‍♂️ 循环优化Loop Optimization

           优化循环结构,例如循环展开、循环不变式外提等。

  • 🙋‍♂️ 内联函数Function Inlining

          将函数调用处用函数体替换,减少函数调用开销。

  • 🙋‍♂️ 数据流分析Data Flow Analysis

          分析数据在程序中的流动,以便进行进一步的优化。

代码生成器

代码生成器的作用,是生成可执行的目标代码,通常代码有两种,机器码字节码

  • 🤖 机器码Machine Code

          机器码是直接针对特定硬件架构的二进制指令,可以直接在该硬件上执行。生成机器码的编译器通常称为本地编译器,因为它们生成的代码可以在本地硬件上运行。

  • ⚙️ 字节码Bytecode

          机器码是一种中间形式,通常不是直接由硬件执行的。相反,它通常由一个虚拟机(如Java虚拟机)来解释或者编译成机器码。字节码的好处是它可以跨平台运行,因为它不依赖于特定的硬件架构,而是依赖于虚拟机的实现。例如,Java编译器会将Java源代码编译成字节码,然后在Java虚拟机上执行。