用Python手写一个JSON解析程序

JSON的组成

一个合法的JSON字符串可以包含这几种元素:

  1. 特殊符号,如 "{"  "}" 表示一个JSON Object,"[" "]" 表示一个JSON Array,":"用于分隔key-value,"," 用于分隔两个元素
  2. 字符串,用引号引起来
  3. 数字,包含0-9,浮点数带有".",表示符号可带有"+" "-"
  4. 常量有true,false,null

 

分词(or 词法分析)

分词的主要目的是将字符串分割成一个个合法的元素,其中每一个特殊符号都为一个元素,一个完整的字符串表达是一个元素,一个完整的数字表达等等

不难发现,特殊元素都只包含一个字符,常量,数字的表示中间均不会出现空格或其他不相关字符,因此可以轻易地用表达的特征区分,例如数字可以匹配一段连续的且所有字符都是在0-9或有"." "+", "-"的子序列(至于表达是否合法,稍后再做处理)。而字符串较为特殊,字符串原则上讲可以包含任何字符,但字符串也有自己的特征,以 " 开始,又以两一个 " 结束,虽然字符串中间也可能出现 " 但若是合法表达,就必须使用 '\' 转义 ,注意处理转义字符就好了,下面是词法分析的代码

    class __Tokener:
        def __init__(self, json_str):
            self.__str = json_str
            self.__i = 0
            self.__cur_token = None

        def __cur_char(self):
            if self.__i < len(self.__str):
                return self.__str[self.__i]
            return ''

        def __move_i(self, step=1):
            if self.__i < len(self.__str):
                self.__i += step

        def __next_string(self):    
            outstr = ''
            trans_flag = False
            self.__move_i()
            while self.__cur_char() != '':
                ch = self.__cur_char()
                if ch == '\\':    # 注意处理转义
                    trans_flag = True
                else:
                    if not trans_flag:
                        if ch == '"':
                            break
                    else:
                        trans_flag = False
                outstr += ch
                self.__move_i()
            return outstr

        def __next_number(self):
            expr = ''
            while self.__cur_char().isdigit() or self.__cur_char() in ('.', '+', '-'):
                expr += self.__cur_char()
                self.__move_i()
            self.__move_i(-1)
            if '.' in expr:    # 若数字表达非法,则下面的转换会抛出异常
                return float(expr)    
            else:
                return int(expr)

        def __next_const(self):
            outstr = ''
            while self.__cur_char().isalpha():
                outstr += self.__cur_char()
                self.__move_i()

            self.__move_i(-1)

            if outstr in ('true', 'false', 'null'):    # 如果不在之中的其他表达都是非法的
                return {
                    'true': True,
                    'false': False,
                    'null': None
                }[outstr]
            raise Exception('Invalid symbol "%s"' % outstr)

        def next(self):    
            is_white_space = lambda a_char: a_char in (
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值