]>
Commit | Line | Data |
---|---|---|
3257aa99 DM |
1 | """JSON token scanner\r |
2 | """\r | |
3 | import re\r | |
4 | try:\r | |
5 | from _json import make_scanner as c_make_scanner\r | |
6 | except ImportError:\r | |
7 | c_make_scanner = None\r | |
8 | \r | |
9 | __all__ = ['make_scanner']\r | |
10 | \r | |
11 | NUMBER_RE = re.compile(\r | |
12 | r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',\r | |
13 | (re.VERBOSE | re.MULTILINE | re.DOTALL))\r | |
14 | \r | |
15 | def py_make_scanner(context):\r | |
16 | parse_object = context.parse_object\r | |
17 | parse_array = context.parse_array\r | |
18 | parse_string = context.parse_string\r | |
19 | match_number = NUMBER_RE.match\r | |
20 | encoding = context.encoding\r | |
21 | strict = context.strict\r | |
22 | parse_float = context.parse_float\r | |
23 | parse_int = context.parse_int\r | |
24 | parse_constant = context.parse_constant\r | |
25 | object_hook = context.object_hook\r | |
26 | object_pairs_hook = context.object_pairs_hook\r | |
27 | \r | |
28 | def _scan_once(string, idx):\r | |
29 | try:\r | |
30 | nextchar = string[idx]\r | |
31 | except IndexError:\r | |
32 | raise StopIteration\r | |
33 | \r | |
34 | if nextchar == '"':\r | |
35 | return parse_string(string, idx + 1, encoding, strict)\r | |
36 | elif nextchar == '{':\r | |
37 | return parse_object((string, idx + 1), encoding, strict,\r | |
38 | _scan_once, object_hook, object_pairs_hook)\r | |
39 | elif nextchar == '[':\r | |
40 | return parse_array((string, idx + 1), _scan_once)\r | |
41 | elif nextchar == 'n' and string[idx:idx + 4] == 'null':\r | |
42 | return None, idx + 4\r | |
43 | elif nextchar == 't' and string[idx:idx + 4] == 'true':\r | |
44 | return True, idx + 4\r | |
45 | elif nextchar == 'f' and string[idx:idx + 5] == 'false':\r | |
46 | return False, idx + 5\r | |
47 | \r | |
48 | m = match_number(string, idx)\r | |
49 | if m is not None:\r | |
50 | integer, frac, exp = m.groups()\r | |
51 | if frac or exp:\r | |
52 | res = parse_float(integer + (frac or '') + (exp or ''))\r | |
53 | else:\r | |
54 | res = parse_int(integer)\r | |
55 | return res, m.end()\r | |
56 | elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':\r | |
57 | return parse_constant('NaN'), idx + 3\r | |
58 | elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':\r | |
59 | return parse_constant('Infinity'), idx + 8\r | |
60 | elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':\r | |
61 | return parse_constant('-Infinity'), idx + 9\r | |
62 | else:\r | |
63 | raise StopIteration\r | |
64 | \r | |
65 | return _scan_once\r | |
66 | \r | |
67 | make_scanner = c_make_scanner or py_make_scanner\r |