3

这可能与我不了解关键字提取功能有关,从文档看来,这似乎是为了避免关键字和以下表达式之间不存在空格的问题。但是假设我有一个用于变量名、函数名等的相当标准的标识符正则表达式:

/\w*[A-Za-z]\w*/

如何防止它匹配保留关键字,如IForELSE或类似的东西?所以这个表达式会产生一个错误:

int IF = 5;

虽然这不会:

int x = 5;

4

1 回答 1

1

自 2019 年以来有一个拉取请求待处理以添加 EXCLUDE 功能,但截至撰写本文时,目前尚未实施(2021 年 4 月 - 如果一段时间过去了并且您正在阅读此内容,请重新检查此内容!) . 而且由于treesitter也不支持其正则表达式中的负向lookbehind,这必须在语义级别进行处理。为了使检查更容易,您可以做的一件事是枚举所有保留字,然后将它们添加为标识符正则表达式的替代:

keyword: $ => choice('IF', 'THEN', 'ELSE'),

name: $ => /\w*[A-Za-z]\w*/,

identifier: $ => choice($.keyword, $.name)

根据 treesitter 的match rules规则 4 ,在表达式int IF = 5;中,IFtoken 将匹配(identifier keyword),而不是(identifier name)因为它是更具体的匹配。这意味着您可以对非法(identifier keyword)节点进行简单的查询,并将错误显示给您的语言服务器中的用户,或者从您使用 treesitter 语法的任何地方。

(identifier keyword)请注意,这种方法确实存在在您的匹配项和使用这些关键字的实际语言结构之间产生许多冲突的风险。如果是这样,您将不得不在语义级别处理整个事情:扫描所有标识符以检查它们是否是保留字。

于 2021-04-05T16:32:23.407 回答