golang快速入门[4]-go语言如何编译为机器码

本文详细介绍了Go语言的编译过程,包括词法分析、语法分析、类型检查、SSA优化、代码优化和机器码生成。通过分析Go编译器的各个阶段,阐述了Go代码如何转化为可执行的机器码。此外,文章还讨论了Go编译速度相对较快的原因。
摘要由CSDN通过智能技术生成

前文

package main
import "fmt"
func main() {
    fmt.Println("Hello, world")
}
  • 在本文中,我们将介绍初学者比较关心的话题:go语言如何编译为机器码
  • 本文的目标是希望读者对go语言的编译过程有一个全面的理解
  • 一段程序要运行起来,需要将go代码生成机器能够识别的二进制代码
  • go代码生成机器码需要编译器经历:
    词法分析 => 语法分析 => 类型检查 => 中间代码 => 代码优化 => 生成机器码
  • Go语言的编译器入口是 src/cmd/compile/internal/gc 包中的 main.go 文件,此函数会先获取命令行传入的参数并更新编译的选项和配置
  • 随后就会开始运行 parseFiles 函数对输入的所有文件进行词法与语法分析
func Main(archInit func(*Arch)) {
    // ...

    lines := parseFiles(flag.Args())
  • 接下来我们将对各个阶段做深入介绍

词法分析

  • 所有的编译过程都是从解析代码的源文件开始的
  • 词法分析的作用就是解析源代码文件,它将文件中的字符串序列转换成Token序列,方便后面的处理和解析
  • 我们一般会把执行词法分析的程序称为词法解析器(lexer)
  • Token可以是关键字,字符串,变量名,函数名
  • 有效程序的"单词"都由Token表示,具体来说,这意味着"package","main","func" 等单词都为Token
  • Go语言允许我们使用go/scanner和go/token包在Go程序中执行解析程序,从而可以看到类似被编译器解析后的结构
  • 如果在语法解析的过程中发生了任何语法错误,都会被语法解析器发现并将消息打印到标准输出上,整个编译过程也会随着错误的出现而被中止
  • helloworld程序解析后如下所示
1:1   package "package"
1:9   IDENT   "main"
1:13  ;       "\n"
2:1   import  "import"
2:8   STRING  "\"fmt\""
2:13  ;       "\n"
3:1   func    "func"
3:6   IDENT   "main"
3:10  (       ""
3:11  )       ""
3:13  {       ""
4:3   IDENT   "fmt"
4:6   .       ""
4:7   IDENT   "Println"
4:14  (       ""
4:15  STRING  "\"Hello, world!\""
4:30  )       ""
4:31  ;       "\n"
5:1   }       ""
5:2   ;       "\n"
5:3   EOF     ""
  • 我们可以看到,词法解析器添加了分号,分号常常是在C语言等语言中一条语句后添加的
  • 这解释了为什么Go不需要分号:词法解析器可以智能地加入分号

语法分析

  • 语法分析的输入就是词法分析器输出的 Token 序列,这些序列会按照顺序被语法分析器进行解析,语法的解析过程就是将词法分析生成的 Token 按照语言定义好的文法(Grammar)自下而上或者自上而下的进行规约,每一个 Go 的源代码文件最终会被归纳成一个 SourceFile 结构:
SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" }
  • 标准的 Golang 语法解析器使用的就是 LALR(1) 的文法,语法解析的结果生成了抽象语法树(Abstract Syntax Tree,AST)
  • 抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值