我正在将旧的ANTLR 2语法转换为ANTLR 4,并且我在字符串规则方面遇到了麻烦。
STRING :
'''!
(
~(''' | '\' | 'r' | 'n')
)*
'''!
;
这将创建一个STRING
令牌,其文本包含字符串的内容,但是不包含起始和结束引号,因为引号后面有!
符号。
ANTLR 4阻塞!
符号,('!' came as a complete surprise to me (AC0050)
),但如果我把它关闭,我最终得到包含引号的令牌,这不是我想要的。把这个移植到ANTLR 4的正确方法是什么?
Antlr4通常将令牌视为不可变的,至少在不支持与!
无关的语言对等物的意义上。
也许最简单的方法是:
string : str=STRING { Strings.unquote($str); } ;
STRING : SQuote ~[rn\']* 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);
}
使用解析器规则的原因是词法分析器(目前)不支持属性引用。尽管如此,它仍然可以在词法分析器规则上完成—只是需要更多的努力来挖掘令牌。
修改令牌文本的另一种方法是使用自定义字段和方法实现自定义令牌。
我相信在ANTLR4中,您的问题可以使用词法模式和词法分析器命令来解决。
这里有一个例子,我认为这正是你需要的(虽然是双引号,但这是一个简单的修复):
lexer grammar Strings;
LQUOTE : '"' -> more, mode(STR) ;
WS : [ rtn]+ -> skip ;
mode STR;
STRING : '"' -> mode(DEFAULT_MODE) ; // token we want parser to see
TEXT : . -> more ; // collect more text for string