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

nik at codespeak.net nik at codespeak.net
Fri Aug 26 10:44:05 CEST 2005


Author: nik
Date: Fri Aug 26 10:44:01 2005
New Revision: 16570

Modified:
   pypy/dist/pypy/module/_sre/app_sre.py
   pypy/dist/pypy/module/_sre/interp_sre.py
Log:
moved op_min_repeat_one from app- to interp-level


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 10:44:01 2005
@@ -454,50 +454,6 @@
             self.executing_contexts[id(context)] = generator
         return has_finished
 
-    def op_min_repeat_one(self, ctx):
-        # match repeated sequence (minimizing)
-        # <MIN_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail
-        mincount = ctx.peek_code(2)
-        maxcount = ctx.peek_code(3)
-        #self._log(ctx, "MIN_REPEAT_ONE", mincount, maxcount)
-
-        if ctx.remaining_chars() < mincount:
-            ctx.has_matched = NOT_MATCHED
-            yield True
-        ctx.state.string_position = ctx.string_position
-        if mincount == 0:
-            count = 0
-        else:
-            count = self.count_repetitions(ctx, mincount)
-            if count < mincount:
-                ctx.has_matched = NOT_MATCHED
-                yield True
-            ctx.skip_char(count)
-        if ctx.peek_code(ctx.peek_code(1) + 1) == OPCODES["success"]:
-            # tail is empty.  we're finished
-            ctx.state.string_position = ctx.string_position
-            ctx.has_matched = MATCHED
-            yield True
-
-        ctx.state.marks_push()
-        while maxcount == MAXREPEAT or count <= maxcount:
-            ctx.state.string_position = ctx.string_position
-            child_context = ctx.push_new_context(ctx.peek_code(1) + 1)
-            yield False
-            if child_context.has_matched == MATCHED:
-                ctx.has_matched = MATCHED
-                yield True
-            ctx.state.string_position = ctx.string_position
-            if self.count_repetitions(ctx, 1) == 0:
-                break
-            ctx.skip_char(1)
-            count += 1
-            ctx.state.marks_pop_keep()
-
-        ctx.state.marks_pop_discard()
-        ctx.has_matched = NOT_MATCHED
-        yield True
-
     def op_repeat(self, ctx):
         # create repeat context.  all the hard work is done by the UNTIL
         # operator (MAX_UNTIL, MIN_UNTIL)

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 10:44:01 2005
@@ -528,6 +528,64 @@
     ctx.has_matched = ctx.NOT_MATCHED
     return True
 
+def op_min_repeat_one(space, ctx):
+    # match repeated sequence (minimizing)
+    # <MIN_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail
+    
+    # Case 1: First entry point
+    if not ctx.is_resumed():
+        mincount = ctx.peek_code(2)
+        maxcount = ctx.peek_code(3)
+        if ctx.remaining_chars() < mincount:
+            ctx.has_matched = ctx.NOT_MATCHED
+            return True
+        ctx.state.string_position = ctx.string_position
+        if mincount == 0:
+            count = 0
+        else:
+            count = count_repetitions(space, ctx, mincount)
+            if count < mincount:
+                ctx.has_matched = ctx.NOT_MATCHED
+                return True
+            ctx.skip_char(count)
+        if ctx.peek_code(ctx.peek_code(1) + 1) == 1: # OPCODES["success"]
+            # tail is empty.  we're finished
+            ctx.state.string_position = ctx.string_position
+            ctx.has_matched = ctx.MATCHED
+            return True
+        ctx.state.marks_push()
+
+    # Case 2: Repetition resumed, "forwardtracking"
+    else:
+        if ctx.child_context.has_matched == ctx.MATCHED:
+            ctx.has_matched = ctx.MATCHED
+            return True
+        values = ctx.restore_values()
+        maxcount = values[0]
+        count = values[1]        
+        ctx.state.string_position = ctx.string_position
+        if count_repetitions(space, ctx, 1) == 0:
+            # Tail didn't match and no more repetitions --> fail
+            ctx.state.marks_pop_discard()
+            ctx.has_matched = ctx.NOT_MATCHED
+            return True
+        ctx.skip_char(1)
+        count += 1
+        ctx.state.marks_pop_keep()
+
+    # Try to match tail
+    if maxcount == MAXREPEAT or count <= maxcount:
+        ctx.state.string_position = ctx.string_position
+        ctx.push_new_context(ctx.peek_code(1) + 1)
+        ctx.backup_value(maxcount)
+        ctx.backup_value(count)
+        return False
+
+    # Failed
+    ctx.state.marks_pop_discard()
+    ctx.has_matched = ctx.NOT_MATCHED
+    return True
+
 def op_jump(space, ctx):
     # jump forward
     # <JUMP>/<INFO> <offset>
@@ -630,7 +688,7 @@
     None, #REPEAT,
     op_repeat_one,
     None, #SUBPATTERN,
-    None, #MIN_REPEAT_ONE
+    op_min_repeat_one,
 ]
 
 



More information about the Pypy-commit mailing list