如何摆脱“围绕我在ANTLR中的字符串?

时间:2012-07-10 03:26:39

标签: antlr antlr3

当我获得带有这些规则的令牌时

STRINGA :   '"' (options {greedy=false;}: ESC | .)* '"';
STRINGB :   '\'' (options {greedy=false;}: ESC | .)* '\'';

最终抓住了'text'而不仅仅是text。我可以轻松删除'',但是想知道如何让ANTLR删除它?

2 个答案:

答案 0 :(得分:1)

一种方法是将字符串内容定义为单独的类别,例如

STRINGA : '"' STRINGCONTENTS '"';
STRINGB : '\'' STRINGCONTENTS '\'';

然后捕获STRINGCONTENTS值。

答案 1 :(得分:1)

您需要一些自定义代码。此外,您不应该在规则中使用.(点):您应该明确定义您想匹配 反斜杠之外的所有内容(假设是ESQ开头的),引用换行符

这样的事情可以做到:

grammar T;

parse
 : STRING EOF {System.out.println($STRING.text);}
 ;

STRING
 : '"' (ESQ | ~('"' | '\\' | '\r' | '\n'))* '"'
   {
     String matched = getText();
     StringBuilder builder = new StringBuilder();

     for(int i = 1; i < matched.length() - 1; i++) {
       char ch = matched.charAt(i);
       if(ch == '\\') {
         i++;
         ch = matched.charAt(i);
         switch(ch) {
           case 'n': builder.append('\n'); break;
           case 't': builder.append('\t'); break;
           default: builder.append(ch); break;
         }
       }
       else {
         builder.append(ch);
       }
     }

     setText(builder.toString());
   }
 ;

fragment ESQ
 : '\\' ('n' | 't' | '"' | '\\')
 ;

如果您现在解析输入"tabs:'\t\t\t'\nquote:\"\nbackslash:\\",则以下内容将打印到控制台:

tabs:'         '
quote:"
backslash:\

为了保持语法清洁,您当然可以使用自定义方法移动代码:

grammar T;

@lexer::members {
  private String fix(String str) {
    ...
  }
}

parse
 : STRING EOF {System.out.println($STRING.text);}
 ;

STRING
 : '"' (ESQ | ~('"' | '\\' | '\r' | '\n'))* '"' {setText(fix(getText()));}
 ;

fragment ESQ
 : '\\' ('n' | 't' | '"' | '\\')
 ;