protected StringValue string() throws ParserException {
        Character openQuote = current;
        int initialPosition = pos;
        boolean escape = false;
        next();
        StringBuilder value = new StringBuilder();
        StringBuilder string = new StringBuilder();
        while (!end()) {
            if (escape) {
                //TODO implement UNICODE
                if (current == openQuote || current == '\\') {
                    value.append(current);
                    string.append(current);
                    escape = false;
                } else {
                    throw new ParserException("Invalid escape character at position " + pos);
                }
            } else {
            	if (current == openQuote) break;
                string.append(current);
                if (current == '\\') {
                    escape = true;
                } else {
                    value.append(current);
                }
            }
            next();
        }

        if (current != openQuote) {
            throw new ParserException("String not closed!");
        }
        next();
        return new StringValue(new Context(content, string.toString(), initialPosition, pos), value.toString());

    }
protected StringValue string() throws ParserException {
        Character openQuote = current;
        int initialPosition = pos;
        boolean escape = false;
        next();
        StringBuilder value = new StringBuilder();
        StringBuilder string = new StringBuilder();
        while (!end()) {
            if (escape) {
                
                if (current == openQuote || current == '\\') {
                    value.append(current);
                    string.append(current);
                    escape = false;
                } else {
                    throw new ParserException("Invalid escape character at position " + pos);
                }
            } else {
            	if (current == openQuote) break;
                string.append(current);
                if (current == '\\') {
                    escape = true;
                } else {
                    value.append(current);
                }
            }
            next();
        }

        if (current != openQuote) {
            throw new ParserException("String not closed!");
        }
        next();
        return new StringValue(new Context(content, string.toString(), initialPosition, pos), value.toString());

    }
protected StringValue string ( ) throws ParserException { Character openQuote = current ; int initialPosition = pos ; boolean escape = false ; next ( ) ; StringBuilder value = new StringBuilder ( ) ; StringBuilder string = new StringBuilder ( ) ; while ( ! end ( ) ) { if ( escape ) { //TODO implement UNICODE
 if ( current == openQuote || current == ' ' ) { value . append ( current ) ; string . append ( current ) ; escape = false ; } else { throw new ParserException ( "Invalid escape character at position " + pos ) ; } } else { if ( current == openQuote ) break ; string . append ( current ) ; if ( current == ' ' ) { escape = true ; } else { value . append ( current ) ; } } next ( ) ; } if ( current != openQuote ) { throw new ParserException ( "String not closed!" ) ; } next ( ) ; return new StringValue ( new Context ( content , string . toString ( ) , initialPosition , pos ) , value . toString ( ) ) ; }
string    {string1}|{string2}
string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
nonascii  [^\0-\177]
escape    {unicode}|\\[^\n\r\f0-9a-f]
unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
nl        \n|\r\n|\r|\f
string { string1 } | { string2 } string1 \ ( [ ^ \ n \ r \ f \\ ] | \\ { nl } | { nonascii } | { escape } ) * \ string2 \ ( [ ^ \ n \ r \ f \\ ] | \\ { nl } | { nonascii } | { escape } ) * \ nonascii [ ^ \ 0 - \ 177 ] escape { unicode } | \\ [ ^ \ n \ r \ f0 - 9a - f ] unicode \\ [ 0 - 9a - f ] { 1 6 } ( \ r \ n| [ \ n \ r \ t \ f ] ) ? nl \ n| \ r \ n| \ r| \ f