Changeset 391 for python/trunk/Lib/json/scanner.py
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Lib/json/scanner.py
r2 r391 1 """Iterator based sre token scanner 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 2 8 3 """ 9 __all__ = ['make_scanner'] 4 10 5 import re 6 import sre_parse 7 import sre_compile 8 import sre_constants 11 NUMBER_RE = re.compile( 12 r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?', 13 (re.VERBOSE | re.MULTILINE | re.DOTALL)) 9 14 10 from re import VERBOSE, MULTILINE, DOTALL 11 from sre_constants import BRANCH, SUBPATTERN 15 def py_make_scanner(context): 16 parse_object = context.parse_object 17 parse_array = context.parse_array 18 parse_string = context.parse_string 19 match_number = NUMBER_RE.match 20 encoding = context.encoding 21 strict = context.strict 22 parse_float = context.parse_float 23 parse_int = context.parse_int 24 parse_constant = context.parse_constant 25 object_hook = context.object_hook 26 object_pairs_hook = context.object_pairs_hook 12 27 13 __all__ = ['Scanner', 'pattern'] 28 def _scan_once(string, idx): 29 try: 30 nextchar = string[idx] 31 except IndexError: 32 raise StopIteration 14 33 15 FLAGS = (VERBOSE | MULTILINE | DOTALL) 34 if nextchar == '"': 35 return parse_string(string, idx + 1, encoding, strict) 36 elif nextchar == '{': 37 return parse_object((string, idx + 1), encoding, strict, 38 _scan_once, object_hook, object_pairs_hook) 39 elif nextchar == '[': 40 return parse_array((string, idx + 1), _scan_once) 41 elif nextchar == 'n' and string[idx:idx + 4] == 'null': 42 return None, idx + 4 43 elif nextchar == 't' and string[idx:idx + 4] == 'true': 44 return True, idx + 4 45 elif nextchar == 'f' and string[idx:idx + 5] == 'false': 46 return False, idx + 5 16 47 17 class Scanner(object): 18 def __init__(self, lexicon, flags=FLAGS):19 self.actions = [None]20 # Combine phrases into a compound pattern21 s = sre_parse.Pattern()22 s.flags = flags23 p = []24 for idx, token in enumerate(lexicon):25 phrase = token.pattern26 try:27 subpattern = sre_parse.SubPattern(s,28 [(SUBPATTERN, (idx + 1, sre_parse.parse(phrase, flags)))])29 except sre_constants.error:30 raise31 p.append(subpattern)32 self.actions.append(token)48 m = match_number(string, idx) 49 if m is not None: 50 integer, frac, exp = m.groups() 51 if frac or exp: 52 res = parse_float(integer + (frac or '') + (exp or '')) 53 else: 54 res = parse_int(integer) 55 return res, m.end() 56 elif nextchar == 'N' and string[idx:idx + 3] == 'NaN': 57 return parse_constant('NaN'), idx + 3 58 elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity': 59 return parse_constant('Infinity'), idx + 8 60 elif nextchar == '-' and string[idx:idx + 9] == '-Infinity': 61 return parse_constant('-Infinity'), idx + 9 62 else: 63 raise StopIteration 33 64 34 s.groups = len(p) + 1 # NOTE(guido): Added to make SRE validation work 35 p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) 36 self.scanner = sre_compile.compile(p) 65 return _scan_once 37 66 38 def iterscan(self, string, idx=0, context=None): 39 """Yield match, end_idx for each match 40 41 """ 42 match = self.scanner.scanner(string, idx).match 43 actions = self.actions 44 lastend = idx 45 end = len(string) 46 while True: 47 m = match() 48 if m is None: 49 break 50 matchbegin, matchend = m.span() 51 if lastend == matchend: 52 break 53 action = actions[m.lastindex] 54 if action is not None: 55 rval, next_pos = action(m, context) 56 if next_pos is not None and next_pos != matchend: 57 # "fast forward" the scanner 58 matchend = next_pos 59 match = self.scanner.scanner(string, matchend).match 60 yield rval, matchend 61 lastend = matchend 62 63 64 def pattern(pattern, flags=FLAGS): 65 def decorator(fn): 66 fn.pattern = pattern 67 fn.regex = re.compile(pattern, flags) 68 return fn 69 return decorator 67 make_scanner = c_make_scanner or py_make_scanner
Note:
See TracChangeset
for help on using the changeset viewer.