这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战
Go有多个生产编译器,而且还有一些为各种平台开发的编译器。
默认编译器 gc ,包含在 Go 发行版中,作为对 go 命令支持的一部分。由于引导困难,Gc 最初是用 C 编写的——因为你需要一个 Go 编译器来设置 Go 环境。但是事情已经有了进展,自从 Go 1.5 发布以来,编译器已经是 Go 实现的了。使用自动翻译工具将编译器从 C 转换为 Go。因此编译器现在是“自托管”的,这意味着我们需要面对自动启动(bootstrap)问题。解决方案是,先有一个可用的 Go安装环境,就和 C 安装环境一样。这篇文章如何从源代码调出一个新的 Go 环境的介绍。
Gc 是用 Go 编写的,带有递归下降解析器,并使用自定义加载器(也是用 Go 编写但基于 Plan 9 加载器)来生成 ELF/Mach-O/PE 二进制文件。
在项目开始时,我们考虑将 LLVM 用于 gc,但认为它太大且速度太慢,无法满足我们的性能目标。更重要的是,使用LLVM 会使引入一些 ABI 和相关更改(例如堆栈管理),而这会让工程变得更加困难,这些更改是 Go 需要的,但不是标准 C 设置的一部分。然而,一个新的 LLVM升级出现了。
Gccgo 编译器是一个用 C++ 编写的前端,后端是 GCC 的递归下降解析器。
Go 被证明是一种很好的语言,可以用它来实现 Go 编译器,尽管这不是它的最初目标。自托管的模式并不是 一开始Go 的设计初衷,Go的初衷是网络服务器。如果一开始就决定 Go可以编译自己,我们可能最终会得到一种更多针对编译器构建的语言,这很有价值,但不是我们最初的目标。
go 包中提供了一个本地词法分析器和解析器,并且还有一个本地类型检查器。