2011-10-08 72 views
0

我正在寫一個類似C語言的分析器/解釋器,我需要解釋轉義字符。其中之一是帶有這種模式的unicode轉義序列「\ uXXXX」,其中X是某個十六進制數。ANTLR不匹配unicode轉義字符

我ANTLR規則是這樣的:

public char returns [char c] 
    : '\\"' { $c = '"'; } 
    | '\\\\' { $c = '\\'; } 
    | '\\/' { $c = '/'; } 
    | '\\b' { $c = '\b'; } 
    | '\\f' { $c = '\f'; } 
    | '\\n' { $c = '\n'; } 
    | '\\r' { $c = '\r'; } 
    | '\\t' { $c = '\t'; } 
    | '\\u' HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT { $c = 'e'; } 
    | ~('\\' | '"') { $c = '/'; } 
    ; 

fragment HEXDIGIT 
    : ('0'..'9'|'a'..'f'|'A'..'F') 

我餵養它這個字符串「\ u1234」爲此,我期待一個「e」,但我得到一個「/」,而不是它是其他一切的後備規則。

是否有一些魔法juju繼續與片段和規則或我不知道的東西?

+0

片段只應該在詞法規則中使用,但「字符」長相就像解析器規則一樣。 – 2011-10-08 17:17:30

+0

啊對,我把HEXNUMBER作爲HEXDIGIT的四項序列。不知道爲什麼ANTLR不會在這種情況下呻吟HEXDIGIT和DIGIT之間的重疊...... –

回答

1

正如亞當提到,char是目前解析器規則,但應作出一個詞法規則來代替,在這種情況下,你不能讓它返回char(詞法規則總是返回Token的實例! )。

可以使用其setText(...)方法這樣調整令牌的內文(假設Java是目標語言):

// lexer rules start with a capital! 
Char 
    : '\\"'          { setText("\""); } 
    | '\\\\'         { setText("\\"); } 
    | '\\/'          { setText("/"); } 
    | '\\b'          { setText("\b"); } 
    | '\\f'          { setText("\f"); } 
    | '\\n'          { setText("\n"); } 
    | '\\r'          { setText("\r"); } 
    | '\\t'          { setText("\t"); } 
    | '\\u' HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT 
    { 
     String hex = getText(); 
     int i = Integer.parseInt(hex.substring(2), 16); 
     setText(hex + " base 10 = " + i); 
    } 
    | ~('\\' | '"') 
    ; 

fragment HEXDIGIT 
    : ('0'..'9'|'a'..'f'|'A'..'F') 
    ;