|
|
|
@ -71,8 +71,8 @@ GLOBAL_FLAGS = SRE_FLAG_DEBUG | SRE_FLAG_TEMPLATE |
|
|
|
class Verbose(Exception): |
|
|
|
pass |
|
|
|
|
|
|
|
class Pattern: |
|
|
|
# main pattern object. keeps track of global attributes |
|
|
|
class State: |
|
|
|
# keeps track of state for parsing |
|
|
|
def __init__(self): |
|
|
|
self.flags = 0 |
|
|
|
self.groupdict = {} |
|
|
|
@ -108,8 +108,8 @@ class Pattern: |
|
|
|
|
|
|
|
class SubPattern: |
|
|
|
# a subpattern, in intermediate form |
|
|
|
def __init__(self, pattern, data=None): |
|
|
|
self.pattern = pattern |
|
|
|
def __init__(self, state, data=None): |
|
|
|
self.state = state |
|
|
|
if data is None: |
|
|
|
data = [] |
|
|
|
self.data = data |
|
|
|
@ -163,7 +163,7 @@ class SubPattern: |
|
|
|
del self.data[index] |
|
|
|
def __getitem__(self, index): |
|
|
|
if isinstance(index, slice): |
|
|
|
return SubPattern(self.pattern, self.data[index]) |
|
|
|
return SubPattern(self.state, self.data[index]) |
|
|
|
return self.data[index] |
|
|
|
def __setitem__(self, index, code): |
|
|
|
self.data[index] = code |
|
|
|
@ -202,7 +202,7 @@ class SubPattern: |
|
|
|
lo = lo + 1 |
|
|
|
hi = hi + 1 |
|
|
|
elif op is GROUPREF: |
|
|
|
i, j = self.pattern.groupwidths[av] |
|
|
|
i, j = self.state.groupwidths[av] |
|
|
|
lo = lo + i |
|
|
|
hi = hi + j |
|
|
|
elif op is GROUPREF_EXISTS: |
|
|
|
@ -940,28 +940,28 @@ def fix_flags(src, flags): |
|
|
|
raise ValueError("ASCII and LOCALE flags are incompatible") |
|
|
|
return flags |
|
|
|
|
|
|
|
def parse(str, flags=0, pattern=None): |
|
|
|
def parse(str, flags=0, state=None): |
|
|
|
# parse 're' pattern into list of (opcode, argument) tuples |
|
|
|
|
|
|
|
source = Tokenizer(str) |
|
|
|
|
|
|
|
if pattern is None: |
|
|
|
pattern = Pattern() |
|
|
|
pattern.flags = flags |
|
|
|
pattern.str = str |
|
|
|
if state is None: |
|
|
|
state = State() |
|
|
|
state.flags = flags |
|
|
|
state.str = str |
|
|
|
|
|
|
|
try: |
|
|
|
p = _parse_sub(source, pattern, flags & SRE_FLAG_VERBOSE, 0) |
|
|
|
p = _parse_sub(source, state, flags & SRE_FLAG_VERBOSE, 0) |
|
|
|
except Verbose: |
|
|
|
# the VERBOSE flag was switched on inside the pattern. to be |
|
|
|
# on the safe side, we'll parse the whole thing again... |
|
|
|
pattern = Pattern() |
|
|
|
pattern.flags = flags | SRE_FLAG_VERBOSE |
|
|
|
pattern.str = str |
|
|
|
state = State() |
|
|
|
state.flags = flags | SRE_FLAG_VERBOSE |
|
|
|
state.str = str |
|
|
|
source.seek(0) |
|
|
|
p = _parse_sub(source, pattern, True, 0) |
|
|
|
p = _parse_sub(source, state, True, 0) |
|
|
|
|
|
|
|
p.pattern.flags = fix_flags(str, p.pattern.flags) |
|
|
|
p.state.flags = fix_flags(str, p.state.flags) |
|
|
|
|
|
|
|
if source.next is not None: |
|
|
|
assert source.next == ")" |
|
|
|
@ -972,7 +972,7 @@ def parse(str, flags=0, pattern=None): |
|
|
|
|
|
|
|
return p |
|
|
|
|
|
|
|
def parse_template(source, pattern): |
|
|
|
def parse_template(source, state): |
|
|
|
# parse 're' replacement string into list of literals and |
|
|
|
# group references |
|
|
|
s = Tokenizer(source) |
|
|
|
@ -982,14 +982,14 @@ def parse_template(source, pattern): |
|
|
|
literal = [] |
|
|
|
lappend = literal.append |
|
|
|
def addgroup(index, pos): |
|
|
|
if index > pattern.groups: |
|
|
|
if index > state.groups: |
|
|
|
raise s.error("invalid group reference %d" % index, pos) |
|
|
|
if literal: |
|
|
|
literals.append(''.join(literal)) |
|
|
|
del literal[:] |
|
|
|
groups.append((len(literals), index)) |
|
|
|
literals.append(None) |
|
|
|
groupindex = pattern.groupindex |
|
|
|
groupindex = state.groupindex |
|
|
|
while True: |
|
|
|
this = sget() |
|
|
|
if this is None: |
|
|
|
|