Beispiel #1
0
 def string_to_int(chars):
     if len(chars) > 19:  # 9223372036854775807L
         raise jsonerror.JsonParseError(
             "Number string is too long : " + str(chars), "string_to_int")
     n = 0
     for i in range(len(chars)):
         n = n * 10 + int(chars[i])
         if n > sys.maxsize:
             raise jsonerror.JsonParseError(
                 "Number is too large : " + str(chars), "string_to_int")
     return n
Beispiel #2
0
 def read_null(self):
     expected = 'null'
     for i in range(len(expected)):
         ech = self.json_char_reader.read_next_char()
         if ech != expected[i]:
             raise jsonerror.JsonParseError(
                 message="Unexpected char:" + ech,
                 where="In class : TokenReader\nIn method : read_string")
Beispiel #3
0
 def read_bool(self):
     ch = self.json_char_reader.read_next_char()
     if ch == 't':
         expected = 'rue'
     elif ch == 'f':
         expected = 'alse'
     else:
         raise jsonerror.JsonParseError(
             message="Unexpected char:" + ch,
             where="In class : TokenReader\nIn method : read_bool")
     for i in range(len(expected)):
         ech = self.json_char_reader.read_next_char()
         if ech != expected[i]:
             raise jsonerror.JsonParseError(
                 message="Unexpected char:" + ech,
                 where="In class : TokenReader\nIn method : read_bool")
     return ch == 't'
Beispiel #4
0
 def string_to_fraction(chars):
     if len(chars) > 16:  # max=1.7976931348623157e+308
         raise jsonerror.JsonParseError(
             "Number string is too long : " + str(chars), "string_to_int")
     d = 0.0
     for i in range(len(chars)):
         n = int(chars[i])
         d += 0 if n == 0 else n / math.pow(10, i + 1)
     return d
Beispiel #5
0
    def read_next_token(self):
        """read next token from json string"""
        try:
            c = self.read_not_white_space()
        except jsonerror.JsonEOFError as eof_error:
            logging.debug(str(eof_error), exc_info=True)
            return TokenType.END_DOC

        if c == '{':
            self.json_char_reader.read_next_char()
            return TokenType.START_OBJ
        elif c == '}':
            self.json_char_reader.read_next_char()
            return TokenType.END_OBJ
        elif c == '[':
            self.json_char_reader.read_next_char()
            return TokenType.START_LIST
        elif c == ']':
            self.json_char_reader.read_next_char()
            return TokenType.END_LIST
        elif c == ':':
            self.json_char_reader.read_next_char()
            return TokenType.COLON
        elif c == ',':
            self.json_char_reader.read_next_char()
            return TokenType.COMMA
        elif c == '\"':
            return TokenType.STRING
        elif c == 'n':
            return TokenType.NULL
        elif c in ('t', 'f'):
            return TokenType.BOOL
        elif c == '-' or ('0' <= c <= '9'):
            return TokenType.NUMBER
        else:
            logging.exception("Parse error when try to get next token.")
            raise jsonerror.JsonParseError(
                message="Parse error when try to get next token.",
                where="In class : TokenReader\nIn method : read_next_token")
