2012-07-10 62 views
0

當我拿到這些規則令牌如何在ANTLR擺脫「在我的字符串?

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

它最終抓住'text',而不是僅僅text,我可以很容易地取出''自己,但想知道我怎麼能得到ANTLR刪除它?

回答

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' | '"' | '\\') 
; 
1

一種方法是定義字符串的內容作爲一個單獨的類別,例如

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

然後捕獲STRINGCONTENTS值。