comparison eDecoder.py @ 71:54bb53434887

begin work on decoder that allows identifiers as keys and values
author Henry S. Thompson <ht@markup.co.uk>
date Wed, 28 Jun 2017 19:08:30 +0100
parents
children 0654e37583b5
comparison
equal deleted inserted replaced
70:0003fe7b6b67 71:54bb53434887
1 '''Extend JSON to support atoms as properties and class names'''
2 from json import decoder
3 from json.decoder import JSONDecoder, JSONObject, _CONSTANTS, WHITESPACE, WHITESPACE_STR, FLAGS, errmsg
4
5 import json, re
6
7 JSONObject_orig=JSONObject
8
9 class eDecoder(JSONDecoder):
10 def __init__(self, encoding=None, object_hook=None, parse_float=None,
11 parse_int=None, parse_constant=None, strict=True,
12 object_pairs_hook=None):
13
14 self.parse_object = eJSONObject
15 super(eDecoder,self).__init__(encoding, object_hook, parse_float,
16 parse_int, e_parse_constant, strict,
17 object_pairs_hook)
18
19 def e_parse_constant(istr):
20 print('constant: %s'%istr)
21 return _CONSTANTS[istr]
22
23 IDENT=re.compile(r'[a-zA-Z0-9_.-]+', FLAGS)
24
25 def eJSONObject(s_and_end, encoding, strict, scan_once, object_hook,
26 object_pairs_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
27 s, end = s_and_end
28 if (s[end] in ('"','}') or
29 (s[end] in _ws and
30 s[_w(s,end).end()] in ('"','}'))):
31 return JSONObject_orig(s_and_end, encoding, strict, scan_once, object_hook,
32 object_pairs_hook, _w, _ws)
33 while True:
34 #key, end = scanstring(s, end, encoding, strict)
35 isId = IDENT.match(s,end)
36 if isId:
37 key=isId.group()
38 end=isId.end()
39 else:
40 raise ValueError(errmsg(
41 "Expecting property name with or w/o in double quotes", s, end))
42
43 # To skip some function call overhead we optimize the fast paths where
44 # the JSON key separator is ": " or just ":".
45 if s[end:end + 1] != ':':
46 end = _w(s, end).end()
47 if s[end:end + 1] != ':':
48 raise ValueError(errmsg("Expecting ':' delimiter", s, end))
49 end += 1
50
51 try:
52 if s[end] in _ws:
53 end += 1
54 if s[end] in _ws:
55 end = _w(s, end + 1).end()
56 except IndexError:
57 pass
58
59 try:
60 value, end = scan_once(s, end)
61 except StopIteration:
62 raise ValueError(errmsg("Expecting object", s, end))
63 pairs_append((key, value))
64
65 try:
66 nextchar = s[end]
67 if nextchar in _ws:
68 end = _w(s, end + 1).end()
69 nextchar = s[end]
70 except IndexError:
71 nextchar = ''
72 end += 1
73
74 if nextchar == '}':
75 break
76 elif nextchar != ',':
77 raise ValueError(errmsg("Expecting ',' delimiter", s, end - 1))
78
79 try:
80 nextchar = s[end]
81 if nextchar in _ws:
82 end += 1
83 nextchar = s[end]
84 if nextchar in _ws:
85 end = _w(s, end + 1).end()
86 nextchar = s[end]
87 except IndexError:
88 nextchar = ''
89
90 end += 1
91 if nextchar != '"':
92 raise ValueError(errmsg(
93 "Expecting property name enclosed in double quotes", s, end - 1))
94 if object_pairs_hook is not None:
95 result = object_pairs_hook(pairs)
96 return result, end
97 pairs = dict(pairs)
98 if object_hook is not None:
99 pairs = object_hook(pairs)
100 return pairs, end
101
102
103 json.scanner.make_scanner=json.scanner.py_make_scanner
104 json.decoder.JSONObject=eJSONObject