Как пользоваться "!"как индикатор комментария, но также оператор НЕ в выделении синтаксиса языка? - PullRequest
1 голос
/ 23 мая 2019

Я использую VScode и создаю свое собственное языковое расширение для выделения синтаксиса, где мне нужно использовать регулярное выражение для поиска комментариев.

Основное правило состоит в том, что все, что после !, является комментарием, однакоесть особый случай.Когда ! находится внутри команды eval(), это означает НЕ.

Например, часть моего кода будет выглядеть так:

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

!DB_EXIST в строках 1 и 2 должноне следует интерпретировать как комментарии, и за ! будет следовать не пробел.

Пробел не имеет значения в комментариях.

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

Какой тип регулярного выражения 1 и 2 следуетЯ использую, чтобы показывать другой цвет для комментариев, а НЕ?

Я не очень хорош в написании этого расширения, поэтому, если есть какой-то лучший способ сделать работу, я буду очень признателен услышать.Спасибо!

Обновление

@ Gama11 помогло мне, но я не полностью охватил весь случай в моих примерах кода.Любой не-sapce после "!"Также должны быть комментарии, пока "!"не внутри eval ().

1 Ответ

3 голосов
/ 23 мая 2019

Вот один из способов сделать это:

{
    "$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"
                }
            ]
        }
    }
}

Сначала мы ставим шаблон для комментариев !, поскольку он более конкретен и должен иметь приоритетнад другим.Кроме того, я использовал область действия "keyword" вместо более подходящего "keyword.operator.NOT", поэтому на скриншоте он фактически показывает другой цвет.

Первое регулярное выражение - это шаблон begin - end, который позволяетмы должны применять шаблоны только для текста между этими двумя совпадениями (в этом случае в eval() calll).Пока мы на этом, мы могли бы также выделить eval как функцию с областью действия entity.name.function.

Если мы находимся в пределах eval(), мы допускаем два шаблона:

  • рекурсивный шаблон begin - end (включает в себя) для балансировки скобок (возможно, у вас может быть что-то вроде eval(foo() + !bar()), и ) в foo() не должно заканчиваться eval -pattern)
  • оператор !, который нас интересует, в первую очередь

Второе регулярное выражение просто соответствует !, а затем чему угодно (.*?)до конца строки ($).

В общем, я настоятельно рекомендую использовать инструмент типа regex101.com для игры с регулярными выражениями файлов TM Grammar.Гораздо проще, чем итерация в самом VSCode, поскольку вы получаете мгновенную обратную связь.

...