summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/sre.py5
-rw-r--r--Lib/sre_compile.py51
-rw-r--r--Lib/sre_constants.py3
-rw-r--r--Lib/sre_parse.py2
4 files changed, 33 insertions, 28 deletions
diff --git a/Lib/sre.py b/Lib/sre.py
index 3e125a7..edfefc1 100644
--- a/Lib/sre.py
+++ b/Lib/sre.py
@@ -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: