private JsonValue parseValue() throws JsonException {
        Token tok;
        tok = lexer.nextToken();

        switch (tok.type) {
            case TokenTypes.INTEGER:
                return new JsonInteger(Integer.parseInt(tok.value));
            case TokenTypes.NUMBER:
                return new JsonNumber(Double.parseDouble(tok.value));
            case TokenTypes.STRING:
                return new JsonString(tok.value);
            case TokenTypes.NULL:
                return new JsonNull();
            case TokenTypes.TRUE:
                return new JsonTrue();
            case TokenTypes.FALSE:
                return new JsonFalse();

            case TokenTypes.LBRACKET:
                lexer.putBack(tok);
                return parseArray();

            case TokenTypes.LBRACE:
                lexer.putBack(tok);
                return parseObject();
        }
        throw new JsonException("Expecting token type " + TokenTypes.asString(tok.type), tok.lineNum, tok.colNum);
    }