一:词法与语法分析
- 意义:解析源代码文件,将文件中字符串序列转换成Token序列
- 过程:编译器首先对源代码文件进行词法和语法分析,将源代码文件中的字符串序列转换成Token序列,并生成抽象语法树(AST)。词法解析器负责将源代码转换成Token,而语法解析器将Token序列组织成语法正确的结构,生成AST。AST包含了当前文件的包名、常量、结构体和函数等信息。
- 执行词法分析的程序称为词法解析器(lexer)
- 语法解析的结果就是抽象语法树(AST)
- 每个AST都对应一个单独的Go语言文件,这个抽象语法树中包括当前文件属于的包名,定义的常量,结构体和函数等
- 如果发生错误,被语法解析器发现并将消息打印在标准输出上,编译过程直接中止
- Go语言早期用lex做词法分析,后续还是使用Go语言实现词法分析器,自己写的词法分析器分析自己
二:类型检查和AST转换
- 编译器对语法树中定义和使用的类型进行检查
- 遍历抽象节点树,保证当前节点上不会出现类型错误
- 不仅对类型进行检查,还会对内置函数进行展开和改写,比如
make关键字在这个阶段会根据子树的结构被替换成makeslice或者makechan等函数
三:通用SSA(静态单赋值)生成
- 使用SSA特性,分析代码中无用变量和片段进行优化
- 类型检查之后,就对Go语言项目全部函数进行编译,生成中间代码
- 关键字和内置函数的功能其实是由语言的编译器和运行时共同完成的
- 机器代码生成
- 根据机器不同,生成不同的机器码