当前位置: 首页 > news >正文

tree-sitter 的 grammar.js 编写方法

tree-sitter 的 grammar.js 编写方法

    • 一、`grammar.js` 的作用是什么?
    • 二、基本结构
    • 三、关键词解释
    • 四、编写小技巧
      • 1. 起点是 `source_file`
      • 2. 所有规则名(如 `identifier`, `number`)都是 `$ => ...`
      • 3. 正则表达式用于定义词法规则(终结符),例如:
    • 五、🍀 `$`的简单解释:`$` 是规则的“引用工具”
      • ❓ 那 `$` 到底能干嘛?
      • 🧠 举个例子来说明
    • 🔧 类比一下:

要掌握 tree-sittergrammar.js 编写方法,首先我们要理解 tree-sitter 的核心概念,它是一个 基于GLR算法的增量解析器生成工具,常用于语法高亮、代码分析等任务。

一、grammar.js 的作用是什么?

这是 tree-sitter 语法的定义文件,描述了一个语言的 词法规则(Lexing)语法规则(Parsing)


二、基本结构

grammar.js 是一个 CommonJS 模块,通常长这样:

module.exports = grammar({
  name: 'my_language', // 语言名称

  // 词法规则
  extras: $ => [/\s/, $.comment], // 忽略的内容,如空格、注释

  // 定义词法(token)
  rules: {
    source_file: $ => repeat($.statement),

    statement: $ => choice(
      $.variable_declaration,
      $.function_call
    ),

    variable_declaration: $ => seq(
      'let',
      $.identifier,
      '=',
      $.expression,
      ';'
    ),

    function_call: $ => seq(
      $.identifier,
      '(',
      optional($.expression),
      ')',
      ';'
    ),

    expression: $ => choice(
      $.number,
      $.string,
      $.identifier
    ),

    identifier: $ => /[a-zA-Z_][a-zA-Z0-9_]*/,
    number: $ => /\d+/,
    string: $ => /"[^"]*"/,
    comment: $ => /\/\/.*/
  }
});

三、关键词解释

  • seq(...): 顺序匹配(sequence),表示一段连续的符号。
  • choice(...): 匹配多个可能之一(like OR)。
  • repeat(...): 重复0次或多次。
  • repeat1(...): 重复至少1次。
  • optional(...): 可选项。
  • token(...): 表示这是一个词法单元(token),不会再细分。
  • prec(n, rule): 设置优先级(n 越大,优先级越高)。

四、编写小技巧

1. 起点是 source_file

tree-sitter 会从你定义的 rules.source_file 开始解析整个文件。

2. 所有规则名(如 identifier, number)都是 $ => ...

这个 $ 是构造语法树时的“工具”,让你可以引用别的规则。

3. 正则表达式用于定义词法规则(终结符),例如:

identifier: $ => /[a-zA-Z_][a-zA-Z0-9_]*/,
number: $ => /\d+/,

五、🍀 $的简单解释:$ 是规则的“引用工具”

grammar.js 中,你写的每一个语法规则都是一个函数,比如这样:

identifier: $ => /[a-zA-Z_][a-zA-Z0-9_]*/

这里的 $ => 就是给 tree-sitter 传递一个函数,这个函数的参数 $ 是个“语法引用器”。

❓ 那 $ 到底能干嘛?

它能让你“引用其他规则”。

🧠 举个例子来说明

比如你想定义这样一个语句:

let x = 42;

你在写规则时会写成:

variable_declaration: $ => seq(
  'let',
  $.identifier,
  '=',
  $.expression,
  ';'
)

这里的 $.identifier$.expression 就是**“引用”之前定义的两个规则**。注意:

  • $.identifier -> 指向你之前写的 identifier: $ => ...
  • $.expression -> 指向你之前写的 expression: $ => ...

这样 tree-sitter 就能在 variable_declaration 这个规则里,使用别的规则了。


🔧 类比一下:

你可以把 rules 想象成一个对象:

rules = {
  identifier: ...,
  expression: ...,
  variable_declaration: ...
}

$.identifier 就相当于 rules.identifier

所以这个 $ 就是代表你整个 rules 对象本身。


相关文章:

  • 如何进行预算考核
  • Ubuntu22环境下,Docker部署阿里FunASR的gpu版本
  • 【力扣hot100题】(085)单词拆分
  • P8647 [蓝桥杯 2017 省 AB] 分巧克力
  • 智能配电保护:公共建筑安全的新 “防火墙”
  • 大模型评估框架-----OpenCompass模型评估简介
  • js触发隐式类型转换的场景
  • 5. 蓝桥公园
  • TCP/UDP的连接和数据发送过程详解
  • 【模拟电路】稳压二极管/齐纳二极管
  • SGLang实战:从KV缓存复用到底层优化,解锁大模型高效推理的全栈方案
  • vue实现在线进制转换
  • 自定义排序注意点
  • 解决:AttributeError: module ‘cv2‘ has no attribute ‘COLOR_BGR2RGB‘
  • 微信小程序中使用ECharts 并且动态设置数据
  • 如何使用AI辅助开发CSS3 - 通义灵码功能全解析
  • Html页面Table表格导出导入Excel文件 xlsx.full
  • 蓝桥杯单片机刷题——按键设置当前采集距离为距离参数
  • TDDMS分布式存储管理系列文章--分片/分区/分桶详解
  • Navicat Premium Lite 17官方正版免费数据库连接工具
  • 简单网页尝试做教案/seo刷词工具在线
  • 网站建设的工作描述/广州网站设计公司
  • 网站建设 - 碧诺网络/搜索关键词排名
  • 漳州市政府门户网站建设/模板网站免费
  • 催眠美女做仆人网站/seo索引擎优化
  • 动态网站制作好了在哪里看/站长之家seo概况查询