如何从 JavaCC 令牌的图像中删除双引号?

How do you remove double quotes from the image of a JavaCC token?

在 JavaCC 中,我接受以下条件的字符串:

   < STRING : "\"" ("\" ~[] | ~["\"","\"] )* "\"" > 

因此图像最终会打印任何字符串但带有另一组双引号。

例如,我将输入:“这是一个句子。”

并且值将结果:“”这是一个句子。“”存储在一个字符串变量中。

在 Java 中有没有办法删除多余的双引号集,以便只打印:"This is a sentence."?

str = str.substring(1,str.length()-1)

Javacc 的替代品

Parsing Strings with JavaCC

如果您的令牌匹配的输入是 "Hello",那么令牌的 image 字段的值将是一个 7 个字符的字符串,其第一个和最后一个字符是双引号字符。它们并不是真正额外的,它们只是在输入中。说你写

void foo() : {
    Token t ; }
{
    t = <STRING>
    { System.out.println( t.image ) ; }
}

这将打印 7 个字符,然后是换行符。

现在,如果您不想要这些字符,那么@Bryan 的回答就可以了。

void foo() : {
    Token t ; }
{
    t = <STRING>
    { { String nakedImage = t.image.substring(1,t.image.length()-1) ;
        System.out.println( nakedImage ) ; } }
}

请注意,没有删除引号。 String Java 中的对象是不可变的,这意味着它们无法更改。真正发生的是创建了一个新的 String 对象并将对它的引用分配给 nakedImage 变量。 t.image 引用的 String 对象保持不变。

现在你还有处理反斜杠的问题。如果输入的是“Hello\tWorld”,那么t.image的长度为14个字符,nakedImage的长度为12个字符。我此时所做的是 运行 字符串通过函数构建一个新字符串,该字符串具有单个字符,其中 nakedImage 具有转义序列。因此,此示例中该函数的结果将是 11 个字符长。

void foo() : {
    Token t ; }
{
    t = <STRING>
    { { String nakedImage = t.image.substring(1,t.image.length()-1) ;
        String unescapedImage = unescape( nakedImage ) ;
        System.out.println( unescapedImage ) ; } }
}

这是一个这样的函数,基于我为 Java 编译器编写的函数。

private static String unescape( String str ) {
    StringBuffer result = new StringBuffer() ;
    for( int i=0, len = str.length() ; i<len ; ) {
        char ch = str.charAt(i) ;

        // Set ch and increment i ;
        if( ch == '\' )  {
            ch = str.charAt(i+1) ;
            switch( ch ) {
                case 'b' : ch = '\b' ; i += 2 ; break ;
                case 't' : ch = '\t' ; i += 2 ; break ;
                case 'n' : ch = '\n' ; i += 2 ; break ;
                case 'f' : ch = '\f' ; i += 2 ; break ;
                case 'r' : ch = '\r' ; i += 2 ; break ;
                case '"' : case '\'' : case '\' : i+= 2 ; break ;
                default: 
                    /*TODO Deal with errors. */ } }
        else {
            i += 1 ; }
        result.append( ch ) ; }
    return result.toString() ;
}