Golang语法定义详解
Golang语法定义详解 大家好,
有谁知道Go语言的lex/yacc或等效文件存放在哪里吗?
先谢过了
此致
问候
关于 Go 编译器的所有内容都在这里:https://github.com/golang/go/tree/master/src/cmd/compile/internal。
我推荐阅读这篇文章来快速了解不同内容的查找位置。
更多关于Golang语法定义详解的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
感谢您的建议,我会去寻找1.6版本的相关资料。
我基本上已经编写了一门语言,并希望为其添加类似Go的语法规则,但在处理.y文件时遇到了困难,所以想看看Go是如何定义这些内容的。
1 个点赞
感谢您的关注,实际上通过研究1.6版本我已经找到了很多相关信息。虽然我也在使用goyacc解析器,但似乎收效甚微,因为我的语法以ANSI C语法风格为基础,而Golang的构建方式有所不同。
我原本想添加多返回值功能,但要做到这一点,我认为几乎需要完全重写代码。
func main() {
fmt.Println("hello world")
}
根据我的发现,Go编译器过去曾使用Bison(GNU的yacc替代工具),但从1.7版本开始改用"手写"(非自动化)的扫描器(词法分析器)和解析器。
这些代码可以在$GOROOT/src/cmd/compile/internal/syntax目录中找到,具体位于scanner.go和parser.go源文件中。
Go语言的EBNF规范包含在《Go编程语言规范》(https://golang.org/ref/spec)中,如果需要,你可以使用该规范自行创建lex和yacc文件。
我还没有尝试过,但或许你可以查看Go 1.6或更早版本的源代码来获取所需的文件。假设这个方法可行,你仍然需要查阅Go规范来添加之后所有新增的语言特性。
我进一步查阅资料,想确认之前从非权威来源(甚至维基百科)获取的信息是否准确,结果发现在Go 1.5版本时,团队已经转向使用基于Go语言编写的yacc兼容解析器生成器。在该版本中我未能找到任何yacc源文件(例如y.tab.c文件)。
不过在1.2版本(至少)中,他们仍在使用Bison:Go源代码中包含yacc文件,我找到了用于Go解析器的相关文件。具体查找步骤如下:
- 访问 https://golang.org/dl/,滚动至页面底部下载 go1.2.2.src.tar.gz
- 解压文件(
tar xvfz go1.2.2.src.tar.gz),在go/src/cmd/gc目录中查找名为go.y的文件
该目录下还存在 y.tab.c 文件,其中的注释显示他们当时使用的是Bison 2.5,且 go.y 被用于生成 y.tab.c。
看到这些后,我回忆起正是在1.5版本时,Go团队将编译器和运行时的实现从C语言迁移到了Go语言。这就是为什么从那时起不再使用Bison的原因。
我仅查看了下载页面上列出的最旧版本。如果您有兴趣,可以尝试查看更近的版本。1.5之前的其他版本可能也包含yacc文件。
在Go语言中,词法分析和语法分析相关的文件位于Go源代码的src/cmd/compile/internal/syntax目录下。具体来说:
- 词法分析器(lexer):相关代码在
scanner.go文件中实现,它负责将Go源代码转换为词法单元(tokens)。 - 语法分析器(parser):相关代码在
parser.go文件中实现,它基于词法单元构建抽象语法树(AST)。
Go语言没有直接使用传统的lex/yacc工具,而是用纯Go实现了自定义的词法和语法分析器。这些文件是Go编译器前端的一部分,用于处理Go源代码的解析。
示例代码结构说明:
在syntax包中,主要文件包括:
scanner.go:定义了scanner结构,用于扫描源代码并生成tokens。tokens.go:定义了Go语言的所有词法单元(如标识符、关键字、操作符等)。parser.go:实现了语法解析逻辑,构建AST节点。
例如,scanner.go中的next方法负责读取下一个token:
func (s *scanner) next() {
// 实现词法扫描逻辑,填充s.tok字段
}
而parser.go中的parseFile方法用于解析整个Go源文件:
func (p *parser) parseFile() *File {
// 解析文件级语法结构,返回AST根节点
}
这些文件是Go工具链的核心部分,如果你需要深入了解Go语法定义,建议直接查阅Go源码树的这个目录。注意,这些是内部实现,可能在不同Go版本中有所变化。

