随手实现一个JSON解析器

class JsonParser:
    def __init__(self, s):
        self.s = s
        self.idx = 0

    def match(self, t):
        if self.curr_char() == t:
            self.idx += 1
        else:
            print(self.curr_char())
            print('match ERROR', t)
            exit()

    def curr_char(self):
        while self.s[self.idx].isspace():
            self.idx += 1
        return self.s[self.idx]

    def common_parse(self):
        """
        递归下降分析: str-->json
        """
        if self.curr_char() == '[':
            return self.parse_list()
        elif self.curr_char() == '{':
            return self.parse_dict()
        else:
            return self.parse_basic()

    def parse_dict(self):
        self.match('{')
        rtv = {}
        while True:
            key = self.parse_basic()
            self.match(':')
            value = self.common_parse()
            rtv[key] = value
            if self.curr_char() != ',':
                break
            self.match(',')
        self.match('}')
        return rtv

    def parse_list(self):
        self.match('[')
        rtv = []
        while True:
            item = self.common_parse()
            rtv.append(item)
            if self.curr_char() != ',':
                break
            self.match(',')
        self.match(']')
        return rtv

    def parse_basic(self):
        """
        int, none, bool, str
        """
        tmp = self.curr_char()
        if tmp.isdigit():
            self.idx += 1
            while self.curr_char().isdigit():
                tmp += self.curr_char()
                self.idx += 1
            return int(tmp)
        elif tmp == 'n':
            for c in 'null':
                self.match(c)
            return None
        elif tmp == 't':
            for c in 'true':
                self.match(c)
            return True
        elif tmp == 'f':
            for c in 'false':
                self.match(c)
            return False
        elif tmp == '"':
            self.match('"')
            tmp = ''
            while self.curr_char() != '"':
                tmp += self.curr_char()
                self.idx += 1
            self.match('"')
            return tmp


class JsonDump:
    @classmethod
    def dump(cls, o):
        return ''.join([s for s in cls.common_dump(o)])

    @classmethod
    def common_dump(cls, o):
        """
        深度优先遍历: json-->str
        """
        if isinstance(o, list):
            yield from cls.dump_list(o)
        elif isinstance(o, dict):
            yield from cls.dump_dict(o)
        else:
            yield from cls.dump_basic(o)

    @classmethod
    def dump_list(cls, o):
        idx, length = 0, len(o)
        yield '['
        for item in o:
            yield from cls.common_dump(item)
            idx += 1
            if idx < length:
                yield ','
        yield ']'

    @classmethod
    def dump_dict(cls, o):
        idx, length = 0, len(o)
        yield '{'
        for k, v in o.items():
            yield from cls.common_dump(k)
            yield ':'
            yield from cls.common_dump(v)
            idx += 1
            if idx < length:
                yield ','
        yield '}'

    @classmethod
    def dump_basic(cls, o):
        if o == True:
            yield 'true'
        elif o == False:
            yield 'false'
        elif o == None:
            yield 'null'
        elif isinstance(o, str):
            yield '"'
            yield o
            yield '"'
        elif isinstance(o, int):
            yield str(o)


if __name__ == '__main__':
    s = '{"hello": "world", "game": "war", "LIST": [1, 2, 3, {"Bang": false}]}'
    s2 = '{"paths":[{"path":"/:firewall:13","mac":false,"mac_users":[]}],"data":{"action":"add_rule","protocol":"TCP","cidr":"116.116.116.12/32","port_range":"80/8080","policy":"Accept","desc":"test"}}'
    jp = JsonParser(s2)
    print(s2)
    from pprint import pprint
    pprint(jp.common_parse())

    o = {'hello': 'world', 'game': 'war', 'LIST': [1, 2, 3, {'Bang': False}]}
    print(o)
    print(JsonDump.dump(o))

运行效果:

E:\workspace\sept>python json_parse.py
{"paths":[{"path":"/:firewall:13","mac":false,"mac_users":[]}],"data":{"action":"add_rule","protocol":"TCP","cidr":"116.116.116.12/32","por
t_range":"80/8080","policy":"Accept","desc":"test"}}
{'data': {'action': 'add_rule',
          'cidr': '116.116.116.12/32',
          'desc': 'test',
          'policy': 'Accept',
          'port_range': '80/8080',
          'protocol': 'TCP'},
 'paths': [{'mac': False, 'mac_users': [None], 'path': '/:firewall:13'}]}
{'hello': 'world', 'game': 'war', 'LIST': [1, 2, 3, {'Bang': False}]}
{"hello":"world","game":"war","LIST":[true,2,3,{"Bang":false}]}

你可能感兴趣的:(随手实现一个JSON解析器)