У меня есть грамматика, которая использует режимы для интерполяции строк: что-то вроде:
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.
- , если число RBRACES заходит слишком далеко, он может вытолкнуть первый режим по умолчанию, который может сбить IDE, и не просто отображать ошибку .
- Токен для закрытия блока и интерполяции блока одинаков, поэтому я не могу выделить их так, как хочу. (это основной)
Моя IDE подсвечивается только на основе токенов, так что это проблема, я бы хотел выделить их по-другому. Так что, в принципе, я хотел бы найти решение для этого, которое делает RBRACE другим токеном, когда он находится в строке.
Я бы предпочел сделать это без предикатов semanti c, потому что я не хочу ie это до языка, но если нужно, я в порядке с этим, мне просто может понадобиться немного больше объяснений, потому что я не использовал их так много.