github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/third_party/stdlib/json_scanner.py (about)

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