0

我正在努力尝试在我正在实现的语言服务器中创建和使用 tree-sitter 语法,以支持查找变量的所有引用等功能。给定语法,我将能够编写一个查询来查找对具有特定名称(例如myVar)的变量的所有引用。但是,我正在为使用不区分大小写的变量编写语言服务器的语言(例如,myVar可以引用为MYVARMyVaRmyvar等)。

我如何能够编写一个树保姆查询来匹配令牌必须不区分大小写地匹配特定字符串的模式?

我可以编写查询以不按变量名称过滤并实现我自己的结果过滤,但我想知道是否有一种方法可以在查询本身内处理这个问题,而不是实现自定义过滤代码。

例子

这是一个简化的示例案例来说明我的意思。

给定以下语法,我想查询为set_statements变量设置新值的所有内容myVar

module.exports = grammar({
  name: 'mylang',

  rules: {
    source_file: $ => repeat($._statement),
    _statement: $ => choice(
      $.set_statement,
    ),
    set_statement: $ => seq(
      'set',
      field("variable", $.identifier),
      field("value", $._expression),
    ),
    _expression: $ => choice(
      $.integer_literal
    ),

    identifier: $ => /[a-zA-Z0-9]+/,
    integer_literal: $ => /[0-9]+/,
  }
});

通常我可以通过如下查询来做到这一点。

(
    (set_statement
        variable: (identifier) @variable)
    (#eq? @variable "myVar")
)

但是,正如我们在以下运行查询的示例中看到的那样,这仅适用于myVar使用与查询相同的大小写的引用。

$ cat set_testing.txt 
set myVar 0
set MYVAR 23
set myVar2 72
set MyVaR 14
$ tree-sitter query find_variable.query set_testing.txt
set_testing.txt
  pattern: 0
    capture: variable, start: (0, 4), text: "myVar"

我想创建一个查询,而不是找到:

tree-sitter query find_variable.query set_testing.txt
set_testing.txt
  pattern: 0
    capture: variable, start: (0, 4), text: "myVar"
  pattern: 0
    capture: variable, start: (1, 4), text: "MYVAR"
  pattern: 0
    capture: variable, start: (3, 4), text: "MyVaR"
4

1 回答 1

1

更改您的查询以匹配与标识符的所有可能的上/下组合匹配的正则表达式,在这种情况下为myvar.

如果您更改 find_variable.query 以对所有大小写组合使用正则表达式匹配:

(
    (set_statement
        variable: (identifier) @variable)
    (#match? @variable "^[mM][yY][vV][aA][rR]$")
)

现在运行tree-sitter query find_variable.query set_testing.txt返回:

set_testing.txt
  pattern: 0
    capture: variable, start: (0, 4), text: "myVar"
  pattern: 0
    capture: variable, start: (1, 4), text: "MYVAR"
  pattern: 0
    capture: variable, start: (3, 4), text: "MyVaR"

Tree-sitter 不支持不区分大小写的正则表达式搜索问题 #261,因此正则表达式稍长一些。

于 2021-06-02T15:14:59.020 回答