[pypy-svn] r16667 - pypy/dist/pypy/module/_sre

nik at codespeak.net nik at codespeak.net
Fri Aug 26 19:01:45 CEST 2005


Author: nik
Date: Fri Aug 26 19:01:41 2005
New Revision: 16667

Modified:
   pypy/dist/pypy/module/_sre/app_sre.py
   pypy/dist/pypy/module/_sre/interp_sre.py
Log:
moved op_min_until to interp-level. core regex interpretation is now fully
at interp-level! refactorings to be done next ...


Modified: pypy/dist/pypy/module/_sre/app_sre.py
==============================================================================
--- pypy/dist/pypy/module/_sre/app_sre.py	(original)
+++ pypy/dist/pypy/module/_sre/app_sre.py	Fri Aug 26 19:01:41 2005
@@ -185,7 +185,7 @@
         return match
 
     def match(self):
-        return self._match_search(match)
+        return self._match_search(_sre._match)
 
     def search(self):
         return self._match_search(search)
@@ -394,126 +394,6 @@
     return has_matched == MATCHED
 
 
-class _Dispatcher(object):
-
-    DISPATCH_TABLE = None
-
-    def dispatch(self, code, context):
-        method = self.DISPATCH_TABLE.get(code, self.__class__.unknown)
-        return method(self, context)
-
-    def unknown(self, code, ctx):
-        raise NotImplementedError()
-
-    def build_dispatch_table(cls, code_dict, method_prefix):
-        if cls.DISPATCH_TABLE is not None:
-            return
-        table = {}
-        for key, value in code_dict.items():
-            if hasattr(cls, "%s%s" % (method_prefix, key)):
-                table[value] = getattr(cls, "%s%s" % (method_prefix, key))
-        cls.DISPATCH_TABLE = table
-
-    build_dispatch_table = classmethod(build_dispatch_table)
-
-
-class _OpcodeDispatcher(_Dispatcher):
-    
-    def __init__(self):
-        self.executing_contexts = {}
-        
-    def match(self, context):
-        """Returns True if the current context matches, False if it doesn't and
-        None if matching is not finished, ie must be resumed after child
-        contexts have been matched."""
-        while context.remaining_codes() > 0 and context.has_matched == UNDECIDED:
-            opcode = context.peek_code()
-            if not self.dispatch(opcode, context):
-                return UNDECIDED
-        if context.has_matched == UNDECIDED:
-            context.has_matched = NOT_MATCHED
-        return context.has_matched
-
-    def dispatch(self, opcode, context):
-        """Dispatches a context on a given opcode. Returns True if the context
-        is done matching, False if it must be resumed when next encountered."""
-        if self.executing_contexts.has_key(id(context)):
-            generator = self.executing_contexts[id(context)]
-            del self.executing_contexts[id(context)]
-            has_finished = generator.next()
-        else:
-            if _sre._opcode_is_at_interplevel(opcode):
-                has_finished = _sre._opcode_dispatch(opcode, context)
-            else:
-                method = self.DISPATCH_TABLE.get(opcode, _OpcodeDispatcher.unknown)
-                has_finished = method(self, context)
-            if hasattr(has_finished, "next"): # avoid using the types module
-                generator = has_finished
-                has_finished = generator.next()
-        if not has_finished:
-            self.executing_contexts[id(context)] = generator
-        return has_finished
-
-    def op_min_until(self, ctx):
-        # minimizing repeat
-        # <REPEAT> <skip> <1=min> <2=max> item <MIN_UNTIL> tail
-        repeat = ctx.state.repeat
-        if repeat is None:
-            raise RuntimeError("Internal re error: MIN_UNTIL without REPEAT.")
-        mincount = repeat.peek_code(2)
-        maxcount = repeat.peek_code(3)
-        ctx.state.string_position = ctx.string_position
-        count = repeat.count + 1
-        #self._log(ctx, "MIN_UNTIL", count)
-
-        if count < mincount:
-            # not enough matches
-            repeat.count = count
-            child_context = repeat.push_new_context(4)
-            yield False
-            ctx.has_matched = child_context.has_matched
-            if ctx.has_matched == NOT_MATCHED:
-                repeat.count = count - 1
-                ctx.state.string_position = ctx.string_position
-            yield True
-
-        # see if the tail matches
-        ctx.state.marks_push()
-        ctx.state.repeat = repeat.previous
-        child_context = ctx.push_new_context(1)
-        yield False
-        if child_context.has_matched == MATCHED:
-            ctx.has_matched = MATCHED
-            yield True
-        ctx.state.repeat = repeat
-        ctx.state.string_position = ctx.string_position
-        ctx.state.marks_pop()
-
-        # match more until tail matches
-        if count >= maxcount and maxcount != MAXREPEAT:
-            ctx.has_matched = NOT_MATCHED
-            yield True
-        repeat.count = count
-        child_context = repeat.push_new_context(4)
-        yield False
-        ctx.has_matched = child_context.has_matched
-        if ctx.has_matched == NOT_MATCHED:
-            repeat.count = count - 1
-            ctx.state.string_position = ctx.string_position
-        yield True
-        
-    def unknown(self, ctx):
-        #self._log(ctx, "UNKNOWN", ctx.peek_code())
-        raise RuntimeError("Internal re error. Unknown opcode: %s" % ctx.peek_code())
-    
-    def _log(self, context, opname, *args):
-        arg_string = ("%s " * len(args)) % args
-        _log("|%s|%s|%s %s" % (context.pattern_codes,
-            context.string_position, opname, arg_string))
-
-_OpcodeDispatcher.build_dispatch_table(OPCODES, "op_")
-
-
 def _log(message):
     if 0:
         print message

