Интерполяция строк в Antlr4 - PullRequest
0 голосов
/ 05 марта 2020

У меня есть грамматика, которая использует режимы для интерполяции строк: что-то вроде:

lexer grammar Example;

//default mode tokens
LBRACE: '{' -> pushMode(DEFAULT_MODE);
RBRACE: '}' -> popMode;

OPEN_STRING: '"' -> pushMode(STRING);
mode STRING;
ID_INTERPOLATION: '$' IDEN;
OPEN_EXPR_INTERPOLATION: '${' -> pushMode(DEFAULT_MODE);
TEXT: '$' | (~[$\r\n])+;
CLOSE_STRING: '"' -> popMode;
parser grammar ExampleParser;
options {tokenVocab = Example;}

test: string* EOF;
string: OPEN_STRING string_part* CLOSE_STRING;
string_part: TEXT | ID_INTERPOLATION | OPEN_EXPR_INTERPOLATION expr RBRACE;


//more rules that use LBRACE and RBRACE

Теперь это работает и разбивает все на части в основном как я хочу , но у него есть 2 fl aws.

  1. , если число RBRACES заходит слишком далеко, он может вытолкнуть первый режим по умолчанию, который может сбить IDE, и не просто отображать ошибку .
  2. Токен для закрытия блока и интерполяции блока одинаков, поэтому я не могу выделить их так, как хочу. (это основной)

Моя IDE подсвечивается только на основе токенов, так что это проблема, я бы хотел выделить их по-другому. Так что, в принципе, я хотел бы найти решение для этого, которое делает RBRACE другим токеном, когда он находится в строке.

Я бы предпочел сделать это без предикатов semanti c, потому что я не хочу ie это до языка, но если нужно, я в порядке с этим, мне просто может понадобиться немного больше объяснений, потому что я не использовал их так много.

1 Ответ

0 голосов
/ 06 марта 2020

Спасибо @ sepp2k за помощь в решении моей проблемы.

Это что-то вроде хака, но он делает именно то, что мне нужно, чтобы

Я решил это, изменив свой popMode на RBRACE следующим образом:

RBRACE: '}' {
    if(_modeStack.size() > 0) {
        popMode();
        if(_mode != DEFAULT_MODE) {
            setType(EXPR_INTERPOLATION);
        }
    }
};

Я также изменил свой синтаксический анализатор на

string_part: TEXT | ID_INTERPOLATION | EXPR_INTERPOLATION expr EXPR_INTERPOLATION;

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

...