PageRenderTime 22ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/examples/jsonrpc/public/services/simplejson/scanner.py

http://pyjamas.googlecode.com/
Python | 63 lines | 49 code | 6 blank | 8 comment | 12 complexity | 2268c927e34e0bb25eb3e276b60b6453 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. """
  2. Iterator based sre token scanner
  3. """
  4. import sre_parse, sre_compile, sre_constants
  5. from sre_constants import BRANCH, SUBPATTERN
  6. from sre import VERBOSE, MULTILINE, DOTALL
  7. import re
  8. __all__ = ['Scanner', 'pattern']
  9. FLAGS = (VERBOSE | MULTILINE | DOTALL)
  10. class Scanner(object):
  11. def __init__(self, lexicon, flags=FLAGS):
  12. self.actions = [None]
  13. # combine phrases into a compound pattern
  14. s = sre_parse.Pattern()
  15. s.flags = flags
  16. p = []
  17. for idx, token in enumerate(lexicon):
  18. phrase = token.pattern
  19. try:
  20. subpattern = sre_parse.SubPattern(s,
  21. [(SUBPATTERN, (idx + 1, sre_parse.parse(phrase, flags)))])
  22. except sre_constants.error:
  23. raise
  24. p.append(subpattern)
  25. self.actions.append(token)
  26. p = sre_parse.SubPattern(s, [(BRANCH, (None, p))])
  27. self.scanner = sre_compile.compile(p)
  28. def iterscan(self, string, idx=0, context=None):
  29. """
  30. Yield match, end_idx for each match
  31. """
  32. match = self.scanner.scanner(string, idx).match
  33. actions = self.actions
  34. lastend = idx
  35. end = len(string)
  36. while True:
  37. m = match()
  38. if m is None:
  39. break
  40. matchbegin, matchend = m.span()
  41. if lastend == matchend:
  42. break
  43. action = actions[m.lastindex]
  44. if action is not None:
  45. rval, next_pos = action(m, context)
  46. if next_pos is not None and next_pos != matchend:
  47. # "fast forward" the scanner
  48. matchend = next_pos
  49. match = self.scanner.scanner(string, matchend).match
  50. yield rval, matchend
  51. lastend = matchend
  52. def pattern(pattern, flags=FLAGS):
  53. def decorator(fn):
  54. fn.pattern = pattern
  55. fn.regex = re.compile(pattern, flags)
  56. return fn
  57. return decorator