自己写了个 RelaxNG 的 tree sitter parser

目前算是把 API 定下来了。之后会用它给 Emacs 写个 rnc-ts-mode

总结一下,其实写起来已经很傻瓜化了,只要有开发 parser 的 PL 理论基础就能上手,如果有 ambiguity 生成器会自动生成反例,和 Invisible XML 也很像。

主要的难度是编程语言官方给的语法不一定合适直接用,要考虑怎么生成对 navigation 有用的语法树,同時 parent relationship 还要合理。

5 个赞

我也有点兴趣给其他的小语言写一个

简单看了看 Elisp Manual 和 Emacs 内置的一些 ts-mode,如果要通过 treesitter parser 来控制代码缩进,则需要编写 treesit-simple-indent-rules。比如 js--treesit-indent-rules

(defvar js--treesit-indent-rules
  (let ((switch-case (rx "switch_" (or "case" "default"))))
    `((javascript
       ((parent-is "program") parent-bol 0)
       ((node-is "}") parent-bol 0)
       ((node-is ")") parent-bol 0)
       ((node-is "]") parent-bol 0)
       ((node-is ">") parent-bol 0)
       ((and (parent-is "comment") c-ts-common-looking-at-star)
...
       ((node-is "statement_block") parent-bol js-indent-level)
       ((parent-is "named_imports") parent-bol js-indent-level)
       ((parent-is "statement_block") parent-bol js-indent-level)
       ((parent-is "variable_declarator") parent-bol js-indent-level)
       ((parent-is "arguments") parent-bol js-indent-level)
       ((parent-is "array") parent-bol js-indent-level)
...

目前我还没仔细看过 treesitter 的文档,如果我想要在 emacs 使用某个 parser ,我需要知道 parser 中给各个节点或者说元素的命名吗,还是说 tree-sitter 给一些类似的结构统一了命名?

对,你要对 parser 生成的语法树大致结构有了解。你可以用 treesit-explore-mode 在 Emacs 中进行交互式开发。命名慣例完全取決于 parser 作者。

见我的 rnc-ts-mode new rnc-ts-mode · LdBeth/InfernoEmacs@bfa492b · GitHub

试过了,很好玩 :innocent:

那各种 ts-mode 应该是和某个 parser 绑定了,现在 Emacs 29 中的各种 mode 使用的应该是 tree-sitter 网站中列出的那些。

get

其实,用別人写的 parser 还要处理不同版本的兼容⋯⋯所以不如用自己写的好。

1 个赞

顺带开个投票决定一下下一个用 tree sitter 实现的语言

  • J
  • PVS
  • CRM114
  • HOL4
  • Clean

0 投票人