文章摘要
该项目是一个用纯Go语言实现的tree-sitter运行时库,提供了语法解析功能。tree-sitter是一个流行的解析器生成工具,该项目使其能在Go环境中使用。
文章总结
GitHub 项目:odvcencio/gotreesitter - 纯 Go 实现的 tree-sitter 运行时
项目简介
该项目是一个用纯 Go 语言实现的 tree-sitter 运行时,无需 CGo 或 C 工具链,支持 WASM。它实现了与 tree-sitter 相同的解析表格式,因此现有语法无需重新编译即可使用。在性能方面,该项目在所有工作负载上都优于 CGo 绑定,特别是在编辑器或语言服务器中占主导的增量编辑操作上,比 C 实现快 90 倍。
为什么选择纯 Go 实现?
现有的 Go tree-sitter 绑定都需要 CGo,这会导致以下问题:
- 跨平台编译失败(如 GOOS=wasip1、GOARCH=arm64 或 Windows 无 MSYS2 环境)
- CI 流水线需要在每个构建镜像中包含 C 工具链
- 没有 gcc 的用户无法通过 go install 安装
- 跨 CGo 边界的竞态检测、模糊测试和覆盖率工具效果不佳
gotreesitter 是纯 Go 实现,可以在任何平台或目标上通过 go get 安装和构建。
快速开始
```go import ( "fmt" "github.com/odvcencio/gotreesitter" "github.com/odvcencio/gotreesitter/grammars" )
func main() {
src := []byte(package main\nfunc main() {})
lang := grammars.GoLanguage()
parser := gotreesitter.NewParser(lang)
tree := parser.Parse(src)
fmt.Println(tree.RootNode())
}
```
查询功能
支持 tree-sitter 的 S 表达式查询语言,包括谓词和基于游标的流式处理。
增量编辑
初始解析后,仅重新解析更改的区域,未更改的子树自动复用。
语法高亮
go
hl, _ := gotreesitter.NewHighlighter(lang, highlightQuery)
ranges := hl.Highlight(src)
符号标记
从源代码中提取定义和引用:
go
tagger, _ := gotreesitter.NewTagger(lang, entry.TagsQuery)
tags := tagger.Tag(src)
性能基准
在解析包含 500 个函数定义的 Go 源文件时,与标准 CGo 绑定对比:
| 工作负载 | gotreesitter | CGo 绑定 | 性能比 | |---------|-------------|---------|-------| | 完整解析 | 1,330 μs | 2,058 μs | ~1.5 倍更快 | | 增量编辑(单字节修改) | 1.38 μs | 124 μs | ~90 倍更快 | | 增量解析(无修改) | 8.6 ns | 121 μs | ~14,000 倍更快 |
支持的语言
目前支持 205 种语法,运行 go run ./cmd/parity_report 可查看实时状态:
- 204 种完整支持(无错误解析)
- 1 种部分支持(norg,需外部扫描器)
- 0 种不支持
架构设计
gotreesitter 完全用 Go 重新实现了 tree-sitter 运行时,包括: - 解析器:基于表的 LR(1) 解析器,支持 GLR 处理歧义语法 - 增量复用:基于游标的子树复用 - 内存管理:基于 slab 的节点分配和引用计数 - 词法分析:从语法表生成的 DFA 词法分析器 - 外部扫描器 VM:用于语言特定扫描的字节码解释器 - 查询引擎:支持谓词评估和流式游标的 S 表达式模式匹配
测试
测试套件包括: - 所有 205 种语法的冒烟测试 - 20 种核心语言的正确性快照测试 - 高亮验证测试 - 查询测试 - 解析器测试 - 模糊测试
路线图
- 当前版本:v0.4.0,支持 205 种语法、稳定解析器、增量解析、查询引擎等
- 下一步计划:
- 强化查询引擎的兼容性
- 为更多语言添加手写外部扫描器
- 改进错误处理
- 自动化与 C tree-sitter 的兼容性测试
- 扩展模糊测试覆盖范围
许可证
评论总结
以下是评论内容的总结:
对项目的积极评价
- 认为该项目对Bazel社区很有价值,可以消除CGO依赖,实现纯Go开发
"Now perhaps we can get rid of the CGO dependency and make it pure Go instead." - 表示对项目的兴趣,认为对Go-based代码托管平台很有用
"I imagine this can very useful for Go-based forges that need syntax highlighting"
- 认为该项目对Bazel社区很有价值,可以消除CGO依赖,实现纯Go开发
命名冲突问题
- 指出"got"可能与OpenBSD的Got工具冲突
"Wouldn'tgotbe confused with OpenBSD's Got"
- 指出"got"可能与OpenBSD的Got工具冲突
技术比较与改进建议
- 询问与git相比的主要改进
"How do you see got's main improvement over git?" - 建议兼容git仓库,降低试用门槛
"How about making 'got' compatible with git repos like jujutsu?"
- 询问与git相比的主要改进
技术细节讨论
- 关注语法解析器的更新状态和二进制文件大小
"Are these pretty up-to-date grammars? How large are your binaries getting?" - 指出部分语法解析可能不准确的问题
"Why do you have a parsing mode that guarantees incorrect outputs on some grammars"
- 关注语法解析器的更新状态和二进制文件大小
项目结构疑问
- 质疑源代码和测试代码放在根目录的做法
"Is it a go-ism that source for implementation and test code lives in the root of the repo"
- 质疑源代码和测试代码放在根目录的做法
标题建议
- 建议修改标题以更准确反映项目内容
"Better title: Claude attempted a treesitter to go port"
- 建议修改标题以更准确反映项目内容
特定功能需求
- 询问是否支持TreeCursors和动态生成语法
"Do you have an equivalent of TreeCursors or tree-sitter-generate?"
- 询问是否支持TreeCursors和动态生成语法