Aestate
scanner.py
Go to the documentation of this file.
1 """JSON token scanner
2 """
3 import re
4 from .errors import JSONDecodeError
6  try:
7  from ._speedups import make_scanner
8  return make_scanner
9  except ImportError:
10  return None
11 c_make_scanner = _import_c_make_scanner()
12 
13 __all__ = ['make_scanner', 'JSONDecodeError']
14 
15 NUMBER_RE = re.compile(
16  r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',
17  (re.VERBOSE | re.MULTILINE | re.DOTALL))
18 
19 
20 def py_make_scanner(context):
21  parse_object = context.parse_object
22  parse_array = context.parse_array
23  parse_string = context.parse_string
24  match_number = NUMBER_RE.match
25  encoding = context.encoding
26  strict = context.strict
27  parse_float = context.parse_float
28  parse_int = context.parse_int
29  parse_constant = context.parse_constant
30  object_hook = context.object_hook
31  object_pairs_hook = context.object_pairs_hook
32  memo = context.memo
33 
34  def _scan_once(string, idx):
35  errmsg = 'Expecting value'
36  try:
37  nextchar = string[idx]
38  except IndexError:
39  raise JSONDecodeError(errmsg, string, idx)
40 
41  if nextchar == '"':
42  return parse_string(string, idx + 1, encoding, strict)
43  elif nextchar == '{':
44  return parse_object((string, idx + 1), encoding, strict,
45  _scan_once, object_hook, object_pairs_hook, memo)
46  elif nextchar == '[':
47  return parse_array((string, idx + 1), _scan_once)
48  elif nextchar == 'n' and string[idx:idx + 4] == 'null':
49  return None, idx + 4
50  elif nextchar == 't' and string[idx:idx + 4] == 'true':
51  return True, idx + 4
52  elif nextchar == 'f' and string[idx:idx + 5] == 'false':
53  return False, idx + 5
54 
55  m = match_number(string, idx)
56  if m is not None:
57  integer, frac, exp = m.groups()
58  if frac or exp:
59  res = parse_float(integer + (frac or '') + (exp or ''))
60  else:
61  res = parse_int(integer)
62  return res, m.end()
63  elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
64  return parse_constant('NaN'), idx + 3
65  elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
66  return parse_constant('Infinity'), idx + 8
67  elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
68  return parse_constant('-Infinity'), idx + 9
69  else:
70  raise JSONDecodeError(errmsg, string, idx)
71 
72  def scan_once(string, idx):
73  if idx < 0:
74  # Ensure the same behavior as the C speedup, otherwise
75  # this would work for *some* negative string indices due
76  # to the behavior of __getitem__ for strings. #98
77  raise JSONDecodeError('Expecting value', string, idx)
78  try:
79  return _scan_once(string, idx)
80  finally:
81  memo.clear()
82 
83  return scan_once
84 
85 make_scanner = c_make_scanner or py_make_scanner
aestate.ajson.sim.scanner.py_make_scanner
def py_make_scanner(context)
Definition: scanner.py:20
aestate.ajson.sim.scanner._import_c_make_scanner
def _import_c_make_scanner()
Definition: scanner.py:5
aestate.ajson.sim.errors.JSONDecodeError
Definition: errors.py:26