【问题标题】:What is the ANTLR4 equivalent of a ! in a lexer rule?什么是 ANTLR4 等价物!在词法分析器规则中?
【发布时间】:2015-09-13 12:56:48
【问题描述】:

我正在将旧的 ANTLR 2 语法转换为 ANTLR 4,但字符串规则有问题。

STRING :
    '\''!
    (
        ~('\'' | '\\' | '\r' | '\n')
    )*
    '\''!
    ;

这将创建一个STRING 标记,其文本包含字符串的内容,但不包含开始和结束引号,因为引号文字后面有! 符号。 p>

ANTLR 4 扼流圈 ! 符号 ('!' came as a complete surprise to me (AC0050)) 但如果我不使用它,我最终会得到包含引号的标记,这不是我想要的。将其移植到 ANTLR 4 的正确方法是什么?

【问题讨论】:

    标签: antlr antlr4


    【解决方案1】:

    Antlr4 通常将标记视为不可变的,至少在不支持 ! 的语言中立等效项的意义上。

    也许完成等效的最简单方法是:

    string : str=STRING { Strings.unquote($str); } ; 
    STRING : SQuote ~[\r\n\\']* SQuote ;
    fragment SQuote : '\'' ;
    

    Strings.unquote 在哪里:

    public static void unquote(Token token) {
        CommonToken ct = (CommonToken) token;
        String text = ct.getText();
        text = .... unquote it ....
        ct.setText(text);
    }
    

    使用解析器规则的原因是词法分析器(当前)不支持属性引用。尽管如此,它仍然可以根据词法分析器规则完成 - 只是需要稍微多一点努力来挖掘令牌。

    修改标记文本的替代方法是使用自定义字段和方法实现自定义标记。如果有兴趣,请参阅this answer

    【讨论】:

      【解决方案2】:

      我相信 ANTLR4 可以使用 lexical modes and lexer commands 解决您的问题。

      这里有一个例子,我认为它完全符合你的需要(虽然是双引号,但它很容易解决):

      lexer grammar Strings;
      LQUOTE : '"' -> more, mode(STR) ;
      WS : [ \r\t\n]+ -> skip ;
      
      mode STR;
      STRING : '"' -> mode(DEFAULT_MODE) ; // token we want parser to see
      TEXT : . -> more ; // collect more text for string
      

      【讨论】:

      • 这并没有解决 OP 的问题 - 如何使用 排除 引号的文本值创建令牌(这就是 Antlr2 ! 运算符所做的)。这个提议的解决方案完全无法实现这一目标。
      猜你喜欢
      • 1970-01-01
      • 2019-05-07
      • 2017-12-24
      • 2019-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-20
      相关资源
      最近更新 更多