scanner.py
Go to the documentation of this file.00001 """JSON token scanner
00002 """
00003 import re
00004 try:
00005 from simplejson._speedups import make_scanner as c_make_scanner
00006 except ImportError:
00007 c_make_scanner = None
00008
00009 __all__ = ['make_scanner']
00010
00011 NUMBER_RE = re.compile(
00012 r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',
00013 (re.VERBOSE | re.MULTILINE | re.DOTALL))
00014
00015 def py_make_scanner(context):
00016 parse_object = context.parse_object
00017 parse_array = context.parse_array
00018 parse_string = context.parse_string
00019 match_number = NUMBER_RE.match
00020 encoding = context.encoding
00021 strict = context.strict
00022 parse_float = context.parse_float
00023 parse_int = context.parse_int
00024 parse_constant = context.parse_constant
00025 object_hook = context.object_hook
00026
00027 def _scan_once(string, idx):
00028 try:
00029 nextchar = string[idx]
00030 except IndexError:
00031 raise StopIteration
00032
00033 if nextchar == '"':
00034 return parse_string(string, idx + 1, encoding, strict)
00035 elif nextchar == '{':
00036 return parse_object((string, idx + 1), encoding, strict, _scan_once, object_hook)
00037 elif nextchar == '[':
00038 return parse_array((string, idx + 1), _scan_once)
00039 elif nextchar == 'n' and string[idx:idx + 4] == 'null':
00040 return None, idx + 4
00041 elif nextchar == 't' and string[idx:idx + 4] == 'true':
00042 return True, idx + 4
00043 elif nextchar == 'f' and string[idx:idx + 5] == 'false':
00044 return False, idx + 5
00045
00046 m = match_number(string, idx)
00047 if m is not None:
00048 integer, frac, exp = m.groups()
00049 if frac or exp:
00050 res = parse_float(integer + (frac or '') + (exp or ''))
00051 else:
00052 res = parse_int(integer)
00053 return res, m.end()
00054 elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
00055 return parse_constant('NaN'), idx + 3
00056 elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
00057 return parse_constant('Infinity'), idx + 8
00058 elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
00059 return parse_constant('-Infinity'), idx + 9
00060 else:
00061 raise StopIteration
00062
00063 return _scan_once
00064
00065 make_scanner = c_make_scanner or py_make_scanner