当前位置:  开发笔记 > 编程语言 > 正文

如何在ANTLR 3中处理字符串文字中的转义序列?

如何解决《如何在ANTLR3中处理字符串文字中的转义序列?》经验,为你挑选了2个好方法。

我一直在查看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规则中的某些内容)?



1> Bruno Ransch..:

以下是我在我编写的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()));}

        )
    ;


我使用了这种方法,但请注意,我必须在每一步附加"getText()"而不是"escaped.getText()".该片段将未转义的文本写入整个STRING令牌,getText()返回该令牌.对我来说,escaped.getText()返回原始片段,反斜杠完好无损.

2> 小智..:

对于ANTLR4,Java目标和标准转义字符串语法,我使用了一个专用的单例类:CharSupport来翻译字符串.它在antlr API中可用:

STRING          :   '"' 
                (   ESC  
                |   ~('"'|'\\'|'\n'|'\r') 
                )* 
                    '"' { 
                        setText( 
                            org.antlr.v4.misc.CharSupport.getStringFromGrammarStringLiteral(
                                getText()
                            )
                        ); 
                    }
                ;

正如我在V4文档和实验中看到的那样,lexer部分不再支持@init!

推荐阅读
手机用户2402851155
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有