Beispiel #6
0
    def json_read(self):
        expected_next_token = JsonReader.TRANSFER_TABLE[0]  # starting state
        while True:
            current_token = self.token_reader.read_next_token()
            if current_token == TokenType.START_OBJ:
                if JsonReader.EXPECT_OBJECT_BEGIN in expected_next_token:
                    self.json_stack.push(
                        StackItem(StackItem.TYPE_JSON_OBJECT, dict()))
                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token]
                else:
                    raise jsonerror.JsonParseError("Unexpected '{' .",
                                                   "Json_read:START_OBJ.")

            elif current_token == TokenType.START_LIST:
                if JsonReader.EXPECT_LIST_BEGIN in expected_next_token:
                    self.json_stack.push(
                        StackItem(StackItem.TYPE_JSON_LIST, list()))
                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token]
                else:
                    raise jsonerror.JsonParseError("Unexpected '['.",
                                                   "Json_read:START_LIST.")

            elif current_token == TokenType.END_OBJ:
                if JsonReader.EXPECT_OBJECT_END in expected_next_token:
                    stack_item = self.json_stack.pop(
                        StackItem.TYPE_JSON_OBJECT)
                    if self.json_stack.is_empty():  # Reach to the EOF:{...}
                        self.json_stack.push(stack_item)
                        expected_next_token = JsonReader.TRANSFER_TABLE[
                            current_token]
                        continue
                    else:
                        stack_item_pre = self.json_stack.pop()
                        # { xx:{...}}
                        if stack_item_pre.get_item_type(
                        ) == StackItem.TYPE_JSON_OBJECT_KEY:
                            item_value_key = stack_item_pre.get_item_value()

                            stack_item_pre_dict = self.json_stack.pop(
                                StackItem.TYPE_JSON_OBJECT)
                            stack_item_pre_dict.get_item_value(
                            )[item_value_key] = stack_item

                            self.json_stack.push(stack_item_pre_dict)
                            expected_next_token = JsonReader.TRANSFER_TABLE[
                                current_token * StackItem.TYPE_JSON_OBJECT_KEY]
                            continue
                        # [ ,{...}, ]
                        elif stack_item_pre.get_item_type(
                        ) == StackItem.TYPE_JSON_LIST:
                            item_value_list = stack_item_pre.get_item_value()
                            item_value_list.append(stack_item)

                            self.json_stack.push(stack_item_pre)
                            expected_next_token = JsonReader.TRANSFER_TABLE[
                                current_token * StackItem.TYPE_JSON_LIST]
                            continue
                raise jsonerror.JsonParseError("Unexpected '}'.",
                                               "Json_read:END_OBJ.")
            elif current_token == TokenType.END_LIST:
                if JsonReader.EXPECT_LIST_END in expected_next_token:
                    stack_item = self.json_stack.pop(StackItem.TYPE_JSON_LIST)
                    if self.json_stack.is_empty():  # Reach to the EOF:[...]
                        self.json_stack.push(stack_item)
                        expected_next_token = JsonReader.TRANSFER_TABLE[
                            current_token]
                        continue
                    else:
                        stack_item_pre = self.json_stack.pop()
                        # { xx:[...]}
                        if stack_item_pre.get_item_type(
                        ) == StackItem.TYPE_JSON_OBJECT_KEY:
                            item_value_key = stack_item_pre.get_item_value()

                            stack_item_pre_dict = self.json_stack.pop(
                                StackItem.TYPE_JSON_OBJECT)
                            stack_item_pre_dict.get_item_value(
                            )[item_value_key] = stack_item

                            self.json_stack.push(stack_item_pre_dict)
                            expected_next_token = JsonReader.TRANSFER_TABLE[
                                current_token * StackItem.TYPE_JSON_OBJECT_KEY]
                            continue
                        # [ ,[...], ]
                        elif stack_item_pre.get_item_type(
                        ) == StackItem.TYPE_JSON_LIST:
                            item_value_list = stack_item_pre.get_item_value()
                            item_value_list.append(stack_item)

                            self.json_stack.push(stack_item_pre)
                            expected_next_token = JsonReader.TRANSFER_TABLE[
                                current_token * StackItem.TYPE_JSON_LIST]
                            continue
                raise jsonerror.JsonParseError("Unexpected '}'.",
                                               "Json_read:END_LIST.")

            elif current_token == TokenType.COLON:
                if JsonReader.EXPECT_COLON in expected_next_token:
                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token]
                else:
                    raise jsonerror.JsonParseError("Unexpected ':' .",
                                                   "Json_read:COLON")

            elif current_token == TokenType.COMMA:
                if JsonReader.EXPECT_COMMA in expected_next_token:
                    if JsonReader.EXPECT_OBJECT_END in expected_next_token:  # {,}
                        expected_next_token = JsonReader.TRANSFER_TABLE[
                            current_token * JsonReader.EXPECT_OBJECT_END]
                        continue
                    elif JsonReader.EXPECT_LIST_END in expected_next_token:  # [,]
                        expected_next_token = JsonReader.TRANSFER_TABLE[
                            current_token * JsonReader.EXPECT_LIST_END]
                        continue
                raise jsonerror.JsonParseError("Unexpected ',' .",
                                               "Json_read:COMMA")

            elif current_token == TokenType.BOOL:
                bool_value = self.token_reader.read_bool()

                if JsonReader.EXPECT_VALUE in expected_next_token:
                    self.json_stack.push(
                        StackItem(StackItem.TYPE_JSON_VALUE, bool_value))
                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token * JsonReader.EXPECT_VALUE]
                elif JsonReader.EXPECT_OBJECT_VALUE in expected_next_token:
                    stack_item = self.json_stack.pop(
                        StackItem.TYPE_JSON_OBJECT_KEY)
                    stack_item_pre_dict = self.json_stack.pop(
                        StackItem.TYPE_JSON_OBJECT)

                    stack_item_pre_dict.get_item_value()[
                        stack_item.get_item_value()] = bool_value
                    self.json_stack.push(stack_item_pre_dict)

                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token * JsonReader.EXPECT_OBJECT_VALUE]
                elif JsonReader.EXPECT_LIST_VALUE in expected_next_token:
                    stack_item_pre_list = self.json_stack.pop(
                        StackItem.TYPE_JSON_LIST)

                    stack_item_pre_list.get_item_value().append(bool_value)
                    self.json_stack.push(stack_item_pre_list)

                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token * JsonReader.EXPECT_LIST_VALUE]
                else:
                    raise jsonerror.JsonParseError("Unexpected bool.",
                                                   "Json_read:BOOL")

            elif current_token == TokenType.NUMBER:
                number_value = self.token_reader.read_number()

                if JsonReader.EXPECT_VALUE in expected_next_token:
                    self.json_stack.push(
                        StackItem(StackItem.TYPE_JSON_VALUE, number_value))
                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token * JsonReader.EXPECT_VALUE]
                elif JsonReader.EXPECT_OBJECT_VALUE in expected_next_token:
                    stack_item = self.json_stack.pop(
                        StackItem.TYPE_JSON_OBJECT_KEY)
                    stack_item_pre_dict = self.json_stack.pop(
                        StackItem.TYPE_JSON_OBJECT)

                    stack_item_pre_dict.get_item_value()[
                        stack_item.get_item_value()] = number_value
                    self.json_stack.push(stack_item_pre_dict)
                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token * JsonReader.EXPECT_OBJECT_VALUE]
                elif JsonReader.EXPECT_LIST_VALUE in expected_next_token:
                    stack_item_pre_list = self.json_stack.pop(
                        StackItem.TYPE_JSON_LIST)

                    stack_item_pre_list.get_item_value().append(number_value)
                    self.json_stack.push(stack_item_pre_list)

                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token * JsonReader.EXPECT_LIST_VALUE]
                else:
                    raise jsonerror.JsonParseError("Unexpected number.",
                                                   "Json_read:NUMBER")

            elif current_token == TokenType.NULL:
                self.token_reader.read_null()

                if JsonReader.EXPECT_VALUE in expected_next_token:
                    self.json_stack.push(
                        StackItem(StackItem.TYPE_JSON_VALUE, None))
                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token * JsonReader.EXPECT_VALUE]
                elif JsonReader.EXPECT_OBJECT_VALUE in expected_next_token:
                    stack_item = self.json_stack.pop(
                        StackItem.TYPE_JSON_OBJECT_KEY)
                    stack_item_pre_dict = self.json_stack.pop(
                        StackItem.TYPE_JSON_OBJECT)

                    stack_item_pre_dict.get_item_value()[
                        stack_item.get_item_value()] = None
                    self.json_stack.push(stack_item_pre_dict)
                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token * JsonReader.EXPECT_OBJECT_VALUE]
                elif JsonReader.EXPECT_LIST_VALUE in expected_next_token:
                    stack_item_pre_list = self.json_stack.pop(
                        StackItem.TYPE_JSON_LIST)

                    stack_item_pre_list.get_item_value().append(None)
                    self.json_stack.push(stack_item_pre_list)

                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token * JsonReader.EXPECT_LIST_VALUE]
                else:
                    raise jsonerror.JsonParseError("Unexpected null.",
                                                   "Json_read:NULL")

            elif current_token == TokenType.STRING:
                string_value = self.token_reader.read_string()

                if JsonReader.EXPECT_VALUE in expected_next_token:
                    self.json_stack.push(
                        StackItem(StackItem.TYPE_JSON_VALUE,
                                  unicode(string_value)))
                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token * JsonReader.EXPECT_VALUE]
                elif JsonReader.EXPECT_OBJECT_KEY in expected_next_token:
                    self.json_stack.push(
                        StackItem(StackItem.TYPE_JSON_OBJECT_KEY,
                                  unicode(string_value)))
                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token * JsonReader.EXPECT_OBJECT_KEY]
                elif JsonReader.EXPECT_OBJECT_VALUE in expected_next_token:
                    stack_item = self.json_stack.pop(
                        StackItem.TYPE_JSON_OBJECT_KEY)
                    stack_item_pre_dict = self.json_stack.pop(
                        StackItem.TYPE_JSON_OBJECT)

                    stack_item_pre_dict.get_item_value()[
                        stack_item.get_item_value()] = unicode(string_value)
                    self.json_stack.push(stack_item_pre_dict)
                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token * JsonReader.EXPECT_OBJECT_VALUE]
                elif JsonReader.EXPECT_LIST_VALUE in expected_next_token:
                    stack_item_pre_list = self.json_stack.pop(
                        StackItem.TYPE_JSON_LIST)

                    stack_item_pre_list.get_item_value().append(string_value)
                    self.json_stack.push(stack_item_pre_list)

                    expected_next_token = JsonReader.TRANSFER_TABLE[
                        current_token * JsonReader.EXPECT_LIST_VALUE]
                else:
                    raise jsonerror.JsonParseError("Unexpected string '\"''.",
                                                   "Json_read:STRING")
            elif current_token == TokenType.END_DOC:
                if JsonReader.EXPECT_DOC_END in expected_next_token:
                    stack_item_last = self.json_stack.pop()
                    if self.json_stack.is_empty():
                        return self.stack_item_to_json_data(stack_item_last)
                raise jsonerror.JsonParseError("Unexpected JSON_END.",
                                               "Json_read:END_DOC")
