Hello World
的例子开始:hello.go
文件就是一个字节序列了,每个字节代表一个字符。man ascii
:文本文件
,其他文件被称为二进制文件
。编译
和运行
的过程。src/cmd/compile
路径下,链接器源码位于 src/cmd/link
路径下。.s
作为文件后缀。词法分析(lexical analysis)是计算机科学中将字符序列转换为标记(token)序列的过程。进行词法分析的程序或者函数叫作词法分析器(lexical analyzer,简称lexer),也叫扫描器(scanner)。词法分析器一般以函数的形式存在,供语法分析器调用。
.go
文件被输入到扫描器(Scanner),它使用一种类似于有限状态机
的算法,将源代码的字符系列分割成一系列的记号(Token)。c := s.getr()
获取下一个未被解析的字符,并且会跳过之后的空格、回车、换行、tab 字符,然后进入一个大的 switch-case
语句,匹配各种不同的情形,最终可以解析出一个 Token,并且把相关的行、列数字记录下来,这样就完成一次解析过程。当前包中的词法分析器 scanner 也只是为上层提供了 next 方法,词法解析的过程都是惰性的,只有在上层的解析器需要时才会调用 next 获取最新的 Token。
表达式
为结点的语法树
。slice[i] = i * (2 + 6)
,得到的一棵语法树如下:+
号表达式缺少一个操作数等。语法分析是根据某种特定的形式文法(Grammar)对 Token 序列构成的输入文本进行分析并确定其语法结构的一种过程。
*
号的两棵子树如果是两个指针,这是不合法的,但语法分析检测不出来,语义分析就是干这个事。类型检查是 Go 语言编译的第二个阶段,在词法和语法分析之后我们得到了每个文件对应的抽象语法树,随后的类型检查会遍历抽象语法树中的节点,对每个节点的类型进行检验,找出其中存在的语法错误。在这个过程中也可能会对抽象语法树进行改写,这不仅能够去除一些不会被执行的代码对编译进行优化提高执行效率,而且也会修改 make、new 等关键字对应节点的操作类型。
三地址码
是这样的:Go 语言的主程序在执行时会调用 runtime 中的函数,也就是说关键字和内置函数的功能其实是由语言的编译器和运行时共同完成的。中间代码的生成过程其实就是从 AST 抽象语法树到 SSA 中间代码的转换过程,在这期间会对语法树中的关键字在进行一次更新,更新后的语法树会经过多轮处理转变最后的 SSA 中间代码。