欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 文化 > tree-sitter的grammar.js解惑

tree-sitter的grammar.js解惑

2025/4/18 13:33:13 来源:https://blog.csdn.net/2302_76774649/article/details/147153452  浏览:    关键词:tree-sitter的grammar.js解惑

❓问题1:grammar.js 不是用正则表达式 /.../ 吗?为什么有 'print' 这样的字符串?

✅ 回答:

grammar.js 分成两类“终结符”表示法:

表达方式含义
'xxx'直接匹配该字符串字面量
/regex/匹配符合正则的文本

💡 举例说明:

'print'           // 匹配文本里正好是 "print" 这个词
/[a-zA-Z_]+/      // 匹配任何标识符(如变量名)

Tree-sitter 支持 literal 字符串正则表达式,它们有不同的用途:

  • '=''let''function' 等是关键词或符号,通常写成字符串字面量
  • 正则主要用来定义通用格式,比如数字、标识符、字符串、注释

❓问题2:token(...) 有什么用?为什么不用正则就行了?

✅ 核心回答:

你写 /.../ 只是写了个规则,tree-sitter 默认会尝试进一步拆解规则内容

token(...) 的作用是:

告诉 Tree-sitter:这个部分是词法单位,不要对它再做语法结构解析了!


📌 举个例子:

🔴 没有 token 的情况:
number: $ => /\d+\.\d+/

Tree-sitter 会试图把这个规则拆开,比如它会试着把 123.45 拆成:

  • 123
  • .
  • 45

这样它就可能匹配错,或者让你写更多优先级规则去处理冲突,非常麻烦。

✅ 使用 token
number: $ => token(/\d+\.\d+/)

Tree-sitter 就会说:

好的,我不拆了,我直接把 123.45 当成一个整体 number 了!


✅ 总结:token(...) 用于匹配词法单位(不可再拆分的基本块),防止 tree-sitter 把内容继续“语法解析”。


❓那关键词比如 seqchoice 等就不能省略吗?我直接 /regex/ 一行行写正则不行吗?

✅ 回答:

你当然可以全写正则,但:

  • 正则只能写“单个词法单元”,比如标识符、数字、注释等;
  • seqchoice 等是用来构建**语法结构(句法规则)**的。

换句话说:

正则是词法(Lexical),而 seq/choice/... 是句法(Syntactic)


📌 比如:

// 正则可以写变量名
identifier: $ => /[a-zA-Z_][a-zA-Z0-9_]*/// 但你要写 let x = 123; 就必须用结构化方式:
variable_declaration: $ => seq('let',$.identifier,'=',$.number,';'
)

✅ 总结一波三问:

问题回答
grammar.js 只能写 /.../ 吗?为什么还有 '...''...' 是字符串字面量,比如关键字、符号等
为什么还要 token(...),不用正则不行吗?token(...) 告诉 tree-sitter:这是一个不可再分的词法单元
能只写正则不写 seq/choice/optional 吗?正则只能写“单元”,构建结构必须用 seq 等关键词

你现在完全可以尝试自己写个 grammar.js 的小文件啦!想不想我们来练一下,比如:解析 let x = 1; 或者 print("hello")

只要你告诉我你想写哪种结构,我可以边写边讲,完全按你节奏来 😎

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词