-- properly reset groups in findall (bug #117612)

-- fixed negative lookbehind to work correctly at the beginning
of the target string (bug #117242)

-- improved syntax check; you can no longer refer to a group
inside itself (bug #110866)
diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py
index 7c36d4f..5334e06 100644
--- a/Lib/sre_parse.py
+++ b/Lib/sre_parse.py
@@ -62,14 +62,20 @@
     # master pattern object.  keeps track of global attributes
     def __init__(self):
         self.flags = 0
+        self.open = []
         self.groups = 1
         self.groupdict = {}
-    def getgroup(self, name=None):
+    def opengroup(self, name=None):
         gid = self.groups
         self.groups = gid + 1
         if name:
             self.groupdict[name] = gid
+        self.open.append(gid)
         return gid
+    def closegroup(self, gid):
+        self.open.remove(gid)
+    def checkgroup(self, gid):
+        return gid < self.groups and gid not in self.open
 
 class SubPattern:
     # a subpattern, in intermediate form
@@ -278,6 +284,8 @@
             # got at least one decimal digit; this is a group reference
             group = _group(escape, state.groups)
             if group:
+                if not state.checkgroup(group):
+                    raise error, "cannot refer to open group"
                 return GROUPREF, group
             raise ValueError
         if len(escape) == 2:
@@ -547,10 +555,12 @@
                     # anonymous group
                     group = None
                 else:
-                    group = state.getgroup(name)
+                    group = state.opengroup(name)
                 p = _parse_sub(source, state)
                 if not source.match(")"):
                     raise error, "unbalanced parenthesis"
+                if group is not None:
+                    state.closegroup(group)
                 subpattern.append((SUBPATTERN, (group, p)))
             else:
                 while 1: