[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