关于编译器

编译器本质就是一个翻译器,作用是将一个高级语言翻译成计算机可以识别的机器语言,如今的编译器都是分层架构,分层可以增加各层之间的独立性。golang 编译器分为前端和后端

编译器种类:

  • 本地编译器:可以编译生成所在计算机系统相同平台可执行的目标代码
  • 交叉编译器:可生成在其他平台上可执行的目标代码

golang 编译器主要编译阶段:

1.词法分析 => 2.语法分析 => 3.类型检查 => 4.生成 SSA 中间代码 => 5.生成机器代码

词法分析

golang 通过词法分析器程序将 golang 源代码文件中的字符串序列化成 Token 序列,或者称为标记序列,便于编译器后面的进一步进行语法分析

语法分析

golang 通过语法分析器将刚才生成的标记序列按照 golang 定义好的语法进行整理,构建出最后的抽象语法树 AST

每一个抽象语法树 AST 都对应一个单独的 golang 源码文件。AST 中包含有当前文件所属包名,定义的常量,结构体和函数等信息,方便后续调试

类型检查

golang 是静态类型语言。在类型检查时候(还会进行 AST 细节优化),编译器通过遍历所有 AST 语法树上的结点,会对 AST 中定义和使用的类型信息进行检查,类型检查的主要内容有:

  • 常量,类型和函数名称和函数类型
  • 变量赋值和初始化
  • 函数和闭包的主体
  • 哈希键值对类型
  • 导入函数
  • 外部声明

一旦检查出语法树上有一处类型错误,编译器就会终止编译过程并且抛出错误

生成 SSA 中间代码

当类型检查没有发现 AST 语法树上的错误时候,就可认定 golang 源代码没有语法错误,golang 编译器使用 SSA 生成中间代码,中间代码即 golang 汇编语言,SSA 生成中间代码的过程中能对代码进行优化

这样的汇编代码可以很好的实现跨平台运行,golang 汇编语言基于 Plan 9 汇编,并不直接提现机器底层硬件特性

生成机器代码

golang 会结合当前使用的硬件架构,使用 golang 目录中的特定的 CPU 的包将 golang 汇编语言转为成机器代码,所以 golang 能在下面不同指令集的 CPU 上运行的原因

  • AMD64
  • ARM
  • ARM64
  • MIPS
  • MIPS 64
  • ppc 64
  • s390x
  • x86
  • WASM
总结

1.词法分析 => 2.语法分析 => 3.类型检查 => 4.生成 SSA 中间代码 => 5.生成机器代码

1.生成标记序列->2.通过标记序列生成抽象语法树 AST->3.检查所有抽象语法树 AST 上的结点->4.使用 SSA 将语法树 AST 转为中间代码(汇编)->5.汇编语言专为机器语言