]> granicus.if.org Git - python/commitdiff
Delete this unused relic.
authorGuido van Rossum <guido@python.org>
Thu, 26 Mar 1998 21:07:14 +0000 (21:07 +0000)
committerGuido van Rossum <guido@python.org>
Thu, 26 Mar 1998 21:07:14 +0000 (21:07 +0000)
Lib/ni1.py [deleted file]
Lib/re1.py [deleted file]

diff --git a/Lib/ni1.py b/Lib/ni1.py
deleted file mode 100644 (file)
index 95c9b59..0000000
+++ /dev/null
@@ -1,434 +0,0 @@
-"""New import scheme with package support.
-
-Quick Reference
----------------
-
-- To enable package support, execute "import ni" before importing any
-  packages.  Importing this module automatically installs the relevant
-  import hooks.
-
-- To create a package named spam containing sub-modules ham, bacon and
-  eggs, create a directory spam somewhere on Python's module search
-  path (i.e. spam's parent directory must be one of the directories in
-  sys.path or $PYTHONPATH); then create files ham.py, bacon.py and
-  eggs.py inside spam.
-
-- To import module ham from package spam and use function hamneggs()
-  from that module, you can either do
-
-    import spam.ham            # *not* "import spam" !!!
-    spam.ham.hamneggs()
-
-  or
-
-    from spam import ham
-    ham.hamneggs()
-
-  or
-
-    from spam.ham import hamneggs
-    hamneggs()
-
-- Importing just "spam" does not do what you expect: it creates an
-  empty package named spam if one does not already exist, but it does
-  not import spam's submodules.  The only submodule that is guaranteed
-  to be imported is spam.__init__, if it exists.  Note that
-  spam.__init__ is a submodule of package spam.  It can reference to
-  spam's namespace via the '__.' prefix, for instance
-
-    __.spam_inited = 1         # Set a package-level variable
-
-
-
-Theory of Operation
--------------------
-
-A Package is a module that can contain other modules.  Packages can be
-nested.  Package introduce dotted names for modules, like P.Q.M, which
-could correspond to a file P/Q/M.py found somewhere on sys.path.  It
-is possible to import a package itself, though this makes little sense
-unless the package contains a module called __init__.
-
-A package has two variables that control the namespace used for
-packages and modules, both initialized to sensible defaults the first
-time the package is referenced.
-
-(1) A package's *module search path*, contained in the per-package
-variable __path__, defines a list of *directories* where submodules or
-subpackages of the package are searched.  It is initialized to the
-directory containing the package.  Setting this variable to None makes
-the module search path default to sys.path (this is not quite the same
-as setting it to sys.path, since the latter won't track later
-assignments to sys.path).
-
-(2) A package's *import domain*, contained in the per-package variable
-__domain__, defines a list of *packages* that are searched (using
-their respective module search paths) to satisfy imports.  It is
-initialized to the list cosisting of the package itself, its parent
-package, its parent's parent, and so on, ending with the root package
-(the nameless package containing all top-level packages and modules,
-whose module search path is None, implying sys.path).
-
-The default domain implements a search algorithm called "expanding
-search".  An alternative search algorithm called "explicit search"
-fixes the import search path to contain only the root package,
-requiring the modules in the package to name all imported modules by
-their full name.  The convention of using '__' to refer to the current
-package (both as a per-module variable and in module names) can be
-used by packages using explicit search to refer to modules in the same
-package; this combination is known as "explicit-relative search".
-
-The PackageImporter and PackageLoader classes together implement the
-following policies:
-
-- There is a root package, whose name is ''.  It cannot be imported
-  directly but may be referenced, e.g. by using '__' from a top-level
-  module.
-
-- In each module or package, the variable '__' contains a reference to
-  the parent package; in the root package, '__' points to itself.
-
-- In the name for imported modules (e.g. M in "import M" or "from M
-  import ..."), a leading '__' refers to the current package (i.e.
-  the package containing the current module); leading '__.__' and so
-  on refer to the current package's parent, and so on.  The use of
-  '__' elsewhere in the module name is not supported.
-
-- Modules are searched using the "expanding search" algorithm by
-  virtue of the default value for __domain__.
-
-- If A.B.C is imported, A is searched using __domain__; then
-  subpackage B is searched in A using its __path__, and so on.
-
-- Built-in modules have priority: even if a file sys.py exists in a
-  package, "import sys" imports the built-in sys module.
-
-- The same holds for frozen modules, for better or for worse.
-
-- Submodules and subpackages are not automatically loaded when their
-  parent packages is loaded.
-
-- The construct "from package import *" is illegal.  (It can still be
-  used to import names from a module.)
-
-- When "from package import module1, module2, ..." is used, those
-    modules are explicitly loaded.
-
-- When a package is loaded, if it has a submodule __init__, that
-  module is loaded.  This is the place where required submodules can
-  be loaded, the __path__ variable extended, etc.  The __init__ module
-  is loaded even if the package was loaded only in order to create a
-  stub for a sub-package: if "import P.Q.R" is the first reference to
-  P, and P has a submodule __init__, P.__init__ is loaded before P.Q
-  is even searched.
-
-Caveats:
-
-- It is possible to import a package that has no __init__ submodule;
-  this is not particularly useful but there may be useful applications
-  for it (e.g. to manipulate its search paths from the outside!).
-
-- There are no special provisions for os.chdir().  If you plan to use
-  os.chdir() before you have imported all your modules, it is better
-  not to have relative pathnames in sys.path.  (This could actually be
-  fixed by changing the implementation of path_join() in the hook to
-  absolutize paths.)
-
-- Packages and modules are introduced in sys.modules as soon as their
-  loading is started.  When the loading is terminated by an exception,
-  the sys.modules entries remain around.
-
-- There are no special measures to support mutually recursive modules,
-  but it will work under the same conditions where it works in the
-  flat module space system.
-
-- Sometimes dummy entries (whose value is None) are entered in
-  sys.modules, to indicate that a particular module does not exist --
-  this is done to speed up the expanding search algorithm when a
-  module residing at a higher level is repeatedly imported (Python
-  promises that importing a previously imported module is cheap!)
-
-- Although dynamically loaded extensions are allowed inside packages,
-  the current implementation (hardcoded in the interpreter) of their
-  initialization may cause problems if an extension invokes the
-  interpreter during its initialization.
-
-- reload() may find another version of the module only if it occurs on
-  the package search path.  Thus, it keeps the connection to the
-  package to which the module belongs, but may find a different file.
-
-XXX Need to have an explicit name for '', e.g. '__root__'.
-
-"""
-
-
-import imp
-import string
-import sys
-import __builtin__
-
-import ihooks
-from ihooks import ModuleLoader, ModuleImporter
-
-
-class PackageLoader(ModuleLoader):
-
-    """A subclass of ModuleLoader with package support.
-
-    find_module_in_dir() will succeed if there's a subdirectory with
-    the given name; load_module() will create a stub for a package and
-    load its __init__ module if it exists.
-
-    """
-
-    def find_module_in_dir(self, name, dir):
-       if dir is not None:
-           dirname = self.hooks.path_join(dir, name)
-           if self.hooks.path_isdir(dirname):
-               return None, dirname, ('', '', 'PACKAGE')
-       return ModuleLoader.find_module_in_dir(self, name, dir)
-
-    def load_module(self, name, stuff):
-       file, filename, info = stuff
-       suff, mode, type = info
-       if type == 'PACKAGE':
-           return self.load_package(name, stuff)
-       if sys.modules.has_key(name):
-           m = sys.modules[name]
-       else:
-           sys.modules[name] = m = imp.new_module(name)
-       self.set_parent(m)
-       if type == imp.C_EXTENSION and '.' in name:
-           return self.load_dynamic(name, stuff)
-       else:
-           return ModuleLoader.load_module(self, name, stuff)
-
-    def load_dynamic(self, name, stuff):
-       file, filename, (suff, mode, type) = stuff
-       # Hack around restriction in imp.load_dynamic()
-       i = string.rfind(name, '.')
-       tail = name[i+1:]
-       if sys.modules.has_key(tail):
-           save = sys.modules[tail]
-       else:
-           save = None
-       sys.modules[tail] = imp.new_module(name)
-       try:
-           m = imp.load_dynamic(tail, filename, file)
-       finally:
-           if save:
-               sys.modules[tail] = save
-           else:
-               del sys.modules[tail]
-       sys.modules[name] = m
-       return m
-
-    def load_package(self, name, stuff):
-       file, filename, info = stuff
-       if sys.modules.has_key(name):
-           package = sys.modules[name]
-       else:
-           sys.modules[name] = package = imp.new_module(name)
-       package.__path__ = [filename]
-       self.init_package(package)
-       return package
-
-    def init_package(self, package):
-       self.set_parent(package)
-       self.set_domain(package)
-       self.call_init_module(package)
-
-    def set_parent(self, m):
-       name = m.__name__
-       if '.' in name:
-           name = name[:string.rfind(name, '.')]
-       else:
-           name = ''
-       m.__ = sys.modules[name]
-
-    def set_domain(self, package):
-       name = package.__name__
-       package.__domain__ = domain = [name]
-       while '.' in name:
-           name = name[:string.rfind(name, '.')]
-           domain.append(name)
-       if name:
-           domain.append('')
-
-    def call_init_module(self, package):
-       stuff = self.find_module('__init__', package.__path__)
-       if stuff:
-           m = self.load_module(package.__name__ + '.__init__', stuff)
-           package.__init__ = m
-
-
-class PackageImporter(ModuleImporter):
-
-    """Importer that understands packages and '__'."""
-
-    def __init__(self, loader = None, verbose = 0):
-       ModuleImporter.__init__(self,
-       loader or PackageLoader(None, verbose), verbose)
-
-    def import_module(self, name, globals={}, locals={}, fromlist=[]):
-       if globals.has_key('__'):
-           package = globals['__']
-       else:
-           # No calling context, assume in root package
-           package = sys.modules['']
-       if name[:3] in ('__.', '__'):
-           p = package
-           name = name[3:]
-           while name[:3] in ('__.', '__'):
-               p = p.__
-               name = name[3:]
-           if not name:
-               return self.finish(package, p, '', fromlist)
-           if '.' in name:
-               i = string.find(name, '.')
-               name, tail = name[:i], name[i:]
-           else:
-               tail = ''
-           mname = p.__name__ and p.__name__+'.'+name or name
-           m = self.get1(mname)
-           return self.finish(package, m, tail, fromlist)
-       if '.' in name:
-           i = string.find(name, '.')
-           name, tail = name[:i], name[i:]
-       else:
-           tail = ''
-       for pname in package.__domain__:
-           mname = pname and pname+'.'+name or name
-           m = self.get0(mname)
-           if m: break
-       else:
-           raise ImportError, "No such module %s" % name
-       return self.finish(m, m, tail, fromlist)
-
-    def finish(self, module, m, tail, fromlist):
-       # Got ....A; now get ....A.B.C.D
-       yname = m.__name__
-       if tail and sys.modules.has_key(yname + tail): # Fast path
-           yname, tail = yname + tail, ''
-           m = self.get1(yname)
-       while tail:
-           i = string.find(tail, '.', 1)
-           if i > 0:
-               head, tail = tail[:i], tail[i:]
-           else:
-               head, tail = tail, ''
-           yname = yname + head
-           m = self.get1(yname)
-
-       # Got ....A.B.C.D; now finalize things depending on fromlist
-       if not fromlist:
-           return module
-       if '__' in fromlist:
-           raise ImportError, "Can't import __ from anywhere"
-       if not hasattr(m, '__path__'): return m
-       if '*' in fromlist:
-           raise ImportError, "Can't import * from a package"
-       for f in fromlist:
-           if hasattr(m, f): continue
-           fname = yname + '.' + f
-           self.get1(fname)
-       return m
-
-    def get1(self, name):
-       m = self.get(name)
-       if not m:
-           raise ImportError, "No module named %s" % name
-       return m
-
-    def get0(self, name):
-       m = self.get(name)
-       if not m:
-           sys.modules[name] = None
-       return m
-
-    def get(self, name):
-       # Internal routine to get or load a module when its parent exists
-       if sys.modules.has_key(name):
-           return sys.modules[name]
-       if '.' in name:
-           i = string.rfind(name, '.')
-           head, tail = name[:i], name[i+1:]
-       else:
-           head, tail = '', name
-       path = sys.modules[head].__path__
-       stuff = self.loader.find_module(tail, path)
-       if not stuff:
-           return None
-       sys.modules[name] = m = self.loader.load_module(name, stuff)
-       if head:
-           setattr(sys.modules[head], tail, m)
-       return m
-
-    def reload(self, module):
-       name = module.__name__
-       if '.' in name:
-           i = string.rfind(name, '.')
-           head, tail = name[:i], name[i+1:]
-           path = sys.modules[head].__path__
-       else:
-           tail = name
-           path = sys.modules[''].__path__
-       stuff = self.loader.find_module(tail, path)
-       if not stuff:
-           raise ImportError, "No module named %s" % name
-       return self.loader.load_module(name, stuff)
-
-    def unload(self, module):
-       if hasattr(module, '__path__'):
-           raise ImportError, "don't know how to unload packages yet"
-       PackageImporter.unload(self, module)
-
-    def install(self):
-       if not sys.modules.has_key(''):
-           sys.modules[''] = package = imp.new_module('')
-           package.__path__ = None
-           self.loader.init_package(package)
-           for m in sys.modules.values():
-               if not m: continue
-               if not hasattr(m, '__'):
-                   self.loader.set_parent(m)
-       ModuleImporter.install(self)
-
-
-def install(v = 0):
-    ihooks.install(PackageImporter(None, v))
-
-def uninstall():
-    ihooks.uninstall()
-
-def ni(v = 0):
-    install(v)
-
-def no():
-    uninstall()
-
-def test():
-    import pdb
-    try:
-       testproper()
-    except:
-       sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info()
-       print
-       print sys.last_type, ':', sys.last_value
-       print
-       pdb.pm()
-
-def testproper():
-    install(1)
-    try:
-       import mactest
-       print dir(mactest)
-       raw_input('OK?')
-    finally:
-       uninstall()
-
-
-if __name__ == '__main__':
-    test()
-else:
-    install()
diff --git a/Lib/re1.py b/Lib/re1.py
deleted file mode 100644 (file)
index 6c24797..0000000
+++ /dev/null
@@ -1,1508 +0,0 @@
-#!/usr/bin/env python
-# -*- mode: python -*-
-# $Id$
-
-import string
-import reop
-
-# reop.error and re.error should be the same, since exceptions can be
-# raised from  either module.
-error = reop.error # 're error'
-
-from reop import NORMAL, CHARCLASS, REPLACEMENT
-from reop import CHAR, MEMORY_REFERENCE, SYNTAX, NOT_SYNTAX, SET
-from reop import WORD_BOUNDARY, NOT_WORD_BOUNDARY, BEGINNING_OF_BUFFER, END_OF_BUFFER
-
-# compilation flags
-
-IGNORECASE = I = 0x01
-
-MULTILINE = M = 0x02
-DOTALL = S = 0x04
-VERBOSE = X = 0x08
-
-repetition_operators = ['*', '*?', '+', '+?', '?', '??', '{n}', '{n}?',
-                       '{n,}', '{n,}?', '{n,m}', '{n,m}?']
-
-#
-#
-#
-
-def valid_identifier(id):
-    if len(id) == 0:
-       return 0
-    if (not reop.syntax_table[id[0]] & reop.word) or \
-       (reop.syntax_table[id[0]] & reop.digit):
-       return 0
-    for char in id[1:]:
-       if not reop.syntax_table[char] & reop.word:
-           return 0
-    return 1
-
-#
-#
-#
-
-_cache = {}
-_MAXCACHE = 20
-
-def _cachecompile(pattern, flags=0):
-    key = (pattern, flags)
-    try:
-       return _cache[key]
-    except KeyError:
-       pass
-    value = compile(pattern, flags)
-    if len(_cache) >= _MAXCACHE:
-       _cache.clear()
-    _cache[key] = value
-    return value
-
-def match(pattern, string, flags=0):
-    return _cachecompile(pattern, flags).match(string)
-  
-def search(pattern, string, flags=0):
-    return _cachecompile(pattern, flags).search(string)
-  
-def sub(pattern, repl, string, count=0):
-    if type(pattern) == type(''):
-       pattern = _cachecompile(pattern)
-    return pattern.sub(repl, string, count)
-
-def subn(pattern, repl, string, count=0):
-    if type(pattern) == type(''):
-       pattern = _cachecompile(pattern)
-    return pattern.subn(repl, string, count)
-  
-def split(pattern, string, maxsplit=0):
-    if type(pattern) == type(''):
-       pattern = _cachecompile(pattern)
-    return pattern.split(string, maxsplit)
-
-#
-#
-#
-
-def _expand(m, repl):
-    results = []
-    index = 0
-    size = len(repl)
-    while index < size:
-       found = string.find(repl, '\\', index)
-       if found < 0:
-           results.append(repl[index:])
-           break
-       if found > index:
-           results.append(repl[index:found])
-       escape_type, value, index = expand_escape(repl, found+1, REPLACEMENT)
-       if escape_type == CHAR:
-           results.append(value)
-       elif escape_type == MEMORY_REFERENCE:
-           r = m.group(value)
-           if r is None:
-               raise error, ('group "' + str(value) + '" did not contribute '
-                             'to the match')
-           results.append(m.group(value))
-       else:
-           raise error, "bad escape in replacement"
-    return string.join(results, '')
-
-class RegexObject:
-    def __init__(self, pattern, flags, code, num_regs, groupindex):
-       self.code = code
-       self.num_regs = num_regs
-       self.flags = flags
-       self.pattern = pattern
-       self.groupindex = groupindex
-       self.fastmap = build_fastmap(code)
-       
-       if code[0].name == 'bol':
-           self.anchor = 1
-           
-       elif code[0].name == 'begbuf':
-           self.anchor = 2
-           
-       else:
-           self.anchor = 0
-           
-       self.buffer = assemble(code)
-    def search(self, string, pos=0):
-       regs = reop.search(self.buffer,
-                          self.num_regs,
-                          self.flags,
-                          self.fastmap.can_be_null,
-                          self.fastmap.fastmap(),
-                          self.anchor,
-                          string,
-                          pos)
-       if regs is None:
-           return None
-       
-       return MatchObject(self,
-                          string,
-                          pos,
-                          regs)
-    
-    def match(self, string, pos=0):
-       regs = reop.match(self.buffer,
-                         self.num_regs,
-                         self.flags,
-                         self.fastmap.can_be_null,
-                         self.fastmap.fastmap(),
-                         self.anchor,
-                         string,
-                         pos)
-       if regs is None:
-           return None
-       
-       return MatchObject(self,
-                          string,
-                          pos,
-                          regs)
-    
-    def sub(self, repl, string, count=0):
-        return self.subn(repl, string, count)[0]
-    
-    def subn(self, repl, source, count=0):
-       if count < 0:
-           raise ValueError, "negative substibution count"
-       if count == 0:
-           import sys
-           count = sys.maxint
-       if type(repl) == type(''):
-           if '\\' in repl:
-               repl = lambda m, r=repl: _expand(m, r)
-           else:
-               repl = lambda m, r=repl: r
-       n = 0           # Number of matches
-       pos = 0         # Where to start searching
-       lastmatch = -1  # End of last match
-       results = []    # Substrings making up the result
-       end = len(source)
-       while n < count and pos <= end:
-           m = self.search(source, pos)
-           if not m:
-               break
-           i, j = m.span(0)
-           if i == j == lastmatch:
-               # Empty match adjacent to previous match
-               pos = pos + 1
-               results.append(source[lastmatch:pos])
-               continue
-           if pos < i:
-               results.append(source[pos:i])
-           results.append(repl(m))
-           pos = lastmatch = j
-           if i == j:
-               # Last match was empty; don't try here again
-               pos = pos + 1
-               results.append(source[lastmatch:pos])
-           n = n + 1
-       results.append(source[pos:])
-       return (string.join(results, ''), n)
-                                                                           
-    def split(self, source, maxsplit=0):
-       if maxsplit < 0:
-           raise error, "negative split count"
-       if maxsplit == 0:
-           import sys
-           maxsplit = sys.maxint
-       n = 0
-       pos = 0
-       lastmatch = 0
-       results = []
-       end = len(source)
-       while n < maxsplit:
-           m = self.search(source, pos)
-           if not m:
-               break
-           i, j = m.span(0)
-           if i == j:
-               # Empty match
-               if pos >= end:
-                   break
-               pos = pos+1
-               continue
-           results.append(source[lastmatch:i])
-           g = m.group()
-           if g:
-               results[len(results):] = list(g)
-           pos = lastmatch = j
-       results.append(source[lastmatch:])
-       return results
-
-class MatchObject:
-    def __init__(self, re, string, pos, regs):
-       self.re = re
-       self.string = string
-       self.pos = pos
-       self.regs = regs
-       
-    def start(self, g):
-       if type(g) == type(''):
-           try:
-               g = self.re.groupindex[g]
-           except (KeyError, TypeError):
-               raise IndexError, ('group "' + g + '" is undefined')
-       return self.regs[g][0]
-    
-    def end(self, g):
-       if type(g) == type(''):
-           try:
-               g = self.re.groupindex[g]
-           except (KeyError, TypeError):
-               raise IndexError, ('group "' + g + '" is undefined')
-       return self.regs[g][1]
-    
-    def span(self, g):
-       if type(g) == type(''):
-           try:
-               g = self.re.groupindex[g]
-           except (KeyError, TypeError):
-               raise IndexError, ('group "' + g + '" is undefined')
-       return self.regs[g]
-    
-    def group(self, *groups):
-       if len(groups) == 0:
-           groups = range(1, self.re.num_regs)
-           use_all = 1
-       else:
-           use_all = 0
-       result = []
-       for g in groups:
-           if type(g) == type(''):
-               try:
-                   g = self.re.groupindex[g]
-               except (KeyError, TypeError):
-                   raise IndexError, ('group "' + g + '" is undefined')
-           if (self.regs[g][0] == -1) or (self.regs[g][1] == -1):
-               result.append(None)
-           else:
-               result.append(self.string[self.regs[g][0]:self.regs[g][1]])
-       if use_all or len(result) > 1:
-           return tuple(result)
-       elif len(result) == 1:
-           return result[0]
-       else:
-           return ()
-
-#
-# A set of classes to make assembly a bit easier, if a bit verbose.
-#
-
-class Instruction:
-    def __init__(self, opcode, size=1):
-       self.opcode = opcode
-       self.size = size
-    def assemble(self, position, labels):
-       return self.opcode
-    def __repr__(self):
-       return '%-15s' % (self.name)
-
-class End(Instruction):
-    name = 'end'
-    def __init__(self):
-       Instruction.__init__(self, chr(0))
-
-class Bol(Instruction):
-    name = 'bol'
-    def __init__(self):
-       self.name = 'bol'
-       Instruction.__init__(self, chr(1))
-
-class Eol(Instruction):
-    name = 'eol'
-    def __init__(self):
-       Instruction.__init__(self, chr(2))
-
-class Set(Instruction):
-    name = 'set'
-    def __init__(self, set, flags=0):
-       self.set = set
-       if flags & IGNORECASE: self.set=map(string.lower, self.set)
-       if len(set)==1: 
-           # If only one element, use the "exact" opcode (it'll be faster)
-           Instruction.__init__(self, chr(4), 2)
-       else:
-           # Use the "set" opcode
-           Instruction.__init__(self, chr(3), 33)
-    def assemble(self, position, labels):
-       if len(self.set)==1:
-           # If only one character in set, generate an "exact" opcode
-           return self.opcode + self.set[0]
-       result = self.opcode
-       temp = 0
-       for i, c in map(lambda x: (x, chr(x)), range(256)):
-           if c in self.set:
-               temp = temp | (1 << (i & 7))
-           if (i % 8) == 7:
-               result = result + chr(temp)
-               temp = 0
-       return result
-    def __repr__(self):
-       result = '%-15s' % (self.name)
-       self.set.sort()
-       # XXX this should print more intelligently
-       for char in self.set:
-           result = result + char
-       return result
-    
-class Exact(Instruction):
-    name = 'exact'
-    def __init__(self, char, flags):
-       self.char = char
-       if flags & IGNORECASE: self.char=string.lower(self.char)
-       Instruction.__init__(self, chr(4), 2)
-    def assemble(self, position, labels):
-       return self.opcode + self.char
-    def __repr__(self):
-       return '%-15s %s' % (self.name, `self.char`)
-    
-class AnyChar(Instruction):
-    name = 'anychar'
-    def __init__(self):
-       Instruction.__init__(self, chr(5))
-    def assemble(self, position, labels):
-       return self.opcode
-
-class MemoryInstruction(Instruction):
-    def __init__(self, opcode, register):
-       self.register = register
-       Instruction.__init__(self, opcode, 2)
-    def assemble(self, position, labels):
-       return self.opcode + chr(self.register)
-    def __repr__(self):
-       return '%-15s %i' % (self.name, self.register)
-
-class StartMemory(MemoryInstruction):
-    name = 'start_memory'
-    def __init__(self, register):
-       MemoryInstruction.__init__(self, chr(6), register)
-
-class EndMemory(MemoryInstruction):
-    name = 'end_memory'
-    def __init__(self, register):
-       MemoryInstruction.__init__(self, chr(7), register)
-
-class MatchMemory(MemoryInstruction):
-    name = 'match_memory'
-    def __init__(self, register):
-       MemoryInstruction.__init__(self, chr(8), register)
-
-class JumpInstruction(Instruction):
-    def __init__(self, opcode, label):
-       self.label = label
-       Instruction.__init__(self, opcode, 3)
-    def compute_offset(self, start, dest):
-       return dest - (start + 3)
-    def pack_offset(self, offset):
-       if offset > 32767:
-           raise error, 'offset out of range (pos)'
-       elif offset < -32768:
-           raise error, 'offset out of range (neg)'
-       elif offset < 0:
-           offset = offset + 65536
-       return chr(offset & 0xff) + chr((offset >> 8) & 0xff)
-    def assemble(self, position, labels):
-       return self.opcode + \
-              self.pack_offset(self.compute_offset(position,
-                                                   labels[self.label]))
-    def __repr__(self):
-       return '%-15s %i' % (self.name, self.label)
-
-class Jump(JumpInstruction):
-    name = 'jump'
-    def __init__(self, label):
-       JumpInstruction.__init__(self, chr(9), label)
-
-class StarJump(JumpInstruction):
-    name = 'star_jump'
-    def __init__(self, label):
-       JumpInstruction.__init__(self, chr(10), label)
-
-class FailureJump(JumpInstruction):
-    name = 'failure_jump'
-    def __init__(self, label):
-       JumpInstruction.__init__(self, chr(11), label)
-
-class UpdateFailureJump(JumpInstruction):
-    name = 'update_failure_jump'
-    def __init__(self, label):
-       JumpInstruction.__init__(self, chr(12), label)
-
-class DummyFailureJump(JumpInstruction):
-    name = 'dummy_failure_jump'
-    def __init__(self, label):
-       JumpInstruction.__init__(self, chr(13), label)
-       
-class BegBuf(Instruction):
-    name = 'begbuf'
-    def __init__(self):
-       Instruction.__init__(self, chr(14))
-
-class EndBuf(Instruction):
-    name = 'endbuf'
-    def __init__(self):
-       Instruction.__init__(self, chr(15))
-
-class WordBeg(Instruction):
-    name = 'wordbeg'
-    def __init__(self):
-       Instruction.__init__(self, chr(16))
-
-class WordEnd(Instruction):
-    name = 'wordend'
-    def __init__(self):
-       Instruction.__init__(self, chr(17))
-
-class WordBound(Instruction):
-    name = 'wordbound'
-    def __init__(self):
-       Instruction.__init__(self, chr(18))
-
-class NotWordBound(Instruction):
-    name = 'notwordbound'
-    def __init__(self):
-       Instruction.__init__(self, chr(19))
-
-class SyntaxSpec(Instruction):
-    name = 'syntaxspec'
-    def __init__(self, syntax):
-       self.syntax = syntax
-       Instruction.__init__(self, chr(20), 2)
-    def assemble(self, postition, labels):
-       return self.opcode + chr(self.syntax)
-
-class NotSyntaxSpec(Instruction):
-    name = 'notsyntaxspec'
-    def __init__(self, syntax):
-       self.syntax = syntax
-       Instruction.__init__(self, chr(21), 2)
-    def assemble(self, postition, labels):
-       return self.opcode + chr(self.syntax)
-
-class Label(Instruction):
-    name = 'label'
-    def __init__(self, label):
-       self.label = label
-       Instruction.__init__(self, '', 0)
-    def __repr__(self):
-       return '%-15s %i' % (self.name, self.label)
-
-class OpenParen(Instruction):
-    name = '('
-    def __init__(self, register):
-       self.register = register
-       Instruction.__init__(self, '', 0)
-    def assemble(self, position, labels):
-       raise error, 'unmatched open parenthesis'
-
-class Alternation(Instruction):
-    name = '|'
-    def __init__(self):
-       Instruction.__init__(self, '', 0)
-    def assemble(self, position, labels):
-       raise error, 'an alternation was not taken care of'
-
-#
-#
-#
-
-def assemble(instructions):
-    labels = {}
-    position = 0
-    pass1 = []
-    for instruction in instructions:
-       if instruction.name == 'label':
-           labels[instruction.label] = position
-       else:
-           pass1.append((position, instruction))
-           position = position + instruction.size
-    pass2 = ''
-    for position, instruction in pass1:
-       pass2 = pass2 + instruction.assemble(position, labels)
-    return pass2
-
-#
-#
-#
-
-def escape(pattern):
-    result = []
-    for char in pattern:
-       if not reop.syntax_table[char] & reop.word:
-           result.append('\\')
-       result.append(char)
-    return string.join(result, '')
-
-#
-#
-#
-
-def registers_used(instructions):
-    result = []
-    for instruction in instructions:
-       if (instruction.name in ['set_memory', 'end_memory']) and \
-          (instruction.register not in result):
-           result.append(instruction.register)
-    return result
-
-#
-#
-#
-
-class Fastmap:
-    def __init__(self):
-       self.map = ['\000']*256
-       self.can_be_null = 0
-    def add(self, char):
-       self.map[ord(char)] = '\001'
-    def fastmap(self):
-       return string.join(self.map, '')
-    def __getitem__(self, char):
-       return ord(self.map[ord(char)])
-    def __repr__(self):
-       self.map.sort()
-       return 'Fastmap(' + `self.can_be_null` + ', ' + `self.map` + ')'
-
-#
-#
-#
-
-def find_label(code, label):
-    line = 0
-    for instruction in code:
-       if (instruction.name == 'label') and (instruction.label == label):
-           return line + 1
-       line = line + 1
-       
-def build_fastmap_aux(code, pos, visited, fastmap):
-    if visited[pos]:
-       return
-    while 1:
-       instruction = code[pos]
-       visited[pos] = 1
-       pos = pos + 1
-       if instruction.name == 'end':
-           fastmap.can_be_null = 1
-           return
-       elif instruction.name == 'syntaxspec':
-           for char in map(chr, range(256)):
-               if reop.syntax_table[char] & instruction.syntax:
-                   fastmap.add(char)
-           return
-       elif instruction.name == 'notsyntaxspec':
-           for char in map(chr, range(256)):
-               if not reop.syntax_table[char] & instruction.syntax:
-                   fastmap.add(char)
-           return
-       elif instruction.name == 'eol':
-           fastmap.add('\n')
-           if fastmap.can_be_null == 0:
-               fastmap.can_be_null = 2
-           return
-       elif instruction.name == 'set':
-           for char in instruction.set:
-               fastmap.add(char)
-           return
-       elif instruction.name == 'exact':
-           fastmap.add(instruction.char)
-       elif instruction.name == 'anychar':
-           for char in map(chr, range(256)):
-               if char != '\n':
-                   fastmap.add(char)
-           return
-       elif instruction.name == 'match_memory':
-           for char in map(chr, range(256)):
-               fastmap.add(char)
-           fastmap.can_be_null = 1
-           return
-       elif instruction.name in ['jump', 'dummy_failure_jump', \
-                                 'update_failure_jump', 'star_jump']:
-           pos = find_label(code, instruction.label)
-           if visited[pos]:
-               return
-           visited[pos] = 1
-       elif instruction.name  == 'failure_jump':
-           build_fastmap_aux(code,
-                             find_label(code, instruction.label),
-                             visited,
-                             fastmap)
-       
-def build_fastmap(code, pos=0):
-    visited = [0] * len(code)
-    fastmap = Fastmap()
-    build_fastmap_aux(code, pos, visited, fastmap)
-    return fastmap
-
-#
-#
-#
-
-#[NORMAL, CHARCLASS, REPLACEMENT] = range(3)
-#[CHAR, MEMORY_REFERENCE, SYNTAX, NOT_SYNTAX, SET, WORD_BOUNDARY,
-# NOT_WORD_BOUNDARY, BEGINNING_OF_BUFFER, END_OF_BUFFER] = range(9)
-
-def expand_escape(pattern, index, context=NORMAL):
-    if index >= len(pattern):
-       raise error, 'escape ends too soon'
-
-    elif pattern[index] == 't':
-       return CHAR, chr(9), index + 1
-    
-    elif pattern[index] == 'n':
-       return CHAR, chr(10), index + 1
-    
-    elif pattern[index] == 'v':
-       return CHAR, chr(11), index + 1
-    
-    elif pattern[index] == 'r':
-       return CHAR, chr(13), index + 1
-    
-    elif pattern[index] == 'f':
-       return CHAR, chr(12), index + 1
-    
-    elif pattern[index] == 'a':
-       return CHAR, chr(7), index + 1
-    
-    elif pattern[index] == 'x':
-       # CAUTION: this is the Python rule, not the Perl rule!
-       end = index + 1  # Skip over the 'x' character
-       while (end < len(pattern)) and (pattern[end] in string.hexdigits):
-           end = end + 1
-       if end == index:
-           raise error, "\\x must be followed by hex digit(s)"
-       # let Python evaluate it, so we don't incorrectly 2nd-guess
-       # what it's doing (and Python in turn passes it on to sscanf,
-       # so that *it* doesn't incorrectly 2nd-guess what C does!)
-       char = eval ('"' + pattern[index-1:end] + '"')
-       assert len(char) == 1
-       return CHAR, char, end
-
-    elif pattern[index] == 'b':
-       if context != NORMAL:
-           return CHAR, chr(8), index + 1
-       else:
-           return WORD_BOUNDARY, '', index + 1
-           
-    elif pattern[index] == 'B':
-       if context != NORMAL:
-           return CHAR, 'B', index + 1
-       else:
-           return NOT_WORD_BOUNDARY, '', index + 1
-           
-    elif pattern[index] == 'A':
-       if context != NORMAL:
-           return CHAR, 'A', index + 1
-       else:
-           return BEGINNING_OF_BUFFER, '', index + 1
-           
-    elif pattern[index] == 'Z':
-       if context != NORMAL:
-           return CHAR, 'Z', index + 1
-       else:
-           return END_OF_BUFFER, '', index + 1
-           
-    elif pattern[index] in 'GluLUQE':
-       raise error, ('\\' + pattern[index] + ' is not allowed')
-    
-    elif pattern[index] == 'w':
-       if context == NORMAL:
-           return SYNTAX, reop.word, index + 1
-       elif context == CHARCLASS:
-           set = []
-           for char in reop.syntax_table.keys():
-               if reop.syntax_table[char] & reop.word:
-                   set.append(char)
-           return SET, set, index + 1
-       else:
-           return CHAR, 'w', index + 1
-       
-    elif pattern[index] == 'W':
-       if context == NORMAL:
-           return NOT_SYNTAX, reop.word, index + 1
-       elif context == CHARCLASS:
-           set = []
-           for char in reop.syntax_table.keys():
-               if not reop.syntax_table[char] & reop.word:
-                   set.append(char)
-           return SET, set, index + 1
-       else:
-           return CHAR, 'W', index + 1
-       
-    elif pattern[index] == 's':
-       if context == NORMAL:
-           return SYNTAX, reop.whitespace, index + 1
-       elif context == CHARCLASS:
-           set = []
-           for char in reop.syntax_table.keys():
-               if reop.syntax_table[char] & reop.whitespace:
-                   set.append(char)
-           return SET, set, index + 1
-       else:
-           return CHAR, 's', index + 1
-       
-    elif pattern[index] == 'S':
-       if context == NORMAL:
-           return NOT_SYNTAX, reop.whitespace, index + 1
-       elif context == CHARCLASS:
-           set = []
-           for char in reop.syntax_table.keys():
-               if not reop.syntax_table[char] & reop.whitespace:
-                   set.append(char)
-           return SET, set, index + 1
-       else:
-           return CHAR, 'S', index + 1
-       
-    elif pattern[index] == 'd':
-       if context == NORMAL:
-           return SYNTAX, reop.digit, index + 1
-       elif context == CHARCLASS:
-           set = []
-           for char in reop.syntax_table.keys():
-               if reop.syntax_table[char] & reop.digit:
-                   set.append(char)
-           return SET, set, index + 1
-       else:
-           return CHAR, 'd', index + 1
-       
-    elif pattern[index] == 'D':
-       if context == NORMAL:
-           return NOT_SYNTAX, reop.digit, index + 1
-       elif context == CHARCLASS:
-           set = []
-           for char in reop.syntax_table.keys():
-               if not reop.syntax_table[char] & reop.digit:
-                   set.append(char)
-           return SET, set, index + 1
-       else:
-           return CHAR, 'D', index + 1
-
-    elif pattern[index] in '0123456789':
-
-       if pattern[index] == '0':
-           if (index + 1 < len(pattern)) and \
-              (pattern[index + 1] in string.octdigits):
-               if (index + 2 < len(pattern)) and \
-                  (pattern[index + 2] in string.octdigits):
-                   value = string.atoi(pattern[index:index + 3], 8)
-                   index = index + 3
-
-               else:
-                   value = string.atoi(pattern[index:index + 2], 8)
-                   index = index + 2
-
-           else:
-               value = 0
-               index = index + 1
-
-           if value > 255:
-               raise error, 'octal value out of range'
-
-           return CHAR, chr(value), index
-       
-       else:
-           if (index + 1 < len(pattern)) and \
-              (pattern[index + 1] in string.digits):
-               if (index + 2 < len(pattern)) and \
-                  (pattern[index + 2] in string.octdigits) and \
-                  (pattern[index + 1] in string.octdigits) and \
-                  (pattern[index] in string.octdigits):
-                   value = string.atoi(pattern[index:index + 3], 8)
-                   if value > 255:
-                       raise error, 'octal value out of range'
-
-                   return CHAR, chr(value), index + 3
-
-               else:
-                   value = string.atoi(pattern[index:index + 2])
-                   if (value < 1) or (value > 99):
-                       raise error, 'memory reference out of range'
-
-                   if context == CHARCLASS:
-                       raise error, ('cannot reference a register from '
-                                     'inside a character class')
-                   return MEMORY_REFERENCE, value, index + 2
-
-           else:
-               if context == CHARCLASS:
-                   raise error, ('cannot reference a register from '
-                                 'inside a character class')
-
-               value = string.atoi(pattern[index])
-               return MEMORY_REFERENCE, value, index + 1
-           
-    elif pattern[index] == 'g':
-       if context != REPLACEMENT:
-           return CHAR, 'g', index + 1
-
-       index = index + 1
-       if index >= len(pattern):
-           raise error, 'unfinished symbolic reference'
-       if pattern[index] != '<':
-           raise error, 'missing < in symbolic reference'
-
-       index = index + 1
-       end = string.find(pattern, '>', index)
-       if end == -1:
-           raise error, 'unfinished symbolic reference'
-       value = pattern[index:end]
-       if not valid_identifier(value):
-           raise error, 'illegal symbolic reference'
-       return MEMORY_REFERENCE, value, end + 1
-    
-    else:
-       return CHAR, pattern[index], index + 1
-
-def compile(pattern, flags=0):
-    stack = []
-    label = 0
-    register = 1
-    groupindex = {}
-    lastop = ''
-
-    # look for embedded pattern modifiers at the beginning of the pattern
-
-    index = 0
-
-    if len(pattern) >= 3 and \
-       (pattern[:2] == '(?') and \
-       (pattern[2] in 'iImMsSxX'):
-       index = 2
-       while (index < len(pattern)) and (pattern[index] != ')'):
-           if pattern[index] in 'iI':
-               flags = flags | IGNORECASE
-           elif pattern[index] in 'mM':
-               flags = flags | MULTILINE
-           elif pattern[index] in 'sS':
-               flags = flags | DOTALL
-           elif pattern[index] in 'xX':
-               flags = flags | VERBOSE
-           else:
-               raise error, 'unknown modifier'
-           index = index + 1
-       index = index + 1
-
-    # compile the rest of the pattern
-    
-    while (index < len(pattern)):
-       char = pattern[index]
-       index = index + 1
-       if char == '\\':
-           escape_type, value, index = expand_escape(pattern, index)
-
-           if escape_type == CHAR:
-               stack.append([Exact(value, flags)])
-               lastop = '\\' + value
-               
-           elif escape_type == MEMORY_REFERENCE:
-               if value >= register:
-                   raise error, ('cannot reference a register '
-                                 'not yet used')
-               stack.append([MatchMemory(value)])
-               lastop = '\\1'
-               
-           elif escape_type == BEGINNING_OF_BUFFER:
-               stack.append([BegBuf()])
-               lastop = '\\A'
-               
-           elif escape_type == END_OF_BUFFER:
-               stack.append([EndBuf()])
-               lastop = '\\Z'
-               
-           elif escape_type == WORD_BOUNDARY:
-               stack.append([WordBound()])
-               lastop = '\\b'
-               
-           elif escape_type == NOT_WORD_BOUNDARY:
-               stack.append([NotWordBound()])
-               lastop = '\\B'
-               
-           elif escape_type == SYNTAX:
-               stack.append([SyntaxSpec(value)])
-               if value == reop.word:
-                   lastop = '\\w'
-               elif value == reop.whitespace:
-                   lastop = '\\s'
-               elif value == reop.digit:
-                   lastop = '\\d'
-               else:
-                   lastop = '\\?'
-                   
-           elif escape_type == NOT_SYNTAX:
-               stack.append([NotSyntaxSpec(value)])
-               if value == reop.word:
-                   lastop = '\\W'
-               elif value == reop.whitespace:
-                   lastop = '\\S'
-               elif value == reop.digit:
-                   lastop = '\\D'
-               else:
-                   lastop = '\\?'
-               
-           elif escape_type == SET:
-               raise error, 'cannot use set escape type here'
-           
-           else:
-               raise error, 'unknown escape type'
-
-       elif char == '|':
-           expr = []
-           
-           while (len(stack) != 0) and \
-                 (stack[-1][0].name != '(') and \
-                 (stack[-1][0].name != '|'):
-               expr = stack[-1] + expr
-               del stack[-1]
-           stack.append([FailureJump(label)] + \
-                        expr + \
-                        [Jump(-1),
-                         Label(label)])
-           stack.append([Alternation()])
-           label = label + 1
-           lastop = '|'
-           
-       elif char == '(':
-           if index >= len(pattern):
-               raise error, 'no matching close paren'
-
-           elif pattern[index] == '?':
-               # Perl style (?...) extensions
-               index = index + 1
-               if index >= len(pattern):
-                   raise error, 'extension ends prematurely'
-
-               elif pattern[index] == 'P':
-                   # Python extensions
-                   index = index + 1
-                   if index >= len(pattern):
-                       raise error, 'extension ends prematurely'
-
-                   elif pattern[index] == '<':
-                       # Handle Python symbolic group names (?P<...>...)
-                       index = index + 1
-                       end = string.find(pattern, '>', index)
-                       if end == -1:
-                           raise error, 'no end to symbolic group name'
-                       name = pattern[index:end]
-                       if not valid_identifier(name):
-                           raise error, ('symbolic group name must be a '
-                                         'valid identifier')
-                       index = end + 1
-                       groupindex[name] = register
-                       stack.append([OpenParen(register)])
-                       register = register + 1
-                       lastop = '('
-
-                   elif pattern[index] == '=':
-                       # backreference to symbolic group name
-                       if index >= len(pattern):
-                           raise error, '(?P= at the end of the pattern'
-                       start = index + 1
-                       end = string.find(pattern, ')', start)
-                       if end == -1:
-                           raise error, 'no ) to end symbolic group name'
-                       name = pattern[start:end]
-                       if name not in groupindex.keys():
-                           raise error, ('symbolic group name ' + name + \
-                                         ' has not been used yet')
-                       stack.append([MatchMemory(groupindex[name])])
-                       index = end + 1
-                       lastop = '(?P=)'
-                       
-                   else:
-                       raise error, ('unknown Python extension: ' + \
-                                     pattern[index])
-                   
-               elif pattern[index] == ':':
-                   # grouping, but no registers
-                   index = index + 1
-                   stack.append([OpenParen(-1)])
-                   lastop = '('
-                   
-               elif pattern[index] == '#':
-                   # comment
-                   index = index + 1
-                   end = string.find(pattern, ')', index)
-                   if end == -1:
-                       raise error, 'no end to comment'
-                   index = end + 1
-                   # do not change lastop
-                   
-               elif pattern[index] == '=':
-                   raise error, ('zero-width positive lookahead '
-                                 'assertion is unsupported')
-
-               elif pattern[index] == '!':
-                   raise error, ('zero-width negative lookahead '
-                                 'assertion is unsupported')
-
-               elif pattern[index] in 'iImMsSxX':
-                   raise error, ('embedded pattern modifiers are only '
-                                 'allowed at the beginning of the pattern')
-
-               else:
-                   raise error, 'unknown extension'
-
-           else:
-               stack.append([OpenParen(register)])
-               register = register + 1
-               lastop = '('
-
-       elif char == ')':
-           # make one expression out of everything on the stack up to
-           # the marker left by the last parenthesis
-           expr = []
-           while (len(stack) > 0) and (stack[-1][0].name != '('):
-               expr = stack[-1] + expr
-               del stack[-1]
-
-           if len(stack) == 0:
-               raise error, 'too many close parens'
-           
-           # remove markers left by alternation
-           expr = filter(lambda x: x.name != '|', expr)
-
-           # clean up jumps inserted by alternation
-           need_label = 0
-           for i in range(len(expr)):
-               if (expr[i].name == 'jump') and (expr[i].label == -1):
-                   expr[i] = Jump(label)
-                   need_label = 1
-           if need_label:
-               expr.append(Label(label))
-               label = label + 1
-
-           if stack[-1][0].register > 0:
-               expr = [StartMemory(stack[-1][0].register)] + \
-                      expr + \
-                      [EndMemory(stack[-1][0].register)]
-           del stack[-1]
-           stack.append(expr)
-           lastop = ')'
-
-       elif char == '{':
-           if len(stack) == 0:
-               raise error, 'no expression to repeat'
-           end = string.find(pattern, '}', index)
-           if end == -1:
-               raise error, ('no close curly bracket to match'
-                             ' open curly bracket')
-
-           fields = map(string.strip,
-                        string.split(pattern[index:end], ','))
-           index = end + 1
-
-           minimal = 0
-           if (index < len(pattern)) and (pattern[index] == '?'):
-               minimal = 1
-               index = index + 1
-
-           if len(fields) == 1:
-               # {n} or {n}? (there's really no difference)
-               try:
-                   count = string.atoi(fields[0])
-               except ValueError:
-                   raise error, ('count must be an integer '
-                                 'inside curly braces')
-               if count > 65535:
-                   raise error, 'repeat count out of range'
-               expr = []
-               while count > 0:
-                   expr = expr + stack[-1]
-                   count = count - 1
-               del stack[-1]
-               stack.append(expr)
-               if minimal:
-                   lastop = '{n}?'
-               else:
-                   lastop = '{n}'
-
-           elif len(fields) == 2:
-               # {n,} or {n,m}
-               if fields[1] == '':
-                   # {n,}
-                   try:
-                       min = string.atoi(fields[0])
-                   except ValueError:
-                       raise error, ('minimum must be an integer '
-                                     'inside curly braces')
-                   if min > 65535:
-                       raise error, 'minimum repeat count out of range'
-
-                   expr = []
-                   while min > 0:
-                       expr = expr + stack[-1]
-                       min = min - 1
-                   if minimal:
-                       expr = expr + \
-                              ([Jump(label + 1),
-                                Label(label)] + \
-                               stack[-1] + \
-                               [Label(label + 1),
-                                FailureJump(label)])
-                       lastop = '{n,}?'
-                   else:
-                       expr = expr + \
-                              ([Label(label),
-                                FailureJump(label + 1)] +
-                               stack[-1] +
-                               [StarJump(label),
-                                Label(label + 1)])
-                       lastop = '{n,}'
-
-                   del stack[-1]
-                   stack.append(expr)
-                   label = label + 2
-
-               else:
-                   # {n,m}
-                   try:
-                       min = string.atoi(fields[0])
-                   except ValueError:
-                       raise error, ('minimum must be an integer '
-                                     'inside curly braces')
-                   try:
-                       max = string.atoi(fields[1])
-                   except ValueError:
-                       raise error, ('maximum must be an integer '
-                                     'inside curly braces')
-                   if min > 65535:
-                       raise error, ('minumim repeat count out '
-                                     'of range')
-                   if max > 65535:
-                       raise error, ('maximum repeat count out '
-                                     'of range')
-                   if min > max:
-                       raise error, ('minimum repeat count must be '
-                                     'less than the maximum '
-                                     'repeat count')
-                   expr = []
-                   while min > 0:
-                       expr = expr + stack[-1]
-                       min = min - 1
-                       max = max - 1
-                   if minimal:
-                       while max > 0:
-                           expr = expr + \
-                                  [FailureJump(label),
-                                   Jump(label + 1),
-                                   Label(label)] + \
-                                  stack[-1] + \
-                                  [Label(label + 1)]
-                           max = max - 1
-                           label = label + 2
-                       del stack[-1]
-                       stack.append(expr)
-                       lastop = '{n,m}?'
-                   else:
-                       while max > 0:
-                           expr = expr + \
-                                  [FailureJump(label)] + \
-                                  stack[-1]
-                           max = max - 1
-                       del stack[-1]
-                       stack.append(expr + [Label(label)])
-                       label = label + 1
-                       lastop = '{n,m}'
-
-           else:
-               raise error, ('there need to be one or two fields '
-                             'in a {} expression')
-
-       elif char == '}':
-           raise error, 'unbalanced close curly brace'
-
-       elif char == '*':
-           # Kleene closure
-           if len(stack) == 0:
-               raise error, '* needs something to repeat'
-
-           if lastop in ['(', '|']:
-               raise error, '* needs something to repeat'
-
-           if lastop in repetition_operators:
-               raise error, 'nested repetition operators'
-           
-           if (index < len(pattern)) and (pattern[index] == '?'):
-               # non-greedy matching
-               expr = [Jump(label + 1),
-                       Label(label)] + \
-                      stack[-1] + \
-                      [Label(label + 1),
-                       FailureJump(label)]
-               index = index + 1
-               lastop = '*?'
-           else:
-               # greedy matching
-               expr = [Label(label),
-                       FailureJump(label + 1)] + \
-                      stack[-1] + \
-                      [StarJump(label),
-                       Label(label + 1)]
-               lastop = '*'
-           del stack[-1]
-           stack.append(expr)
-           label = label + 2
-
-       elif char == '+':
-           # positive closure
-           if len(stack) == 0:
-               raise error, '+ needs something to repeat'
-           
-           if lastop in ['(', '|']:
-               raise error, '+ needs something to repeat'
-
-           if lastop in repetition_operators:
-               raise error, 'nested repetition operators'
-
-           if (index < len(pattern)) and (pattern[index] == '?'):
-               # non-greedy
-               expr = [Label(label)] + \
-                      stack[-1] + \
-                      [FailureJump(label)]
-               label = label + 1
-               index = index + 1
-               lastop = '+?'
-               
-           else:
-               # greedy
-               expr = [DummyFailureJump(label + 1),
-                       Label(label),
-                       FailureJump(label + 2),
-                       Label(label + 1)] + \
-                      stack[-1] + \
-                      [StarJump(label),
-                       Label(label + 2)]
-               label = label + 3
-               lastop = '+'
-               
-           del stack[-1]
-           stack.append(expr)
-
-       elif char == '?':
-           if len(stack) == 0:
-               raise error, 'need something to be optional'
-           
-           if len(stack) == 0:
-               raise error, '? needs something to repeat'
-           
-           if lastop in ['(', '|']:
-               raise error, '? needs something to repeat'
-
-           if lastop in repetition_operators:
-               raise error, 'nested repetition operators'
-
-           if (index < len(pattern)) and (pattern[index] == '?'):
-               # non-greedy matching
-               expr = [FailureJump(label),
-                       Jump(label + 1),
-                       Label(label)] + \
-                      stack[-1] + \
-                      [Label(label + 1)]
-               label = label + 2
-               index = index + 1
-               lastop = '??'
-               
-           else:
-               # greedy matching
-               expr = [FailureJump(label)] + \
-                      stack[-1] + \
-                      [Label(label)]
-               label = label + 1
-               lastop = '?'
-               
-           del stack[-1]
-           stack.append(expr)
-
-       elif char == '.':
-           if flags & DOTALL:
-               stack.append([Set(map(chr, range(256)), flags)])
-           else:
-               stack.append([AnyChar()])
-           lastop = '.'
-
-       elif char == '^':
-           if flags & MULTILINE:
-               stack.append([Bol()])
-           else:
-               stack.append([BegBuf()])
-           lastop = '^'
-
-       elif char == '$':
-           if flags & MULTILINE:
-               stack.append([Eol()])
-           else:
-               stack.append([EndBuf()])
-           lastop = '$'
-
-       elif char == '#':
-           if flags & VERBOSE:
-               # comment
-               index = index + 1
-               end = string.find(pattern, '\n', index)
-               if end == -1:
-                   index = len(pattern)
-               else:
-                   index = end + 1
-               # do not change lastop
-           else:
-               stack.append([Exact(char, flags)])
-               lastop = '#'
-
-       elif char in string.whitespace:
-           if not (flags & VERBOSE):
-               stack.append([Exact(char, flags)])
-               lastop = char
-
-       elif char == '[':
-           # compile character class
-           
-           if index >= len(pattern):
-               raise error, 'unclosed character class'
-           
-           negate = 0
-           last = ''
-           set = []
-
-           if pattern[index] == '^':
-               negate = 1
-               index = index + 1
-               if index >= len(pattern):
-                   raise error, 'unclosed character class'
-
-           if pattern[index] == ']':
-               set.append(']')
-               index = index + 1
-               if index >= len(pattern):
-                   raise error, 'unclosed character class'
-               
-           elif pattern[index] == '-':
-               set.append('-')
-               index = index + 1
-               if index >= len(pattern):
-                   raise error, 'unclosed character class'
-               
-           while (index < len(pattern)) and (pattern[index] != ']'):
-               next = pattern[index]
-               index = index + 1
-               if next == '-':
-                   if index >= len(pattern):
-                       raise error, 'incomplete range in character class'
-
-                   elif pattern[index] == ']':
-                       set.append('-')
-                       
-                   else:
-                       if last == '':
-                           raise error, ('improper use of range in '
-                                         'character class')
-
-                       start = last
-                       
-                       if pattern[index] == '\\':
-                           escape_type,
-                           value,
-                           index = expand_escape(pattern,
-                                                 index + 1,
-                                                 CHARCLASS)
-
-                           if escape_type == CHAR:
-                               end = value
-                               
-                           else:
-                               raise error, ('illegal escape in character '
-                                             'class range')
-                       else:
-                           end = pattern[index]
-                           index = index + 1
-
-                       if start > end:
-                           raise error, ('range arguments out of order '
-                                         'in character class')
-                       
-                       for char in map(chr, range(ord(start), ord(end) + 1)):
-                           if char not in set:
-                               set.append(char)
-                           
-                       last = ''
-
-               elif next == '\\':
-                   # expand syntax meta-characters and add to set
-                   if index >= len(pattern):
-                       raise error, 'incomplete set'
-
-                   escape_type, value, index = expand_escape(pattern,
-                                                             index,
-                                                             CHARCLASS)
-
-                   if escape_type == CHAR:
-                       set.append(value)
-                       last = value
-
-                   elif escape_type == SET:
-                       for char in value:
-                           if char not in set:
-                               set.append(char)
-                       last = ''
-
-                   else:
-                       raise error, 'illegal escape type in character class'
-
-               else:
-                   if next not in set:
-                       set.append(next)
-                   last = next
-                   
-           if (index >= len(pattern)) or ( pattern[index] != ']'):
-               raise error, 'incomplete set'
-
-           index = index + 1
-
-           if negate:
-               # If case is being ignored, then both upper- and lowercase
-               # versions of the letters must be excluded.
-               if flags & IGNORECASE: set=set+map(string.upper, set)
-               notset = []
-               for char in map(chr, range(256)):
-                   if char not in set:
-                       notset.append(char)
-               if len(notset) == 0:
-                   raise error, 'empty negated set'
-               stack.append([Set(notset, flags)])
-           else:
-               if len(set) == 0:
-                   raise error, 'empty set'
-               stack.append([Set(set, flags)])
-
-           lastop = '[]'
-
-       else:
-           stack.append([Exact(char, flags)])
-           lastop = char
-
-    code = []
-    while len(stack) > 0:
-       if stack[-1][0].name == '(':
-           raise error, 'too many open parens'
-       code = stack[-1] + code
-       del stack[-1]
-    if len(code) == 0:
-       raise error, 'no code generated'
-    code = filter(lambda x: x.name != '|', code)
-    need_label = 0
-    for i in range(len(code)):
-       if (code[i].name == 'jump') and (code[i].label == -1):
-           code[i] = Jump(label)
-           need_label = 1
-    if need_label:
-       code.append(Label(label))
-       label = label + 1
-    code.append(End())
-#    print code
-    return RegexObject(pattern, flags, code, register, groupindex)
-
-# Replace expand_escape and _expand functions with their C equivalents.
-# If you suspect bugs in the C versions, comment out the next two lines
-expand_escape = reop.expand_escape
-_expand  = reop._expand