Mercurial > hg > ooxml
changeset 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 | 4bd5de7ac247 |
files | eDecoder.py |
diffstat | 1 files changed, 86 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/eDecoder.py Wed Jun 28 19:08:30 2017 +0100 +++ b/eDecoder.py Thu Jun 29 17:58:06 2017 +0100 @@ -1,10 +1,12 @@ '''Extend JSON to support atoms as properties and class names''' from json import decoder -from json.decoder import JSONDecoder, JSONObject, _CONSTANTS, WHITESPACE, WHITESPACE_STR, FLAGS, errmsg +from json.decoder import JSONDecoder, JSONObject, JSONArray,\ + _CONSTANTS, WHITESPACE, WHITESPACE_STR, FLAGS, errmsg import json, re JSONObject_orig=JSONObject +JSONArray_orig=JSONArray class eDecoder(JSONDecoder): def __init__(self, encoding=None, object_hook=None, parse_float=None, @@ -20,26 +22,84 @@ print('constant: %s'%istr) return _CONSTANTS[istr] -IDENT=re.compile(r'[a-zA-Z0-9_.-]+', FLAGS) +IDENT=re.compile(r'[$]?[A-Z]+[$]?[0-9]+([:][$]?[A-Z]+[$]?[0-9]+)|[a-zA-Z0-9_.-]+', FLAGS) + +def eJSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): + s, end = s_and_end + values = [] + nextchar = s[end:end + 1] + if nextchar in _ws: + end = _w(s, end + 1).end() + nextchar = s[end:end + 1] + # Look-ahead for trivial empty array + if nextchar == ']': + return values, end + 1 + _append = values.append + while True: + try: + value, end = scan_once(s, end) + except StopIteration: + # Two possible causes: string empty, or no ident here + # Either way, the match will fail and the (original) value error is correct + isId = IDENT.match(s,end) + if isId: + value=isId.group() + end=isId.end() + else: + raise ValueError(errmsg("Expecting object", s, end)) + _append(value) + nextchar = s[end:end + 1] + if nextchar in _ws: + end = _w(s, end + 1).end() + nextchar = s[end:end + 1] + end += 1 + if nextchar == ']': + break + elif nextchar != ',': + raise ValueError(errmsg("Expecting ',' delimiter", s, end)) + try: + if s[end] in _ws: + end += 1 + if s[end] in _ws: + end = _w(s, end + 1).end() + except IndexError: + pass + + return values, end def eJSONObject(s_and_end, encoding, strict, scan_once, object_hook, object_pairs_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR): s, end = s_and_end - if (s[end] in ('"','}') or - (s[end] in _ws and - s[_w(s,end).end()] in ('"','}'))): - return JSONObject_orig(s_and_end, encoding, strict, scan_once, object_hook, - object_pairs_hook, _w, _ws) + pairs = [] + pairs_append = pairs.append + # Use a slice to prevent IndexError from being raised, the following + # check will raise a more specific ValueError if the string is empty + nextchar = s[end:end + 1] + # Normally we expect nextchar == '"' + if nextchar != '"': + if nextchar in _ws: + end = _w(s, end).end() + nextchar = s[end:end + 1] + # Trivial empty object + if nextchar == '}': + if object_pairs_hook is not None: + result = object_pairs_hook(pairs) + return result, end + 1 + pairs = {} + if object_hook is not None: + pairs = object_hook(pairs) + return pairs, end + 1 while True: - #key, end = scanstring(s, end, encoding, strict) - isId = IDENT.match(s,end) - if isId: - key=isId.group() - end=isId.end() + if nextchar=='"': + key, end = scanstring(s, end, encoding, strict) else: - raise ValueError(errmsg( - "Expecting property name with or w/o in double quotes", s, end)) - + isId = IDENT.match(s,end) + if isId: + key=isId.group() + end=isId.end() + else: + raise ValueError(errmsg( + "Expecting property name with or w/o double quotes", s, end)) # To skip some function call overhead we optimize the fast paths where # the JSON key separator is ": " or just ":". if s[end:end + 1] != ':': @@ -59,7 +119,14 @@ try: value, end = scan_once(s, end) except StopIteration: - raise ValueError(errmsg("Expecting object", s, end)) + # Two possible causes: string empty, or no ident here + # Either way, the match will fail and the (original) value error is correct + isId = IDENT.match(s,end) + if isId: + value=isId.group() + end=isId.end() + else: + raise ValueError(errmsg("Expecting object", s, end)) pairs_append((key, value)) try: @@ -87,10 +154,8 @@ except IndexError: nextchar = '' - end += 1 - if nextchar != '"': - raise ValueError(errmsg( - "Expecting property name enclosed in double quotes", s, end - 1)) + if nextchar=='"': + end += 1 if object_pairs_hook is not None: result = object_pairs_hook(pairs) return result, end @@ -102,3 +167,4 @@ json.scanner.make_scanner=json.scanner.py_make_scanner json.decoder.JSONObject=eJSONObject +json.decoder.JSONArray=eJSONArray