使用tree-sitter作为编译器的主要解析器

gav*_*n.d 8 compiler-construction parsing syntax-highlighting treesitter

由tree-sitter生成的解析器可以同时用于语法突出显示和编译器本身吗?如果不是——为什么?

编写两个不同的解析器并维护它们会适得其反。

注意:我还没有使用过tree-sitter,但考虑使用它来突出显示我自己的编程语言的语法。因此,我可能会误解它的解析器实际上是如何工作的。

Seb*_*raf 5

引用https://github.com/tree-sitter/tree-sitter/discussions/831的答案:

我认为在编译器前端使用 Tree-sitter 解析器的最大缺点是,虽然我们在 Tree-sitter 的错误恢复方面做了很多工作,但我们还没有构建错误消息的功能。因此,找出错误发生的确切标记/位置并获取预期标记的列表以及类似的事情并不是一件容易的事。

此外,错误恢复当前不能以特定于域的方式进行定制(例如,一旦出现“函数”一词,就假设用户打算编写整个函数定义)。

今后,我很乐意投资这两件事,但由于我们正在研究很多其他事情,因此可能需要一段时间才能实现。

我设法使用玩具语言的树保姆解析器来实现 Rust 中的解释器:https ://github.com/sgraf812/tree-sitter-lambda/blob/35fe05520e806548dedb48e7f97118847b531b26/src/main.rs

完成后,我不能推荐它:

  1. (Rust 是一种有点可怕的语言来做到这一点,所有的循环引用。不过,可能有更好的方法。)
  2. 没有 AST,也没有办法生成 AST,因为树守护者不允许规范化简操作(因为这又会将元语言与规范语言联系起来,就像bisonC 和 C 的情况一样)。这意味着你必须切换Node::kind一个字符串。低效且不完整的匹配随处可见。
  3. 语法树节点仅存储范围,而不存储关联的源代码字符串,导致 API 有点笨拙,请参阅ut8_text.

我有一种感觉,只有当您不需要语法树的类型覆盖时,树守护者才是课堂上最好的。

另请参阅https://github.com/tree-sitter/tree-sitter/discussions/831#discussioncomment-5797368以获取另一份体验报告。