Modified: pypy/dist/pypy/module/_sre/interp_sre.py
==============================================================================
--- pypy/dist/pypy/module/_sre/interp_sre.py	(original)
+++ pypy/dist/pypy/module/_sre/interp_sre.py	Fri Aug 26 19:01:41 2005
@@ -695,6 +695,93 @@
                 ctx.state.string_position = ctx.string_position
             return True
 
+def op_min_until(space, ctx):
+    # minimizing repeat
+    # <REPEAT> <skip> <1=min> <2=max> item <MIN_UNTIL> tail
+    
+    # Case 1: First entry point
+    if not ctx.is_resumed():
+        repeat = ctx.state.repeat
+        if repeat is None:
+            raise RuntimeError("Internal re error: MIN_UNTIL without REPEAT.")
+        mincount = repeat.peek_code(2)
+        maxcount = repeat.peek_code(3)
+        ctx.state.string_position = ctx.string_position
+        count = repeat.count + 1
+
+        if count < mincount:
+            # not enough matches
+            repeat.count = count
+            repeat.repeat_stack.append(repeat.push_new_context(4))
+            ctx.backup_value(mincount)
+            ctx.backup_value(maxcount)
+            ctx.backup_value(count)
+            ctx.backup_value(0)
+            ctx.repeat = repeat
+            return False
+
+        # see if the tail matches
+        ctx.state.marks_push()
+        ctx.state.repeat = repeat.previous
+        ctx.push_new_context(1)
+        ctx.backup_value(mincount)
+        ctx.backup_value(maxcount)
+        ctx.backup_value(count)
+        ctx.backup_value(1)
+        ctx.repeat = repeat
+        return False
+
+    # Case 2: Resumed
+    else:
+        repeat = ctx.repeat
+        if repeat.has_matched == ctx.MATCHED:
+            ctx.has_matched = ctx.MATCHED
+            return True
+        values = ctx.restore_values()
+        mincount = values[0]
+        maxcount = values[1]
+        count = values[2]
+        matching_state = values[3]
+
+        if count < mincount:
+            # not enough matches
+            ctx.has_matched = repeat.repeat_stack.pop().has_matched
+            if ctx.has_matched == ctx.NOT_MATCHED:
+                repeat.count = count - 1
+                ctx.state.string_position = ctx.string_position
+            return True
+        
+        if matching_state == 1:
+            # returning from tail matching
+            if ctx.child_context.has_matched == ctx.MATCHED:
+                ctx.has_matched = ctx.MATCHED
+                return True
+            ctx.state.repeat = repeat
+            ctx.state.string_position = ctx.string_position
+            ctx.state.marks_pop()
+
+        if not matching_state == 2:
+            # match more until tail matches
+            if count >= maxcount and maxcount != MAXREPEAT:
+                ctx.has_matched = ctx.NOT_MATCHED
+                return True
+            repeat.count = count
+            repeat.repeat_stack.append(repeat.push_new_context(4))
+            ctx.backup_value(mincount)
+            ctx.backup_value(maxcount)
+            ctx.backup_value(count)
+            ctx.backup_value(2)
+            ctx.repeat = repeat
+            return False
+
+        # Final return
+        ctx.has_matched = repeat.repeat_stack.pop().has_matched
+        repeat.has_matched = ctx.has_matched
+        if ctx.has_matched == ctx.NOT_MATCHED:
+            repeat.count = count - 1
+            ctx.state.string_position = ctx.string_position
+        return True
+
 def op_jump(space, ctx):
     # jump forward
     # <JUMP>/<INFO> <offset>
@@ -822,7 +909,7 @@
     op_literal, op_literal_ignore,
     op_mark,
     op_max_until,
-    None, #MIN_UNTIL,
+    op_min_until,
     op_not_literal, op_not_literal_ignore,
     None, #NEGATE,
     None, #RANGE,



More information about the Pypy-commit mailing list