private String string ( ) { char quote = peek ( 0 ) ; int start = ++ _x ; boolean has_escapes = false ; while ( _x < _str . length ( ) ) { char c = peek ( 0 ) ; if ( c == ' ' ) { has_escapes = true ; char cc = peek ( 1 ) ; if ( simpleEscapeSequences . containsKey ( cc ) ) { _x += 2 ; } else if ( cc == ' ' ) { _x += 4 ; // e.g: \x5A } else if ( cc == ' ' ) { _x += 6 ; // e.g: \u1234 } else if ( cc == ' ' ) { _x += 10 ; // e.g: \U0010FFFF } else throw new IllegalASTException ( "Invalid escape sequence \\" + cc ) ; } else if ( c == quote ) { _x ++ ; if ( has_escapes ) { StringBuilder sb = new StringBuilder ( ) ; for ( int i = start ; i < _x - 1 ; i ++ ) { char ch = _str . charAt ( i ) ; if ( ch == ' ' ) { char cc = _str . charAt ( ++ i ) ; if ( simpleEscapeSequences . containsKey ( cc ) ) { sb . append ( simpleEscapeSequences . get ( cc ) ) ; } else { int n = ( cc == ' ' ) ? 2 : ( cc == ' ' ) ? 4 : ( cc == ' ' ) ? 8 : - 1 ; int hex = - 1 ; try { hex = StringUtils . unhex ( _str . substring ( i + 1 , i + 1 + n ) ) ; } catch ( NumberFormatException e ) { throw new IllegalASTException ( e . toString ( ) ) ; } if ( hex > 0x10FFFF ) throw new IllegalASTException ( "Illegal unicode codepoint " + hex ) ; sb . append ( Character . toChars ( hex ) ) ; i += n ; } } else { sb . append ( ch ) ; } } return sb . toString ( ) ; } else { return _str . substring ( start , _x - 1 ) ; } } else { _x ++ ; } } throw new IllegalASTException ( "Unterminated string at " + start ) ; }
Parse a string from the token stream .