Antlr4中的字符串插值

Antlr4中的字符串插值,antlr,antlr4,Antlr,Antlr4,我有一个使用模式进行字符串插值的语法: 大致如下: lexer grammar Example; //default mode tokens LBRACE: '{' -> pushMode(DEFAULT_MODE); RBRACE: '}' -> popMode; OPEN_STRING: '"' -> pushMode(STRING); mode STRING; ID_INTERPOLATION: '$' IDEN; OPEN_EXPR_INTERPOLATION: '

我有一个使用模式进行字符串插值的语法: 大致如下:

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;
现在,它可以正常工作,并以我想要的方式标记所有内容,但它确实有两个缺陷

  • 如果RBRACES的数量过多,它会弹出第一个默认模式,这会使IDE出现故障,而不仅仅是显示错误
  • 用于闭合块和闭合插值的标记是相同的,因此我无法根据需要高亮显示它们。(这是主要的)
  • 我的IDE只基于令牌高亮显示,所以这是一个问题,我希望能够以不同的方式高亮显示它们。所以基本上我想要一个解决方案,当RBRACE在一个字符串中时,它是一个不同的令牌


    我宁愿不使用语义谓词,因为我不想把它束缚在一种语言上,但如果需要的话,我可以接受,我可能需要更多的解释,因为我没有太多地使用它们。

    谢谢@sepp2k帮助我解决我的问题

    这是一个有点黑客,但它正是我所需要的

    我通过将RBRACE上的popMode更改为以下方式解决了此问题:

    RBRACE: '}' {
        if(_modeStack.size() > 0) {
            popMode();
            if(_mode != DEFAULT_MODE) {
                setType(EXPR_INTERPOLATION);
            }
        }
    };
    
    我还将解析器更改为

    string_part: TEXT | ID_INTERPOLATION | EXPR_INTERPOLATION expr EXPR_INTERPOLATION;
    

    我知道在特定情况下更改标记类型是非常困难的,但它为我完成了任务,因此我将保留它,除非我找到一种不太麻烦的方法来完成此操作。

    用于关闭块和关闭插值的标记是相同的
    :我不明白,我看到两个不同的字符被用来“关闭”东西:
    }
    另外,为什么要使用
    LBRACE:'{'->pushMode(默认模式)
    RBRACE:'}'->popMode是否存在(即模式推送和弹出)?或者你是否试图过多地简化问题?在这种情况下,请编辑你的问题,使之更接近你原来的语法。我指的是一条规则,我没有包含在这段代码中,我确实简化了一点,我使用LBRACE推送模式的原因是RBRACE使用的每个其他位置都与LBRACE结合,所以我不想意外地弹出最外层的模式。我想区分每次使用RBRACE(当它用于封装代码位时)和每次使用它进行插值时。因此,当返回到字符串模式时,将匹配不同的标记。我正在弹出RBRACE,这样当您完成插值后,它将返回到字符串模式,因此您可以说:
    “x+1=${x+1}”
    我想让Bart困惑的是您似乎忘记了
    ->pushMode(默认模式)
    OPEN\u EXPR\u INTERPOLATION
    规则中。无论如何,我相信通过添加跟踪嵌套的
    {}
    s的操作,您可以得到想要的。类似于,但您希望使用堆栈而不仅仅是计数器来跟踪何时弹出
    {}
    和何时弹出
    ${}
    ,以便可以适当地更改令牌类型。
    string_part: TEXT | ID_INTERPOLATION | EXPR_INTERPOLATION expr EXPR_INTERPOLATION;