如何使用 ”!”作为注释指示器,但也不是语言语法高亮中的运算符?

How to use "!" as the comment indicator, but also NOT operator in language syntax highlight?

我正在使用 VScode 并创建我自己的语言扩展来突出显示语法,我需要在其中使用正则表达式来查找注释。

基本规则是!之后的所有内容都是注释,但是有一种特殊情况。当!eval()命令中时,表示NOT。

例如我的一些代码如下所示:

if condition=(eval(!DB_EXIST)) ! this is a comment
(eval( !DB_UPDATED && !DB_EXIST)) !---"!" inside eval() means NOT
!this is another comment
<some commands> ! this is also a comment

第1行和第2行的!DB_EXIST不应被解释为注释,!后面会跟一个非space.

白色space评论无所谓

"comments": {
    "patterns" [{
        "match":"regex1",
        "name":"comment"
    }]
},
"operator": {
    "patterns" [{
        "match":"regex2",
        "name":"keyword.operator.NOT"
    }]
},

我应该使用哪种正则表达式 1 和 2 来显示不同颜色的评论而不是?

我不擅长写这个扩展,所以如果有更好的方法来完成这项工作,我将不胜感激。 谢谢!

更新

@Gama11 帮助了我,但我并没有在我的代码示例中完全涵盖所有情况。 “!”之后的任何非空间也应该是注释,只要“!”不在 eval() 内。

这是一种方法:

{
    "$schema": "https://raw.githubusercontent.com/Septh/tmlanguage/master/tmLanguage.schema.json",
    "scopeName": "source.abc",
    "patterns": [
        {
            "begin": "(eval)\(",
            "end": "\)",
            "captures": {
                "1": {
                    "name": "entity.name.function"
                }
            },
            "patterns": [
                {
                    "include": "#parens"
                },
                {
                    "match": "!",
                    "name": "keyword"
                }
            ]
        },
        {
            "match": "!.*?$",
            "name": "comment"
        }
    ],
    "repository": {
        "parens": {
            "begin": "\(",
            "end": "\)",
            "patterns": [
                {
                    "include": "#parens"
                }
            ]
        }
    }
}

我们将 non-comment ! 的模式放在第一位,因为它更具体并且应该优先于另一个。另外,我使用了 "keyword" 范围而不是更合适的 "keyword.operator.NOT" 所以它实际上在屏幕截图中显示了不同的颜色。

第一个正则表达式是 begin-end 模式,它允许我们仅将模式应用于这两个匹配项之间的文本(在本例中为 eval() calll) .当我们这样做时,我们不妨将 eval 突出显示为具有 entity.name.function 范围的函数。

如果我们在 eval() 内,我们允许两种模式:

  • 递归 begin-end 模式(包括自身)来平衡括号(你可能有类似 eval(foo() + !bar()) 的东西,而 )foo() 不应该结束 eval-模式)
  • 我们首先感兴趣的 ! 运算符

第二个正则表达式只匹配 !,然后匹配任何内容 (.*?),直到行尾 ($).

一般来说,我强烈建议使用像 regex101.com 这样的工具来处理 TM 语法文件的正则表达式。比在 VSCode 本身迭代要容易得多,因为你会得到即时反馈。