Beispiel #7
0
    def read_number(self):
        """
        number
            int
            int frac
            int exp
            int frac exp
        int
            digit
            digit1-9 digits
            - digit
            - digit1-9 digits
        frac
            . digits
        exp
            e digits
        digits
            digit
            digit digits
        """
        int_part = []  # ###.xxxExxx
        fra_part = []  # xxx.###Exxx
        exp_part = []  # xxx.xxxE###

        INT_PART = 0
        FRA_PART = 1
        EXP_PART = 2
        NUMBER_END = 3

        has_fra_part = False
        has_exp_part = False

        ch = self.json_char_reader.read_top_char()
        minus_sign = (ch == '-')
        exp_minus_sign = False
        if minus_sign:
            self.json_char_reader.read_next_char()

        status = INT_PART
        while True:
            if self.json_char_reader.has_more_char():
                ch = self.json_char_reader.read_top_char()
            else:
                status = NUMBER_END

            if status == INT_PART:
                if '0' <= ch <= '9':
                    int_part.append(self.json_char_reader.read_next_char())

                elif ch == '.':
                    if not int_part:
                        raise jsonerror.JsonParseError(
                            message="Expected int_part : ###.xxxExxx but None",
                            where=
                            "In class : TokenReader\nIn method : read_number_INT_PART_."
                        )
                    self.json_char_reader.read_next_char()
                    has_fra_part = True
                    status = FRA_PART

                elif ch in ('e', 'E'):
                    if not int_part:
                        raise jsonerror.JsonParseError(
                            message="Expected int_part : ###.xxxExxx but None",
                            where=
                            "In class : TokenReader\nIn method : read_number_INT_PART_e"
                        )
                    self.json_char_reader.read_next_char()
                    has_exp_part = True
                    sign_char = self.json_char_reader.read_top_char()
                    if (sign_char not in ('-', '+')) and (
                            '0' > sign_char) and (sign_char > '9'):
                        raise jsonerror.JsonParseError(
                            message="Expected '-' or '+' or digit but is " +
                            sign_char,
                            where=
                            "In class : TokenReader\nIn method : read_number_INT_PART_e"
                        )
                    elif sign_char in ('-', '+'):
                        exp_minus_sign = (sign_char == '-')
                        self.json_char_reader.read_next_char()
                    status = EXP_PART

                else:
                    if not int_part:
                        raise jsonerror.JsonParseError(
                            message="Unexpected char:" +
                            self.json_char_reader.read_next_char(),
                            where=
                            "In class : TokenReader\nIn method : read_number_INT_PART_"
                        )
                    status = NUMBER_END

            elif status == FRA_PART:
                if '0' <= ch <= '9':
                    fra_part.append(self.json_char_reader.read_next_char())

                elif ch in ('e', 'E'):
                    if not int_part:
                        raise jsonerror.JsonParseError(
                            message="Expected int_part : ###.xxxExxx but None",
                            where=
                            "In class : TokenReader\nIn method : read_number_FRA_PART_e"
                        )
                    self.json_char_reader.read_next_char()
                    has_exp_part = True
                    sign_char = self.json_char_reader.read_top_char()
                    if (sign_char not in ('-', '+')) and (
                            '0' > sign_char) and (sign_char > '9'):
                        raise jsonerror.JsonParseError(
                            message="Expected '-' or '+' or digit but is " +
                            sign_char,
                            where=
                            "In class : TokenReader\nIn method : read_number_FRA_PART_e"
                        )
                    elif sign_char in ('-', '+'):
                        exp_minus_sign = (sign_char == '-')
                        self.json_char_reader.read_next_char()
                    status = EXP_PART

                else:
                    if not fra_part:
                        raise jsonerror.JsonParseError(
                            message="Unexpected char:" +
                            self.json_char_reader.read_next_char(),
                            where=
                            "In class : TokenReader\nIn method : read_number_FRA_PART_"
                        )
                    status = NUMBER_END

            elif status == EXP_PART:
                if '0' <= ch <= '9':
                    exp_part.append(self.json_char_reader.read_next_char())
                else:
                    if not exp_part:
                        raise jsonerror.JsonParseError(
                            message="Unexpected char:" +
                            self.json_char_reader.read_next_char(),
                            where=
                            "In class : TokenReader\nIn method : read_number_EXP_PART_"
                        )
                    status = NUMBER_END

            elif status == NUMBER_END:  # Start to convert string to number
                if not int_part:
                    raise jsonerror.JsonParseError(
                        message="Expected int_part : ###.xxxExxx but None",
                        where=
                        "In class : TokenReader\nIn method : read_number_END")
                if minus_sign:
                    int_value = -self.string_to_int(int_part)
                else:
                    int_value = self.string_to_int(int_part)

                if not has_fra_part and not has_exp_part:
                    return int_value
                if has_fra_part and not fra_part:
                    raise jsonerror.JsonParseError(
                        "Expected fra_part : xxx.###Exxx but None",
                        "In class : TokenReader\nIn method : read_number_END")
                if has_fra_part:
                    if minus_sign:
                        fra_value = -self.string_to_fraction(fra_part)
                    else:
                        fra_value = self.string_to_fraction(fra_part)
                else:
                    fra_value = 0.0

                if has_exp_part and not exp_part:
                    raise jsonerror.JsonParseError(
                        "Expected exp_part : xxx.xxxE### but None",
                        "In class : TokenReader\nIn method : read_number_END")
                if has_exp_part:
                    if exp_minus_sign:
                        number = (int_value + fra_value) * math.pow(
                            10, -self.string_to_int(exp_part))
                    else:
                        number = (int_value + fra_value) * math.pow(
                            10, self.string_to_int(exp_part))

                    if minus_sign and number > 0:  # eg: -2.2E2 < 0
                        number = -number
                else:
                    number = int_value + fra_value

                if number > sys.float_info.max:
                    raise jsonerror.JsonParseError(
                        "Number is too large " + str(number),
                        "In class : TokenReader\nIn method : read_number_END")
                return number
