comparison eDecoder.py @ 72:0654e37583b5

appears to read kdir.js correctly
author Henry S. Thompson <ht@markup.co.uk>
date Thu, 29 Jun 2017 17:58:06 +0100
parents 54bb53434887
children
comparison
equal deleted inserted replaced
71:54bb53434887 72:0654e37583b5
1 '''Extend JSON to support atoms as properties and class names''' 1 '''Extend JSON to support atoms as properties and class names'''
2 from json import decoder 2 from json import decoder
3 from json.decoder import JSONDecoder, JSONObject, _CONSTANTS, WHITESPACE, WHITESPACE_STR, FLAGS, errmsg 3 from json.decoder import JSONDecoder, JSONObject, JSONArray,\
4 _CONSTANTS, WHITESPACE, WHITESPACE_STR, FLAGS, errmsg
4 5
5 import json, re 6 import json, re
6 7
7 JSONObject_orig=JSONObject 8 JSONObject_orig=JSONObject
9 JSONArray_orig=JSONArray
8 10
9 class eDecoder(JSONDecoder): 11 class eDecoder(JSONDecoder):
10 def __init__(self, encoding=None, object_hook=None, parse_float=None, 12 def __init__(self, encoding=None, object_hook=None, parse_float=None,
11 parse_int=None, parse_constant=None, strict=True, 13 parse_int=None, parse_constant=None, strict=True,
12 object_pairs_hook=None): 14 object_pairs_hook=None):
18 20
19 def e_parse_constant(istr): 21 def e_parse_constant(istr):
20 print('constant: %s'%istr) 22 print('constant: %s'%istr)
21 return _CONSTANTS[istr] 23 return _CONSTANTS[istr]
22 24
23 IDENT=re.compile(r'[a-zA-Z0-9_.-]+', FLAGS) 25 IDENT=re.compile(r'[$]?[A-Z]+[$]?[0-9]+([:][$]?[A-Z]+[$]?[0-9]+)|[a-zA-Z0-9_.-]+', FLAGS)
26
27 def eJSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
28 s, end = s_and_end
29 values = []
30 nextchar = s[end:end + 1]
31 if nextchar in _ws:
32 end = _w(s, end + 1).end()
33 nextchar = s[end:end + 1]
34 # Look-ahead for trivial empty array
35 if nextchar == ']':
36 return values, end + 1
37 _append = values.append
38 while True:
39 try:
40 value, end = scan_once(s, end)
41 except StopIteration:
42 # Two possible causes: string empty, or no ident here
43 # Either way, the match will fail and the (original) value error is correct
44 isId = IDENT.match(s,end)
45 if isId:
46 value=isId.group()
47 end=isId.end()
48 else:
49 raise ValueError(errmsg("Expecting object", s, end))
50 _append(value)
51 nextchar = s[end:end + 1]
52 if nextchar in _ws:
53 end = _w(s, end + 1).end()
54 nextchar = s[end:end + 1]
55 end += 1
56 if nextchar == ']':
57 break
58 elif nextchar != ',':
59 raise ValueError(errmsg("Expecting ',' delimiter", s, end))
60 try:
61 if s[end] in _ws:
62 end += 1
63 if s[end] in _ws:
64 end = _w(s, end + 1).end()
65 except IndexError:
66 pass
67
68 return values, end
24 69
25 def eJSONObject(s_and_end, encoding, strict, scan_once, object_hook, 70 def eJSONObject(s_and_end, encoding, strict, scan_once, object_hook,
26 object_pairs_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR): 71 object_pairs_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
27 s, end = s_and_end 72 s, end = s_and_end
28 if (s[end] in ('"','}') or 73 pairs = []
29 (s[end] in _ws and 74 pairs_append = pairs.append
30 s[_w(s,end).end()] in ('"','}'))): 75 # Use a slice to prevent IndexError from being raised, the following
31 return JSONObject_orig(s_and_end, encoding, strict, scan_once, object_hook, 76 # check will raise a more specific ValueError if the string is empty
32 object_pairs_hook, _w, _ws) 77 nextchar = s[end:end + 1]
78 # Normally we expect nextchar == '"'
79 if nextchar != '"':
80 if nextchar in _ws:
81 end = _w(s, end).end()
82 nextchar = s[end:end + 1]
83 # Trivial empty object
84 if nextchar == '}':
85 if object_pairs_hook is not None:
86 result = object_pairs_hook(pairs)
87 return result, end + 1
88 pairs = {}
89 if object_hook is not None:
90 pairs = object_hook(pairs)
91 return pairs, end + 1
33 while True: 92 while True:
34 #key, end = scanstring(s, end, encoding, strict) 93 if nextchar=='"':
35 isId = IDENT.match(s,end) 94 key, end = scanstring(s, end, encoding, strict)
36 if isId:
37 key=isId.group()
38 end=isId.end()
39 else: 95 else:
40 raise ValueError(errmsg( 96 isId = IDENT.match(s,end)
41 "Expecting property name with or w/o in double quotes", s, end)) 97 if isId:
42 98 key=isId.group()
99 end=isId.end()
100 else:
101 raise ValueError(errmsg(
102 "Expecting property name with or w/o double quotes", s, end))
43 # To skip some function call overhead we optimize the fast paths where 103 # To skip some function call overhead we optimize the fast paths where
44 # the JSON key separator is ": " or just ":". 104 # the JSON key separator is ": " or just ":".
45 if s[end:end + 1] != ':': 105 if s[end:end + 1] != ':':
46 end = _w(s, end).end() 106 end = _w(s, end).end()
47 if s[end:end + 1] != ':': 107 if s[end:end + 1] != ':':
57 pass 117 pass
58 118
59 try: 119 try:
60 value, end = scan_once(s, end) 120 value, end = scan_once(s, end)
61 except StopIteration: 121 except StopIteration:
62 raise ValueError(errmsg("Expecting object", s, end)) 122 # Two possible causes: string empty, or no ident here
123 # Either way, the match will fail and the (original) value error is correct
124 isId = IDENT.match(s,end)
125 if isId:
126 value=isId.group()
127 end=isId.end()
128 else:
129 raise ValueError(errmsg("Expecting object", s, end))
63 pairs_append((key, value)) 130 pairs_append((key, value))
64 131
65 try: 132 try:
66 nextchar = s[end] 133 nextchar = s[end]
67 if nextchar in _ws: 134 if nextchar in _ws:
85 end = _w(s, end + 1).end() 152 end = _w(s, end + 1).end()
86 nextchar = s[end] 153 nextchar = s[end]
87 except IndexError: 154 except IndexError:
88 nextchar = '' 155 nextchar = ''
89 156
90 end += 1 157 if nextchar=='"':
91 if nextchar != '"': 158 end += 1
92 raise ValueError(errmsg(
93 "Expecting property name enclosed in double quotes", s, end - 1))
94 if object_pairs_hook is not None: 159 if object_pairs_hook is not None:
95 result = object_pairs_hook(pairs) 160 result = object_pairs_hook(pairs)
96 return result, end 161 return result, end
97 pairs = dict(pairs) 162 pairs = dict(pairs)
98 if object_hook is not None: 163 if object_hook is not None:
100 return pairs, end 165 return pairs, end
101 166
102 167
103 json.scanner.make_scanner=json.scanner.py_make_scanner 168 json.scanner.make_scanner=json.scanner.py_make_scanner
104 json.decoder.JSONObject=eJSONObject 169 json.decoder.JSONObject=eJSONObject
170 json.decoder.JSONArray=eJSONArray