谓词与指令(Predicates and Directives)
查询中的谓词(Predicates)和指令(Directives)类似于过程式语言中的函数。
- 谓词用于根据特定条件过滤匹配结果
- 指令用于向查询执行环境传递操作指令(例如设置元数据)
Tree-sitter 核心库本身并未内置具体的谓词或指令实现。 相反,一些工具和编辑器约定并实现了一组通用谓词与指令。(Nova)
谓词语法
谓词写在模式内部,形式如下:
(#predicate-name arguments...)
参数可以是:
- 捕获(capture)
- 字符串(string)
例如:
(#eq? @attr "border:")
(#not-eq? @tag.name div)
其中:
@attr、@tag.name是捕获节点引用"border:"或div是常量字符串 (仅包含字母、数字、下划线、连字符或点的字符串可以省略引号)(Nova)
常见谓词
#eq?
判断捕获节点的文本是否等于指定字符串。
(
(identifier) @name
(#eq? @name "main")
)
仅匹配名称为 main 的 identifier。
#not-eq?
判断捕获节点文本不等于指定字符串。
(#not-eq? @name "test")
#match?
使用正则表达式匹配捕获节点文本。
(
(identifier) @constant
(#match? @constant "^[A-Z_]+$")
)
匹配全大写常量名称。
#not-match?
正则表达式不匹配时成立。
(#not-match? @name "^_")
匹配不以下划线开头的名称。
#any-of?
当捕获文本属于给定集合之一时匹配。
(
(identifier) @keyword
(#any-of? @keyword "if" "for" "while")
)
多捕获比较
谓词也可以比较两个捕获节点:
(
(pair
key: (property_identifier) @key
value: (identifier) @value)
(#eq? @key @value)
)
仅当 key 与 value 文本相同时匹配。
指令(Directives)
指令与谓词语法类似,但用于修改匹配结果的元信息或影响后续处理。
语法形式:
(#directive-name! arguments...)
注意:
- 指令名称以
!结尾 - 不用于过滤匹配,而是执行操作
示例:#set!
为捕获节点设置元数据属性:
(
(identifier) @variable
(#set! highlight "variable.special")
)
该指令可被编辑器或工具读取,用于语法高亮等用途。
示例:#offset!
用于调整捕获范围(常见于编辑器实现中):
(#offset! @capture 0 1 0 -1)
具体行为取决于宿主工具实现。
关键点总结
- 查询模式负责结构匹配
- 捕获负责命名节点
- 谓词负责条件过滤
- 指令负责附加行为或元数据
即:
Pattern → Capture → Predicate → Directive
形成 Tree-sitter Query 的完整匹配流程。