Beispiel #8
0
    def read_string(self):
        string = []
        # first char must be "
        ch = self.json_char_reader.read_next_char()
        if ch != '\"':
            raise jsonerror.JsonParseError(
                message="Expected \" but actual is: " + ch,
                where="In class : TokenReader\nIn method : read_string")
        while True:
            ch = self.json_char_reader.read_next_char()
            if ch == '\\':  # escape: \" \\ \/ \b \f \n \r \t
                ech = self.json_char_reader.read_next_char()

                if ech == "\"":
                    string.append('\"')
                elif ech == "\\":
                    string.append("\\")
                elif ech == "/":
                    string.append("/")
                elif ech == "b":
                    string.append("\b")
                elif ech == "f":
                    string.append("\f")
                elif ech == "n":
                    string.append("\n")
                elif ech == "r":
                    string.append("\r")
                elif ech == "t":
                    string.append("\t")
                elif ech == "u":  # read an unicode uXXXX
                    # u = 0
                    # for i in range(4):
                    #     uch = self.json_char_reader.read_next_char()
                    #     if '0' <= uch <= '9':
                    #         u = (u << 4) + int(uch)
                    #     elif 'a' <= uch <= 'f':
                    #         u = (u << 4) + int(uch, 16)
                    #     elif 'A' <= uch <= "F":
                    #         u = (u << 4) + int(uch, 16)
                    uni_str = ''
                    for i in range(4):
                        uch = self.json_char_reader.read_next_char()
                        if '0' <= uch <= '9' or 'a' <= uch <= 'f' or "A" <= uch <= "F":
                            uni_str += uch
                        else:
                            raise jsonerror.JsonParseError(
                                message="Unexpected char:" + uch,
                                where=
                                "In class : TokenReader\nIn method : read_string"
                            )
                    # string.append(unicode(u))
                    string.append(('\u' + uni_str).decode('unicode-escape')
                                  # .encode('utf-8')
                                  )
                else:
                    raise jsonerror.JsonParseError(
                        message="Unexpected char:" + ech,
                        where="In class : TokenReader\nIn method : read_string"
                    )

            elif ch == '\"':  # end of string
                break
            elif ch == '\r' or ch == '\n':
                raise jsonerror.JsonParseError(
                    message="Unexpected char:" + ch,
                    where="In class : TokenReader\nIn method : read_string")
            else:
                string.append(ch)
        return ''.join(string)