我一直在查看ANTLR v3文档(以及我对"The Definitive ANTLR reference"的可靠副本),我似乎无法找到一种在字符串文字中实现转义序列的简洁方法(我目前正在使用Java目标).我希望能够做到这样的事情:
fragment ESCAPE_SEQUENCE : '\\' '\'' { setText("'"); } ; STRING : '\'' (ESCAPE_SEQUENCE | ~('\'' | '\\'))* '\'' { // strip the quotes from the resulting token setText(getText().substring(1, getText().length() - 1)); } ;
例如,我希望输入标记" 'Foo\'s House'
"成为字符串" Foo's House
".
不幸的是,片段中的setText(...)
调用ESCAPE_SEQUENCE
设置了整个STRING
令牌的文本,这显然不是我想要的.
有没有办法实现这个语法而不添加一个方法来返回结果字符串并手动替换转义序列(例如,setText(escapeString(getText()))
在STRING
规则中的某些内容)?
以下是我在我编写的JSON解析器中完成此操作的方法.
STRING @init{StringBuilder lBuf = new StringBuilder();} : '"' ( escaped=ESC {lBuf.append(getText());} | normal=~('"'|'\\'|'\n'|'\r') {lBuf.appendCodePoint(normal);} )* '"' {setText(lBuf.toString());} ; fragment ESC : '\\' ( 'n' {setText("\n");} | 'r' {setText("\r");} | 't' {setText("\t");} | 'b' {setText("\b");} | 'f' {setText("\f");} | '"' {setText("\"");} | '\'' {setText("\'");} | '/' {setText("/");} | '\\' {setText("\\");} | ('u')+ i=HEX_DIGIT j=HEX_DIGIT k=HEX_DIGIT l=HEX_DIGIT {setText(ParserUtil.hexToChar(i.getText(),j.getText(), k.getText(),l.getText()));} ) ;
对于ANTLR4,Java目标和标准转义字符串语法,我使用了一个专用的单例类:CharSupport来翻译字符串.它在antlr API中可用:
STRING : '"' ( ESC | ~('"'|'\\'|'\n'|'\r') )* '"' { setText( org.antlr.v4.misc.CharSupport.getStringFromGrammarStringLiteral( getText() ) ); } ;
正如我在V4文档和实验中看到的那样,lexer部分不再支持@init!