我正在为类c语言编写解析器/解释器,我需要解释转义字符。其中之一是unicode转义序列,其模式为"uXXXX",其中X是某个十六进制数。
我的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",但我得到一个"/",而不是这是其他一切的回退规则。
是不是有一些我不知道的关于碎片和规则的魔法在起作用?
正如Adam所提到的,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')
;