diff options
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/sre.py | 5 | ||||
-rw-r--r-- | Lib/sre_compile.py | 51 | ||||
-rw-r--r-- | Lib/sre_constants.py | 3 | ||||
-rw-r--r-- | Lib/sre_parse.py | 2 |
4 files changed, 33 insertions, 28 deletions
@@ -98,7 +98,10 @@ def _compile(pattern, flags=0): return _cache[key] except KeyError: pass - p = sre_compile.compile(pattern, flags) + try: + p = sre_compile.compile(pattern, flags) + except error, v: + raise error, v # invalid expression if len(_cache) >= _MAXCACHE: _cache.clear() _cache[key] = p diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py index 8fdcecf..abd619e 100644 --- a/Lib/sre_compile.py +++ b/Lib/sre_compile.py @@ -73,6 +73,13 @@ def _charset(charset, fixup=None): return out return charset +def _simple(av): + # check if av is a "simple" operator + lo, hi = av[2].getwidth() + if lo == 0: + raise error, "nothing to repeat" + return lo == hi == 1 and av[2][0][0] != SUBPATTERN + def _compile(code, pattern, flags): # internal: compile a (sub)pattern emit = code.append @@ -116,10 +123,9 @@ def _compile(code, pattern, flags): code[skip] = len(code) - skip elif op is ANY: if flags & SRE_FLAG_DOTALL: - emit(OPCODES[op]) + emit(OPCODES[ANY_ALL]) else: - emit(OPCODES[CATEGORY]) - emit(CHCODES[CATEGORY_NOT_LINEBREAK]) + emit(OPCODES[ANY]) elif op in (REPEAT, MIN_REPEAT, MAX_REPEAT): if flags & SRE_FLAG_TEMPLATE: raise error, "internal: unsupported template operator" @@ -130,30 +136,25 @@ def _compile(code, pattern, flags): _compile(code, av[2], flags) emit(OPCODES[SUCCESS]) code[skip] = len(code) - skip + elif _simple(av) and op == MAX_REPEAT: + emit(OPCODES[REPEAT_ONE]) + skip = len(code); emit(0) + emit(av[0]) + emit(av[1]) + _compile(code, av[2], flags) + emit(OPCODES[SUCCESS]) + code[skip] = len(code) - skip else: - lo, hi = av[2].getwidth() - if lo == 0: - raise error, "nothing to repeat" - if 0 and lo == hi == 1 and op is MAX_REPEAT: - # FIXME: <fl> fast and wrong (but we'll fix that) - emit(OPCODES[REPEAT_ONE]) - skip = len(code); emit(0) - emit(av[0]) - emit(av[1]) - _compile(code, av[2], flags) - emit(OPCODES[SUCCESS]) - code[skip] = len(code) - skip + emit(OPCODES[REPEAT]) + skip = len(code); emit(0) + emit(av[0]) + emit(av[1]) + _compile(code, av[2], flags) + code[skip] = len(code) - skip + if op == MAX_REPEAT: + emit(OPCODES[MAX_UNTIL]) else: - emit(OPCODES[REPEAT]) - skip = len(code); emit(0) - emit(av[0]) - emit(av[1]) - _compile(code, av[2], flags) - code[skip] = len(code) - skip - if op == MAX_REPEAT: - emit(OPCODES[MAX_UNTIL]) - else: - emit(OPCODES[MIN_UNTIL]) + emit(OPCODES[MIN_UNTIL]) elif op is SUBPATTERN: if av[0]: emit(OPCODES[MARK]) diff --git a/Lib/sre_constants.py b/Lib/sre_constants.py index e595915..5a20930 100644 --- a/Lib/sre_constants.py +++ b/Lib/sre_constants.py @@ -20,6 +20,7 @@ FAILURE = "failure" SUCCESS = "success" ANY = "any" +ANY_ALL = "any_all" ASSERT = "assert" ASSERT_NOT = "assert_not" AT = "at" @@ -81,7 +82,7 @@ OPCODES = [ # failure=0 success=1 (just because it looks better that way :-) FAILURE, SUCCESS, - ANY, + ANY, ANY_ALL, ASSERT, ASSERT_NOT, AT, BRANCH, diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index 1eec3d3..1c1d0d5 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -142,7 +142,7 @@ class SubPattern: for av in av[1]: l, h = av.getwidth() i = min(i, l) - j = min(j, h) + j = max(j, h) lo = lo + i hi = hi + j elif op is CALL: |