1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
import sys, random
from rpython.rlib import debug
from rpython.rlib.rsre.rsre_core import _adjust, match_context, search_context
from rpython.rlib.rsre.rsre_core import MODE_FULL
from rpython.rlib.rsre.rsre_core import StrMatchContext, EndOfString
class Position(object):
def __init__(self, p):
assert isinstance(p, int)
if p < 0:
raise debug.NegativeArgumentNotAllowed(
"making a Position with byte index %r" % p)
self._p = p
def __repr__(self):
return '<Position %d>' % (self._p)
def __cmp__(self, other):
if isinstance(other, Position):
return cmp(self._p, other._p)
if type(other) is int and other == -1:
return cmp(self._p, -1)
raise TypeError("cannot compare %r with %r" % (self, other))
class MatchContextForTests(StrMatchContext):
"""Concrete subclass for matching in a plain string, tweaked for tests"""
ZERO = Position(0)
def next(self, position):
assert isinstance(position, Position)
return Position(position._p + 1)
next_indirect = next
def prev(self, position):
assert isinstance(position, Position)
if position._p == 0:
raise EndOfString
return Position(position._p - 1)
prev_indirect = prev
def next_n(self, position, n, end_position):
assert isinstance(position, Position)
assert isinstance(end_position, Position)
assert position._p <= end_position._p
r = position._p + n
if r > end_position._p:
raise EndOfString
return Position(r)
def prev_n(self, position, n, start_position):
assert isinstance(position, Position)
assert isinstance(start_position, Position)
assert position._p >= start_position._p
r = position._p - n
if r < start_position._p:
raise EndOfString
return Position(r)
def _real_pos(self, position):
if type(position) is int and position == -1:
return -1
assert isinstance(position, Position)
return position._p
def group(self, groupnum=0):
frm, to = self.span(groupnum)
if self.ZERO <= frm <= to:
return self._string[self._real_pos(frm):self._real_pos(to)]
else:
return None
def str(self, position):
assert isinstance(position, Position)
return ord(self._string[position._p])
def debug_check_pos(self, position):
assert isinstance(position, Position)
#def minimum_distance(self, position_low, position_high):
# """Return an estimate. The real value may be higher."""
# assert isinstance(position_low, Position)
# assert isinstance(position_high, Position)
# dist = position_high._p - position_low._p
# if dist == 0:
# return 0
# return random.randrange(1, dist + 1)
def maximum_distance(self, position_low, position_high):
"""Return an estimate. The real value may be lower."""
assert isinstance(position_low, Position)
assert isinstance(position_high, Position)
return position_high._p - position_low._p + random.randrange(0, 10)
def bytes_difference(self, position1, position2):
assert isinstance(position1, Position)
assert isinstance(position2, Position)
return position1._p - position2._p
def get_single_byte(self, base_position, index):
assert isinstance(base_position, Position)
assert isinstance(index, int)
return ord(self._string[base_position._p + index])
def go_forward_by_bytes(self, base_position, index):
assert isinstance(base_position, Position)
assert isinstance(index, int)
return Position(base_position._p + index)
def match(pattern, string, start=0, end=sys.maxint, fullmatch=False):
start, end = _adjust(start, end, len(string))
start = Position(start)
end = Position(end)
ctx = MatchContextForTests(string, start, end)
if fullmatch:
ctx.match_mode = MODE_FULL
if match_context(ctx, pattern):
return ctx
else:
return None
def fullmatch(pattern, string, start=0, end=sys.maxint):
return match(pattern, string, start, end, fullmatch=True)
def search(pattern, string, start=0, end=sys.maxint):
start, end = _adjust(start, end, len(string))
start = Position(start)
end = Position(end)
ctx = MatchContextForTests(string, start, end)
if search_context(ctx, pattern):
return ctx
else:
return None
|