summaryrefslogtreecommitdiff
path: root/django/utils/simplejson/scanner.py
diff options
context:
space:
mode:
authorJacob Kaplan-Moss <jacob@jacobian.org>2006-06-28 20:59:49 +0000
committerJacob Kaplan-Moss <jacob@jacobian.org>2006-06-28 20:59:49 +0000
commitf44e7acb17738cb222a0d8390eac480488241d15 (patch)
tree1e7a9572cb2159ef9ffab81aaf1a9de7e1a88116 /django/utils/simplejson/scanner.py
parentaab3a418ac9293bb4abd7670f65d930cb0426d58 (diff)
Added Bob Ippolito's simplejson (http://undefined.org/python/#simplejson) as {{{django.auth.simplejson}}}. This is version 1.3 of simplejson. Thanks to Bob for his code and his permission to include it.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@3232 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/utils/simplejson/scanner.py')
-rw-r--r--django/utils/simplejson/scanner.py63
1 files changed, 63 insertions, 0 deletions
diff --git a/django/utils/simplejson/scanner.py b/django/utils/simplejson/scanner.py
new file mode 100644
index 0000000000..c2e9b6eb89
--- /dev/null
+++ b/django/utils/simplejson/scanner.py
@@ -0,0 +1,63 @@
+"""
+Iterator based sre token scanner
+"""
+import sre_parse, sre_compile, sre_constants
+from sre_constants import BRANCH, SUBPATTERN
+from sre import VERBOSE, MULTILINE, DOTALL
+import re
+
+__all__ = ['Scanner', 'pattern']
+
+FLAGS = (VERBOSE | MULTILINE | DOTALL)
+class Scanner(object):
+ def __init__(self, lexicon, flags=FLAGS):
+ self.actions = [None]
+ # combine phrases into a compound pattern
+ s = sre_parse.Pattern()
+ s.flags = flags
+ p = []
+ for idx, token in enumerate(lexicon):
+ phrase = token.pattern
+ try:
+ subpattern = sre_parse.SubPattern(s,
+ [(SUBPATTERN, (idx + 1, sre_parse.parse(phrase, flags)))])
+ except sre_constants.error:
+ raise
+ p.append(subpattern)
+ self.actions.append(token)
+
+ p = sre_parse.SubPattern(s, [(BRANCH, (None, p))])
+ self.scanner = sre_compile.compile(p)
+
+
+ def iterscan(self, string, idx=0, context=None):
+ """
+ Yield match, end_idx for each match
+ """
+ match = self.scanner.scanner(string, idx).match
+ actions = self.actions
+ lastend = idx
+ end = len(string)
+ while True:
+ m = match()
+ if m is None:
+ break
+ matchbegin, matchend = m.span()
+ if lastend == matchend:
+ break
+ action = actions[m.lastindex]
+ if action is not None:
+ rval, next_pos = action(m, context)
+ if next_pos is not None and next_pos != matchend:
+ # "fast forward" the scanner
+ matchend = next_pos
+ match = self.scanner.scanner(string, matchend).match
+ yield rval, matchend
+ lastend = matchend
+
+def pattern(pattern, flags=FLAGS):
+ def decorator(fn):
+ fn.pattern = pattern
+ fn.regex = re.compile(pattern, flags)
+ return fn
+ return decorator