【问题标题】:How does the Go1 compiler work?Go1 编译器是如何工作的?
【发布时间】:2012-04-21 18:26:28
【问题描述】:

我已经为一个学校项目涉足 Go 大约一个月了,我注意到 src/pkg/go 文件夹中的 go/ast、go/token、go/parser 等包。但是,gc 编译器是基于位于 src/cmd/gc 中的 C 文件。

我的问题是关于 Go1 中构建和运行程序的新 go 命令:这个工具是否依赖于我上面引用的包?即如果我在 /go/token/token.go 中添加了一个新的令牌,它会被新的 go 编译器识别吗?

【问题讨论】:

    标签: compiler-construction go


    【解决方案1】:

    Go 编译器是用纯 C 编写的,不使用 go/ 下的包。在 Go 源代码树中,它的词法分析器位于 src/cmd/gc/lex.c 中,其 Bison 语法为 src/cmd/gc/go.y。

    go/ 包用于 godoc、gofmt 等工具和各种 go 工具子命令。也许有一天它们也可以用来在 Go 中编写 Go 编译器,但目前还没有人在这条路上走得很远。

    【讨论】:

    • 用它应该编译的语言编写编译器有一个直接的优势:狗食可以让你感受你的语言。然而,它也带来了一个障碍:便携性。拥有适用于您的语言的 C 编译器意味着您可以让编译器在您喜欢的任何平台上工作。当然,运行时和代码生成可能仍然需要工作,但差距较小(尽管仍然很困难)。
    • 其实还有llgo,这是一个使用llvm作为后端用Go编写的Go编译器,虽然还没有完成,但是看起来很高级:github.com/axw/llgo
    【解决方案2】:

    注意(2013 年 12 月 18 日),有计划将编译器从 C 迁移到 Go 本身:

    Go 1.3+ Compiler Overhaul”(拉斯考克斯)

    在这种情况下,将涉及 go/parser 等包,并且“第 5 阶段”提到:

    go/parsergo/types 的最新(可能是新)版本替换前端。
    Robert Griesemer 讨论了在某个时候设计新的 go/parsergo/types API 的可能性,基于对当前 API 的经验(并使用新名称,以保持 Go 1 的兼容性)。
    将它们连接到编译器后端的工作可能有助于指导新 API 的设计。


    这可能是语言变得多么稳定的证明,因为之前提到的旧的“A Tour of Go”(2012 年 6 月)明确指出:

    Go 本身不是编写的这一事实也使得进行重大语言更改变得更加容易。
    在初始版本之前,我们经历了一些大规模的语法剧变,我很高兴我们不必担心我们将如何重新启动编译器或在这些更改期间确保某种向后兼容性。

    当时(再次,2012 年 6 月)提到的问题“有没有计划在 Go 中引导 Go,在 Go 中编写 Go 编译器?”:

    没有立即的计划。 Go 附带了一个用 Go 编写的 Go 程序解析器,所以第一部分已经完成,并且有一个实验性的类型检查器正在开发中,但主要用于编写程序分析工具。

    我过去曾研究过引导式语言,我发现引导式不一定适合经常变化的语言。它让我想起了攀登悬崖,偶尔在悬崖上拧上钩子,以便在你跌倒时抓住你。

    【讨论】:

    【解决方案3】:

    这个工具是否依赖于我上面提到的包?

    “go”工具确实依赖于这些包

    如果我在 /go/token/token.go 中添加了一个新的令牌,新的 go 编译器会识别它吗?

    没有。

    【讨论】:

    • 如果我添加了一个新的token,以及一个对应的ast节点和解析方法呢?还是我完全走错了路
    • go 工具调用了 Go 编译器,但是 Go 编译器是一个 C 项目,它不使用 Go 解析器包。
    猜你喜欢
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多