5
Created by Thomas Mangin on 2013-07-01.
6
Copyright (c) 2009-2012 Exa Networks. All rights reserved.
9
from decimal import Decimal
11
from exabgp.util import coroutine
13
class JSONError(Exception):
16
class UnexpectedData(JSONError):
17
def __init__(self, line, position, token):
18
super(UnexpectedData, self).__init__('Unexpected data at line %d position %d : "%s"' % (line,position,token))
24
pos = s.find('\\', start)
42
yield chr(int(s[pos + 1:pos + 5], 16))
50
spaces = [' ', '\t', '\r', '\n']
52
syntax = [',','[',']','{','}']
64
yield nb_lines,nb_chars,word
73
yield nb_lines,nb_chars,word
74
nb_chars += len(word) + 1
85
yield nb_lines,nb_chars,word
88
yield nb_lines,nb_chars,char
95
def parser (tokeniser,container):
96
# Yes, you can add attributes to function ...
102
line,position,token = next()
105
klass = container(next.path)
107
for key,value in iterate_dict(next):
112
for element in iterate_list(next):
115
elif token[0] == '"':
116
return unescape(token[1:-1])
117
elif token == 'true':
119
elif token == 'false':
121
elif token == 'null':
123
elif token == ']': # required for parsing arrays
126
# can raise ValueError
127
return Decimal(token) if '.' in token else int(token)
129
raise UnexpectedData(line,position,token)
130
except StopIteration:
133
def iterate_dict(next):
134
line,position,key = next()
138
raise UnexpectedData(line,position,key)
140
line,position,colon = next()
142
raise UnexpectedData(line,position,colon)
144
next.path.append(key)
145
yield key[1:-1],content(next)
148
line,position,separator = next()
152
raise UnexpectedData(line,position,separator)
153
line,position,key = next()
155
def iterate_list(next):
156
value = content(next)
161
line,position,separator = next()
165
raise UnexpectedData(line,position,separator)
167
value = content(next)
169
return content(tokeniser)
172
def load (stream,container=lambda _:dict):
173
return parser(tokens(stream),container)
175
__all__ = [load,JSONError,UnexpectedData]