[pypy-svn] r44378 - in pypy/dist/pypy/rlib/parsing: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Tue Jun 19 17:24:32 CEST 2007


Author: cfbolz
Date: Tue Jun 19 17:24:32 2007
New Revision: 44378

Added:
   pypy/dist/pypy/rlib/parsing/makepackrat.py   (contents, props changed)
   pypy/dist/pypy/rlib/parsing/pypackrat.py   (contents, props changed)
   pypy/dist/pypy/rlib/parsing/test/test_pypackrat.py   (contents, props changed)
Log:
Very experimental rewrite of the packrat parsing engine. The new version is
meant to be much more featureful eventually, right now it already supports over
the original packrat parser:

 - left recursion
 - a limited form of sematic actions
 - scannerless parsing


Added: pypy/dist/pypy/rlib/parsing/makepackrat.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rlib/parsing/makepackrat.py	Tue Jun 19 17:24:32 2007
@@ -0,0 +1,610 @@
+import py
+import sys
+from pypy.rlib.parsing.tree import Nonterminal, Symbol, RPythonVisitor
+from pypy.rlib.parsing.regexparse import parse_regex
+
+class BacktrackException(Exception):
+    def __init__(self, error=None):
+        self.error = error
+        Exception.__init__(self, error)
+
+
+class TreeOptimizer(RPythonVisitor):
+    def visit_or(self, t):
+        if len(t.children) == 1:
+            return self.dispatch(t.children[0])
+        return self.general_nonterminal_visit(t)
+
+    visit_commands = visit_or
+    visit_toplevel_or = visit_or
+
+    def visit_negation(self, t):
+        child = self.dispatch(t.children[0])
+        if child.symbol == "negation":
+            child.symbol = "lookahead"
+            return child
+        t.children[0] = child
+        return t
+
+    def general_nonterminal_visit(self, t):
+        for i in range(len(t.children)):
+            t.children[i] = self.dispatch(t.children[i])
+        return t
+
+    def general_visit(self, t):
+        return t
+
+
+syntax = r"""
+NAME:
+    `[a-zA-Z_][a-zA-Z0-9_]*`;
+
+SPACE:
+    ' ';
+
+COMMENT:
+    `( *#[^\n]*\n)+`;
+
+IGNORE:
+    `(#[^\n]*\n)|\n|\t| `;
+
+newline:
+    COMMENT
+  | `( *\n *)*`;
+    
+
+REGEX:
+     r = `\`[^\\\`]*(\\.[^\\\`]*)*\``
+    return {Symbol('REGEX', r, None)};
+
+QUOTE:
+    r = `'[^\']*'`
+    return {Symbol('QUOTE', r, None)};
+
+PYTHONCODE:
+    r = `\{[^\n\}]*\}`
+    return {Symbol('PYTHONCODE', r, None)};
+
+EOF:
+    !__any__;
+
+file:
+    IGNORE*
+    list
+    [EOF];
+
+list:
+    content = production+
+    return {Nonterminal('list', content)};
+
+production:
+    name = NAME
+    SPACE*
+    ':'
+    IGNORE*
+    what = or_
+    IGNORE*
+    ';'
+    IGNORE*
+    return {Nonterminal('production', [name, what])};
+
+or_:
+    l = (commands ['|' IGNORE*])+
+    last = commands
+    return {Nonterminal('or', l + [last])}
+  | commands;
+
+commands:
+    cmd = command
+    newline
+    cmds = (command [newline])+
+    return {Nonterminal('commands', [cmd] + cmds)}
+  | command;
+
+command:
+    simplecommand;
+
+simplecommand:
+    return_
+  | named_command
+  | repetition
+  | negation
+  | enclosed;
+
+return_:
+    'return'
+    SPACE*
+    code = PYTHONCODE
+    IGNORE*
+    return {Nonterminal('return', [code])};
+
+commandchain:
+    result = simplecommand+
+    return {Nonterminal('commands', result)};
+
+named_command:
+    name = NAME
+    SPACE*
+    '='
+    SPACE*
+    cmd = command
+    return {Nonterminal('named_command', [name, cmd])};
+
+repetition:
+    what = enclosed
+    SPACE* '?' IGNORE*
+    return {Nonterminal('maybe', [what])}
+  | what = enclosed
+    SPACE*
+    repetition = ('*' | '+')
+    IGNORE*
+    return {Nonterminal('repetition', [repetition, what])};
+
+negation:
+    '!'
+    SPACE*
+    what = negation
+    IGNORE*
+    return {Nonterminal('negation', [what])}
+  | enclosed;
+
+enclosed:
+    '<'
+    IGNORE*
+    what = primary
+    IGNORE*
+    '>'
+    IGNORE*
+    return {Nonterminal('exclusive', [what])}
+  | '['
+    IGNORE*
+    what = or_
+    IGNORE*
+    ']'
+    IGNORE*
+    return {Nonterminal('ignore', [what])}
+  | ['(' IGNORE*] or_ [')' IGNORE*]
+  |  primary;
+
+primary:
+    call | REGEX [IGNORE*] | QUOTE [IGNORE*];
+
+call:
+    x = NAME
+    IGNORE*
+    return {Nonterminal("call", [x])};
+"""
+
+class ErrorInformation(object):
+    def __init__(self, pos, expected=None):
+        if expected is None:
+            expected = []
+        self.expected = expected
+        self.pos = pos
+
+    def __str__(self):
+        return "ErrorInformation(%s, %s)" % (self.pos, self.expected)
+
+
+class Status(object):
+    # status codes:
+    NORMAL = 0
+    ERROR = 1
+    INPROGRESS = 2
+    LEFTRECURSION = 3
+    SOMESOLUTIONS = 4
+    def __repr__(self):
+        return "Status(%s, %s, %s, %s)" % (self.pos, self.result, self.error,
+                                           self.status)
+
+
+class ParserBuilder(RPythonVisitor):
+    def __init__(self):
+        self.code = []
+        self.blocks = []
+        self.initcode = []
+        self.namecount = 0
+        self.names = {}
+        self.matchers = {}
+
+    def get_code(self):
+        assert not self.blocks
+        return "\n".join(self.code)
+
+    def make_parser(self):
+        m = {'_Status': Status,
+             'Nonterminal': Nonterminal,
+             'Symbol': Symbol,}
+        exec py.code.Source(self.get_code()).compile() in m
+        return m['Parser']
+
+    def emit(self, line):
+        for line in line.split("\n"):
+            self.code.append(" " * (4 * len(self.blocks)) + line)
+
+    def emit_initcode(self, line):
+        for line in line.split("\n"):
+            self.initcode.append(line)
+
+    def start_block(self, blockstarter):
+        assert blockstarter.endswith(":")
+        self.emit(blockstarter)
+        self.blocks.append(blockstarter)
+        def BlockEnder():
+            yield None
+            self.end_block(blockstarter)
+        return BlockEnder()
+
+    def end_block(self, starterpart=""):
+        block = self.blocks.pop()
+        assert starterpart in block, "ended wrong block %s with %s" % (
+            block, starterpart)
+
+    def memoize_header(self, name):
+        statusclassname = "self._Status_%s" % (name, )
+        dictname = "_dict_%s" % (name, )
+        self.emit_initcode("self.%s = {}" % (dictname, ))
+        self.emit("_status = self.%s.get(self._pos, None)" % (dictname, ))
+        for _ in self.start_block("if _status is None:"):
+            self.emit("_status = self.%s[self._pos] = %s()" % (
+                dictname, statusclassname))
+        for _ in self.start_block("elif _status.status == _status.NORMAL:"):
+            self.emit("self._pos = _status.pos")
+            self.emit("return _status")
+        for _ in self.start_block("elif _status.status == _status.ERROR:"):
+            self.emit("raise self._BacktrackException(_status.error)")
+        for _ in self.start_block(
+            "elif (_status.status == _status.INPROGRESS or\n"
+            "      _status.status == _status.LEFTRECURSION):"):
+            self.emit("_status.status = _status.LEFTRECURSION")
+            for _ in self.start_block("if _status.result is not None:"):
+                self.emit("self._pos = _status.pos")
+                self.emit("return _status")
+            for _ in self.start_block("else:"):
+                self.emit("raise self._BacktrackException(None)")
+        for _ in self.start_block("elif _status.status == _status.SOMESOLUTIONS:"):
+            self.emit("_status.status = _status.INPROGRESS")
+        self.emit("_startingpos = self._pos")
+        self.start_block("try:")
+        self.emit("_result = None")
+        self.emit("_error = None")
+
+    def memoize_footer(self, name):
+        statusclassname = "self._Status_%s" % (name, )
+        dictname = "_dict_%s" % (name, )
+        for _ in self.start_block("if _status.status == _status.LEFTRECURSION:"):
+            for _ in self.start_block("if _status.result is not None:"):
+                for _ in self.start_block("if _status.pos >= self._pos:"):
+                    self.emit("_status.status = _status.NORMAL")
+                    self.emit("self._pos = _status.pos")
+                    self.emit("return _status")
+            self.emit("_status.pos = self._pos")
+            self.emit("_status.status = _status.SOMESOLUTIONS")
+            self.emit("_status.result = %s" % (self.resultname, ))
+            self.emit("_status.error = _error")
+            self.emit("self._pos = _startingpos")
+            self.emit("return self._%s()" % (name, ))
+        self.emit("_status.status = _status.NORMAL")
+        self.emit("_status.pos = self._pos")
+        self.emit("_status.result = %s" % (self.resultname, ))
+        self.emit("_status.error = _error")
+        self.emit("return _status")
+        self.end_block("try")
+        for _ in self.start_block("except self._BacktrackException, _exc:"):
+            self.emit("_status.pos = -1")
+            self.emit("_status.result = None")
+            self.emit("_error = self._combine_errors(_error, _exc.error)")
+            self.emit("_status.error = _error")
+            self.emit("_status.status = _status.ERROR")
+            self.emit("raise self._BacktrackException(_error)")
+
+    def choice_point(self, name=None):
+        var = "_choice%s" % (self.namecount, )
+        self.namecount += 1
+        self.emit("%s = self._pos" % (var, ))
+        return var
+
+    def revert(self, var):
+        self.emit("self._pos = %s" % (var, ))
+
+    def make_status_class(self, name):
+        classname = "_Status_%s" % (name, )
+        for _ in self.start_block("class %s(_Status):" % (classname, )):
+            for _ in self.start_block("def __init__(self):"):
+                self.emit("self.pos = 0")
+                self.emit("self.error = None")
+                self.emit("self.status = self.INPROGRESS")
+                self.emit("self.result = None")
+        return classname
+
+    def visit_list(self, t):
+        self.start_block("class Parser(object):")
+        for elt in t.children:
+            self.dispatch(elt)
+        for _ in self.start_block("def __init__(self, inputstream):"):
+            for line in self.initcode:
+                self.emit(line)
+            self.emit("self._pos = 0")
+            self.emit("self._inputstream = inputstream")
+        if self.matchers:
+            self.emit_regex_code()
+        self.end_block("class")
+
+    def emit_regex_code(self):
+        for regex, matcher in self.matchers.iteritems():
+            for _ in  self.start_block(
+                    "def _regex%s(self):" % (abs(hash(regex)), )):
+                c = self.choice_point()
+                self.emit("_runner = self._Runner(self._inputstream, self._pos)")
+                self.emit("_i = _runner.recognize_%s(self._pos)" % (
+                    abs(hash(regex)), ))
+                self.start_block("if _runner.last_matched_state == -1:")
+                self.revert(c)
+                self.emit("raise self._BacktrackException")
+                self.end_block("if")
+                self.emit("_upto = _runner.last_matched_index + 1")
+                self.emit("_result = self._inputstream[self._pos: _upto]")
+                self.emit("self._pos = _upto")
+                self.emit("return _result")
+
+        for _ in self.start_block("class _Runner(object):"):
+            for _ in self.start_block("def __init__(self, text, pos):"):
+                self.emit("self.text = text")
+                self.emit("self.pos = pos")
+                self.emit("self.last_matched_state = -1")
+                self.emit("self.last_matched_index = -1")
+                self.emit("self.state = -1")
+            for regex, matcher in self.matchers.iteritems():
+                matcher = str(matcher).replace(
+                    "def recognize(runner, i)",
+                    "def recognize_%s(runner, i)" % (abs(hash(regex)), ))
+                self.emit(str(matcher))
+
+    def visit_production(self, t):
+        name = t.children[0]
+        if name in self.names:
+            raise Exception("name %s appears twice" % (name, ))
+        self.names[name] = True
+        self.make_status_class(name)
+        for _ in self.start_block("def %s(self):" % (name, )):
+            self.emit("return self._%s().result" % (name, ))
+        self.start_block("def _%s(self):" % (name, ))
+        self.memoize_header(name)
+        #self.emit("print '%s', self._pos" % (name, ))
+        self.resultname = "_result"
+        self.dispatch(t.children[1])
+        self.memoize_footer(name)
+        self.end_block("def")
+
+    def visit_or(self, t):
+        possibilities = t.children
+        if len(possibilities) > 1:
+            self.start_block("while 1:")
+            self.emit("_error = None")
+        for i, p in enumerate(possibilities):
+            c = self.choice_point()
+            for _ in self.start_block("try:"):
+                self.dispatch(p)
+                self.emit("break")
+            for _ in self.start_block("except self._BacktrackException, _exc:"):
+                self.emit("_error = self._combine_errors(_error, _exc.error)")
+                self.revert(c)
+                if i == len(possibilities) - 1:
+                    self.emit("raise self._BacktrackException(_error)")
+        self.dispatch(possibilities[-1])
+        if len(possibilities) > 1:
+            self.emit("break")
+            self.end_block("while")
+    visit_toplevel_or = visit_or
+
+    def visit_commands(self, t):
+        for elt in t.children:
+            self.dispatch(elt)
+
+    def visit_maybe(self, t):
+        c = self.choice_point()
+        for _ in self.start_block("try:"):
+            self.dispatch(t.children[0])
+        for _ in self.start_block("except self._BacktrackException:"):
+            self.revert(c)
+
+    def visit_repetition(self, t):
+        name = "_all%s" % (self.namecount, )
+        self.namecount += 1
+        self.emit("%s = []" % (name, ))
+        if t.children[0] == '+':
+            self.dispatch(t.children[1])
+            self.emit("%s.append(_result)"  % (name, ))
+        for _ in self.start_block("while 1:"):
+            c = self.choice_point()
+            for _ in self.start_block("try:"):
+                self.dispatch(t.children[1])
+                self.emit("%s.append(_result)" % (name, ))
+            for _ in self.start_block("except self._BacktrackException, _exc:"):
+                self.emit("_error = self._combine_errors(_error, _exc.error)")
+                self.revert(c)
+                self.emit("break")
+        self.emit("_result = %s" % (name, ))
+
+    def visit_exclusive(self, t):
+        self.resultname = "_enclosed"
+        self.dispatch(t.children[0])
+        self.emit("_enclosed = _result")
+
+    def visit_ignore(self, t):
+        resultname = "_before_discard%i" % (self.namecount, )
+        self.namecount += 1
+        self.emit("%s = _result" % (resultname, ))
+        self.dispatch(t.children[0])
+        self.emit("_result = %s" % (resultname, ))
+
+    def visit_negation(self, t):
+        c = self.choice_point()
+        resultname = "_stored_result%i" % (self.namecount, )
+        self.namecount += 1
+        child = t.children[0]
+        self.emit("%s = _result" % (resultname, ))
+        for _ in self.start_block("try:"):
+            self.dispatch(child)
+        for _ in self.start_block("except self._BacktrackException:"):
+            self.revert(c)
+            self.emit("_result = %s" % (resultname, ))
+        for _ in self.start_block("else:"):
+            # heuristic to get nice error messages sometimes
+            if isinstance(child, Symbol) and child.symbol == "QUOTE":
+
+                error = "self._ErrorInformation(%s, ['NOT %s'])" % (
+                        c, child.additional_info[1:-1], )
+            else:
+                error = "None"
+            self.emit("raise self._BacktrackException(%s)" % (error, ))
+
+    def visit_lookahead(self, t):
+        resultname = "_stored_result%i" % (self.namecount, )
+        self.emit("%s = _result" % (resultname, ))
+        c = self.choice_point()
+        self.dispatch(t.children[0])
+        self.revert(c)
+        self.emit("_result = %s" % (resultname, ))
+
+    def visit_named_command(self, t):
+        name = t.children[0]
+        self.dispatch(t.children[1])
+        self.emit("%s = _result" % (name, ))
+
+    def visit_return(self, t):
+        self.emit("_result = (%s)" % (t.children[0].additional_info[1:-1], ))
+
+    def visit_call(self, t):
+        if t.children[0].startswith("_"):
+            callname = t.children[0]
+            self.emit("_result = self.%s()" % (callname, ))
+        else:
+            callname = "_" + t.children[0]
+            self.emit("_call_status = self.%s()" % (callname, ))
+            self.emit("_result = _call_status.result")
+            self.emit(
+                "_error = self._combine_errors(_call_status.error, _error)")
+
+    def visit_REGEX(self, t):
+        r = t.additional_info[1:-1].replace('\\`', '`')
+        matcher = self.get_regex(r)
+        self.emit("_result = self._regex%s()" % (abs(hash(r)), ))
+        
+    def visit_QUOTE(self, t):
+        self.emit("_result = self.__chars__(%r)" % (
+                    str(t.additional_info[1:-1]), ))
+
+    def get_regex(self, r):
+        from pypy.rlib.parsing.regexparse import parse_regex
+        if r in self.matchers:
+            return self.matchers[r]
+        regex = parse_regex(r)
+        if regex is None:
+            raise ValueError(
+                "%s is not a valid regular expression" % regextext)
+        automaton = regex.make_automaton().make_deterministic()
+        automaton.optimize()
+        matcher = automaton.make_lexing_code()
+        self.matchers[r] = py.code.Source(matcher)
+        return matcher
+
+class MetaPackratParser(type):
+    def __new__(cls, name_, bases, dct):
+        if '__doc__' not in dct or dct['__doc__'] is None:
+            return type.__new__(cls, name_, bases, dct)
+        from pypackrat import PyPackratSyntaxParser
+        import sys, new
+        frame = sys._getframe(1)
+        p = PyPackratSyntaxParser(dct['__doc__'])
+        t = p.file()
+        t = t.visit(TreeOptimizer())
+        visitor = ParserBuilder()
+        t.visit(visitor)
+        pcls = visitor.make_parser()
+        forbidden = dict.fromkeys(("__weakref__ __doc__ "
+                                   "__dict__ __module__").split())
+        initthere = "__init__" in dct
+
+        for key, value in pcls.__dict__.iteritems():
+            if isinstance(value, type(lambda: None)):
+                value = new.function(value.func_code, frame.f_globals)
+            if key not in dct and key not in forbidden:
+                dct[key] = value
+        dct['init_parser'] = pcls.__dict__['__init__']
+        dct['_code'] = visitor.get_code()
+        return type.__new__(cls, name_, bases, dct)
+
+class PackratParser(object):
+    __metaclass__ = MetaPackratParser
+
+    _Status = Status
+    _ErrorInformation = ErrorInformation
+    _BacktrackException = BacktrackException
+
+    def __chars__(self, chars):
+        #print '__chars__(%s)' % (chars, ), self._pos
+        try:
+            for i in range(len(chars)):
+                if self._inputstream[self._pos + i] != chars[i]:
+                    raise self._BacktrackException(
+                        self._ErrorInformation(self._pos, [chars]))
+            self._pos += len(chars)
+            return chars
+        except IndexError:
+            raise self._BacktrackException(
+                self._ErrorInformation(self._pos, [chars]))
+
+    def  __any__(self):
+        try:
+            result = self._inputstream[self._pos]
+            self._pos += 1
+            return result
+        except IndexError:
+            raise self._BacktrackException(
+                self._ErrorInformation(self._pos, ['anything']))
+
+    def _combine_errors(self, error1, error2):
+        if error1 is None:
+            return error2
+        if (error2 is None or error1.pos > error2.pos or
+            len(error2.expected) == 0):
+            return error1
+        elif error2.pos > error1.pos or len(error1.expected) == 0:
+            return error2
+        expected = []
+        already_there = {}
+        for ep in [error1.expected, error2.expected]:
+            for reason in ep:
+                if reason not in already_there:
+                    already_there[reason] = True
+                    expected.append(reason)
+        return ErrorInformation(error1.pos, expected)
+
+
+def test_generate():
+    f = py.magic.autopath().dirpath().join("pypackrat.py")
+    from pypackrat import PyPackratSyntaxParser
+    p = PyPackratSyntaxParser(syntax)
+    t = p.file()
+    t = t.visit(TreeOptimizer())
+    visitor = ParserBuilder()
+    t.visit(visitor)
+    code = visitor.get_code()
+    content = """
+from pypy.rlib.parsing.tree import Nonterminal, Symbol
+from makepackrat import PackratParser, BacktrackException, Status as _Status
+%s
+class PyPackratSyntaxParser(PackratParser):
+    def __init__(self, stream):
+        self.init_parser(stream)
+forbidden = dict.fromkeys(("__weakref__ __doc__ "
+                           "__dict__ __module__").split())
+initthere = "__init__" in PyPackratSyntaxParser.__dict__
+for key, value in Parser.__dict__.iteritems():
+    if key not in PyPackratSyntaxParser.__dict__ and key not in forbidden:
+        setattr(PyPackratSyntaxParser, key, value)
+PyPackratSyntaxParser.init_parser = Parser.__init__.im_func
+""" % (code, )
+    print content
+    f.write(content)

Added: pypy/dist/pypy/rlib/parsing/pypackrat.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rlib/parsing/pypackrat.py	Tue Jun 19 17:24:32 2007
@@ -0,0 +1,2706 @@
+
+from pypy.rlib.parsing.tree import Nonterminal, Symbol
+from makepackrat import PackratParser, BacktrackException, Status as _Status
+class Parser(object):
+    class _Status_NAME(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def NAME(self):
+        return self._NAME().result
+    def _NAME(self):
+        _status = self._dict_NAME.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_NAME[self._pos] = self._Status_NAME()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _result = self._regex1074651696()
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._NAME()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_SPACE(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def SPACE(self):
+        return self._SPACE().result
+    def _SPACE(self):
+        _status = self._dict_SPACE.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_SPACE[self._pos] = self._Status_SPACE()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _result = self.__chars__(' ')
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._SPACE()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_COMMENT(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def COMMENT(self):
+        return self._COMMENT().result
+    def _COMMENT(self):
+        _status = self._dict_COMMENT.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_COMMENT[self._pos] = self._Status_COMMENT()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _result = self._regex528667127()
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._COMMENT()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_IGNORE(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def IGNORE(self):
+        return self._IGNORE().result
+    def _IGNORE(self):
+        _status = self._dict_IGNORE.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_IGNORE[self._pos] = self._Status_IGNORE()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _result = self._regex1979538501()
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._IGNORE()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_newline(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def newline(self):
+        return self._newline().result
+    def _newline(self):
+        _status = self._dict_newline.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_newline[self._pos] = self._Status_newline()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            while 1:
+                _error = None
+                _choice0 = self._pos
+                try:
+                    _call_status = self._COMMENT()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice0
+                _choice1 = self._pos
+                try:
+                    _result = self._regex299149370()
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice1
+                    raise self._BacktrackException(_error)
+                _result = self._regex299149370()
+                break
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._newline()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_REGEX(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def REGEX(self):
+        return self._REGEX().result
+    def _REGEX(self):
+        _status = self._dict_REGEX.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_REGEX[self._pos] = self._Status_REGEX()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _result = self._regex1006631623()
+            r = _result
+            _result = (Symbol('REGEX', r, None))
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._REGEX()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_QUOTE(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def QUOTE(self):
+        return self._QUOTE().result
+    def _QUOTE(self):
+        _status = self._dict_QUOTE.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_QUOTE[self._pos] = self._Status_QUOTE()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _result = self._regex1124192327()
+            r = _result
+            _result = (Symbol('QUOTE', r, None))
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._QUOTE()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_PYTHONCODE(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def PYTHONCODE(self):
+        return self._PYTHONCODE().result
+    def _PYTHONCODE(self):
+        _status = self._dict_PYTHONCODE.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_PYTHONCODE[self._pos] = self._Status_PYTHONCODE()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _result = self._regex291086639()
+            r = _result
+            _result = (Symbol('PYTHONCODE', r, None))
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._PYTHONCODE()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_EOF(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def EOF(self):
+        return self._EOF().result
+    def _EOF(self):
+        _status = self._dict_EOF.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_EOF[self._pos] = self._Status_EOF()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _choice2 = self._pos
+            _stored_result3 = _result
+            try:
+                _result = self.__any__()
+            except self._BacktrackException:
+                self._pos = _choice2
+                _result = _stored_result3
+            else:
+                raise self._BacktrackException(None)
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._EOF()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_file(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def file(self):
+        return self._file().result
+    def _file(self):
+        _status = self._dict_file.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_file[self._pos] = self._Status_file()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _all4 = []
+            while 1:
+                _choice5 = self._pos
+                try:
+                    _call_status = self._IGNORE()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _all4.append(_result)
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice5
+                    break
+            _result = _all4
+            _call_status = self._list()
+            _result = _call_status.result
+            _error = self._combine_errors(_call_status.error, _error)
+            _before_discard6 = _result
+            _call_status = self._EOF()
+            _result = _call_status.result
+            _error = self._combine_errors(_call_status.error, _error)
+            _result = _before_discard6
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._file()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_list(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def list(self):
+        return self._list().result
+    def _list(self):
+        _status = self._dict_list.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_list[self._pos] = self._Status_list()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _all7 = []
+            _call_status = self._production()
+            _result = _call_status.result
+            _error = self._combine_errors(_call_status.error, _error)
+            _all7.append(_result)
+            while 1:
+                _choice8 = self._pos
+                try:
+                    _call_status = self._production()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _all7.append(_result)
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice8
+                    break
+            _result = _all7
+            content = _result
+            _result = (Nonterminal('list', content))
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._list()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_production(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def production(self):
+        return self._production().result
+    def _production(self):
+        _status = self._dict_production.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_production[self._pos] = self._Status_production()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _call_status = self._NAME()
+            _result = _call_status.result
+            _error = self._combine_errors(_call_status.error, _error)
+            name = _result
+            _all9 = []
+            while 1:
+                _choice10 = self._pos
+                try:
+                    _call_status = self._SPACE()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _all9.append(_result)
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice10
+                    break
+            _result = _all9
+            _result = self.__chars__(':')
+            _all11 = []
+            while 1:
+                _choice12 = self._pos
+                try:
+                    _call_status = self._IGNORE()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _all11.append(_result)
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice12
+                    break
+            _result = _all11
+            _call_status = self._or_()
+            _result = _call_status.result
+            _error = self._combine_errors(_call_status.error, _error)
+            what = _result
+            _all13 = []
+            while 1:
+                _choice14 = self._pos
+                try:
+                    _call_status = self._IGNORE()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _all13.append(_result)
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice14
+                    break
+            _result = _all13
+            _result = self.__chars__(';')
+            _all15 = []
+            while 1:
+                _choice16 = self._pos
+                try:
+                    _call_status = self._IGNORE()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _all15.append(_result)
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice16
+                    break
+            _result = _all15
+            _result = (Nonterminal('production', [name, what]))
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._production()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_or_(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def or_(self):
+        return self._or_().result
+    def _or_(self):
+        _status = self._dict_or_.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_or_[self._pos] = self._Status_or_()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            while 1:
+                _error = None
+                _choice17 = self._pos
+                try:
+                    _all18 = []
+                    _call_status = self._commands()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _before_discard19 = _result
+                    _result = self.__chars__('|')
+                    _all20 = []
+                    while 1:
+                        _choice21 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all20.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice21
+                            break
+                    _result = _all20
+                    _result = _before_discard19
+                    _all18.append(_result)
+                    while 1:
+                        _choice22 = self._pos
+                        try:
+                            _call_status = self._commands()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _before_discard23 = _result
+                            _result = self.__chars__('|')
+                            _all24 = []
+                            while 1:
+                                _choice25 = self._pos
+                                try:
+                                    _call_status = self._IGNORE()
+                                    _result = _call_status.result
+                                    _error = self._combine_errors(_call_status.error, _error)
+                                    _all24.append(_result)
+                                except self._BacktrackException, _exc:
+                                    _error = self._combine_errors(_error, _exc.error)
+                                    self._pos = _choice25
+                                    break
+                            _result = _all24
+                            _result = _before_discard23
+                            _all18.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice22
+                            break
+                    _result = _all18
+                    l = _result
+                    _call_status = self._commands()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    last = _result
+                    _result = (Nonterminal('or', l + [last]))
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice17
+                _choice26 = self._pos
+                try:
+                    _call_status = self._commands()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice26
+                    raise self._BacktrackException(_error)
+                _call_status = self._commands()
+                _result = _call_status.result
+                _error = self._combine_errors(_call_status.error, _error)
+                break
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._or_()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_commands(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def commands(self):
+        return self._commands().result
+    def _commands(self):
+        _status = self._dict_commands.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_commands[self._pos] = self._Status_commands()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            while 1:
+                _error = None
+                _choice27 = self._pos
+                try:
+                    _call_status = self._command()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    cmd = _result
+                    _call_status = self._newline()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _all28 = []
+                    _call_status = self._command()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _before_discard29 = _result
+                    _call_status = self._newline()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _result = _before_discard29
+                    _all28.append(_result)
+                    while 1:
+                        _choice30 = self._pos
+                        try:
+                            _call_status = self._command()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _before_discard31 = _result
+                            _call_status = self._newline()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _result = _before_discard31
+                            _all28.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice30
+                            break
+                    _result = _all28
+                    cmds = _result
+                    _result = (Nonterminal('commands', [cmd] + cmds))
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice27
+                _choice32 = self._pos
+                try:
+                    _call_status = self._command()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice32
+                    raise self._BacktrackException(_error)
+                _call_status = self._command()
+                _result = _call_status.result
+                _error = self._combine_errors(_call_status.error, _error)
+                break
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._commands()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_command(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def command(self):
+        return self._command().result
+    def _command(self):
+        _status = self._dict_command.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_command[self._pos] = self._Status_command()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _call_status = self._simplecommand()
+            _result = _call_status.result
+            _error = self._combine_errors(_call_status.error, _error)
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._command()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_simplecommand(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def simplecommand(self):
+        return self._simplecommand().result
+    def _simplecommand(self):
+        _status = self._dict_simplecommand.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_simplecommand[self._pos] = self._Status_simplecommand()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            while 1:
+                _error = None
+                _choice33 = self._pos
+                try:
+                    _call_status = self._return_()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice33
+                _choice34 = self._pos
+                try:
+                    _call_status = self._named_command()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice34
+                _choice35 = self._pos
+                try:
+                    _call_status = self._repetition()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice35
+                _choice36 = self._pos
+                try:
+                    _call_status = self._negation()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice36
+                _choice37 = self._pos
+                try:
+                    _call_status = self._enclosed()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice37
+                    raise self._BacktrackException(_error)
+                _call_status = self._enclosed()
+                _result = _call_status.result
+                _error = self._combine_errors(_call_status.error, _error)
+                break
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._simplecommand()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_return_(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def return_(self):
+        return self._return_().result
+    def _return_(self):
+        _status = self._dict_return_.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_return_[self._pos] = self._Status_return_()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _result = self.__chars__('return')
+            _all38 = []
+            while 1:
+                _choice39 = self._pos
+                try:
+                    _call_status = self._SPACE()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _all38.append(_result)
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice39
+                    break
+            _result = _all38
+            _call_status = self._PYTHONCODE()
+            _result = _call_status.result
+            _error = self._combine_errors(_call_status.error, _error)
+            code = _result
+            _all40 = []
+            while 1:
+                _choice41 = self._pos
+                try:
+                    _call_status = self._IGNORE()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _all40.append(_result)
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice41
+                    break
+            _result = _all40
+            _result = (Nonterminal('return', [code]))
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._return_()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_commandchain(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def commandchain(self):
+        return self._commandchain().result
+    def _commandchain(self):
+        _status = self._dict_commandchain.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_commandchain[self._pos] = self._Status_commandchain()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _all42 = []
+            _call_status = self._simplecommand()
+            _result = _call_status.result
+            _error = self._combine_errors(_call_status.error, _error)
+            _all42.append(_result)
+            while 1:
+                _choice43 = self._pos
+                try:
+                    _call_status = self._simplecommand()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _all42.append(_result)
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice43
+                    break
+            _result = _all42
+            result = _result
+            _result = (Nonterminal('commands', result))
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._commandchain()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_named_command(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def named_command(self):
+        return self._named_command().result
+    def _named_command(self):
+        _status = self._dict_named_command.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_named_command[self._pos] = self._Status_named_command()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _call_status = self._NAME()
+            _result = _call_status.result
+            _error = self._combine_errors(_call_status.error, _error)
+            name = _result
+            _all44 = []
+            while 1:
+                _choice45 = self._pos
+                try:
+                    _call_status = self._SPACE()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _all44.append(_result)
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice45
+                    break
+            _result = _all44
+            _result = self.__chars__('=')
+            _all46 = []
+            while 1:
+                _choice47 = self._pos
+                try:
+                    _call_status = self._SPACE()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _all46.append(_result)
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice47
+                    break
+            _result = _all46
+            _call_status = self._command()
+            _result = _call_status.result
+            _error = self._combine_errors(_call_status.error, _error)
+            cmd = _result
+            _result = (Nonterminal('named_command', [name, cmd]))
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._named_command()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_repetition(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def repetition(self):
+        return self._repetition().result
+    def _repetition(self):
+        _status = self._dict_repetition.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_repetition[self._pos] = self._Status_repetition()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            while 1:
+                _error = None
+                _choice48 = self._pos
+                try:
+                    _call_status = self._enclosed()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    what = _result
+                    _all49 = []
+                    while 1:
+                        _choice50 = self._pos
+                        try:
+                            _call_status = self._SPACE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all49.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice50
+                            break
+                    _result = _all49
+                    _result = self.__chars__('?')
+                    _all51 = []
+                    while 1:
+                        _choice52 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all51.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice52
+                            break
+                    _result = _all51
+                    _result = (Nonterminal('maybe', [what]))
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice48
+                _choice53 = self._pos
+                try:
+                    _call_status = self._enclosed()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    what = _result
+                    _all54 = []
+                    while 1:
+                        _choice55 = self._pos
+                        try:
+                            _call_status = self._SPACE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all54.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice55
+                            break
+                    _result = _all54
+                    while 1:
+                        _error = None
+                        _choice56 = self._pos
+                        try:
+                            _result = self.__chars__('*')
+                            break
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice56
+                        _choice57 = self._pos
+                        try:
+                            _result = self.__chars__('+')
+                            break
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice57
+                            raise self._BacktrackException(_error)
+                        _result = self.__chars__('+')
+                        break
+                    repetition = _result
+                    _all58 = []
+                    while 1:
+                        _choice59 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all58.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice59
+                            break
+                    _result = _all58
+                    _result = (Nonterminal('repetition', [repetition, what]))
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice53
+                    raise self._BacktrackException(_error)
+                _call_status = self._enclosed()
+                _result = _call_status.result
+                _error = self._combine_errors(_call_status.error, _error)
+                what = _result
+                _all60 = []
+                while 1:
+                    _choice61 = self._pos
+                    try:
+                        _call_status = self._SPACE()
+                        _result = _call_status.result
+                        _error = self._combine_errors(_call_status.error, _error)
+                        _all60.append(_result)
+                    except self._BacktrackException, _exc:
+                        _error = self._combine_errors(_error, _exc.error)
+                        self._pos = _choice61
+                        break
+                _result = _all60
+                while 1:
+                    _error = None
+                    _choice62 = self._pos
+                    try:
+                        _result = self.__chars__('*')
+                        break
+                    except self._BacktrackException, _exc:
+                        _error = self._combine_errors(_error, _exc.error)
+                        self._pos = _choice62
+                    _choice63 = self._pos
+                    try:
+                        _result = self.__chars__('+')
+                        break
+                    except self._BacktrackException, _exc:
+                        _error = self._combine_errors(_error, _exc.error)
+                        self._pos = _choice63
+                        raise self._BacktrackException(_error)
+                    _result = self.__chars__('+')
+                    break
+                repetition = _result
+                _all64 = []
+                while 1:
+                    _choice65 = self._pos
+                    try:
+                        _call_status = self._IGNORE()
+                        _result = _call_status.result
+                        _error = self._combine_errors(_call_status.error, _error)
+                        _all64.append(_result)
+                    except self._BacktrackException, _exc:
+                        _error = self._combine_errors(_error, _exc.error)
+                        self._pos = _choice65
+                        break
+                _result = _all64
+                _result = (Nonterminal('repetition', [repetition, what]))
+                break
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._repetition()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_negation(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def negation(self):
+        return self._negation().result
+    def _negation(self):
+        _status = self._dict_negation.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_negation[self._pos] = self._Status_negation()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            while 1:
+                _error = None
+                _choice66 = self._pos
+                try:
+                    _result = self.__chars__('!')
+                    _all67 = []
+                    while 1:
+                        _choice68 = self._pos
+                        try:
+                            _call_status = self._SPACE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all67.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice68
+                            break
+                    _result = _all67
+                    _call_status = self._negation()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    what = _result
+                    _all69 = []
+                    while 1:
+                        _choice70 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all69.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice70
+                            break
+                    _result = _all69
+                    _result = (Nonterminal('negation', [what]))
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice66
+                _choice71 = self._pos
+                try:
+                    _call_status = self._enclosed()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice71
+                    raise self._BacktrackException(_error)
+                _call_status = self._enclosed()
+                _result = _call_status.result
+                _error = self._combine_errors(_call_status.error, _error)
+                break
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._negation()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_enclosed(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def enclosed(self):
+        return self._enclosed().result
+    def _enclosed(self):
+        _status = self._dict_enclosed.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_enclosed[self._pos] = self._Status_enclosed()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            while 1:
+                _error = None
+                _choice72 = self._pos
+                try:
+                    _result = self.__chars__('<')
+                    _all73 = []
+                    while 1:
+                        _choice74 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all73.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice74
+                            break
+                    _result = _all73
+                    _call_status = self._primary()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    what = _result
+                    _all75 = []
+                    while 1:
+                        _choice76 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all75.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice76
+                            break
+                    _result = _all75
+                    _result = self.__chars__('>')
+                    _all77 = []
+                    while 1:
+                        _choice78 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all77.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice78
+                            break
+                    _result = _all77
+                    _result = (Nonterminal('exclusive', [what]))
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice72
+                _choice79 = self._pos
+                try:
+                    _result = self.__chars__('[')
+                    _all80 = []
+                    while 1:
+                        _choice81 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all80.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice81
+                            break
+                    _result = _all80
+                    _call_status = self._or_()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    what = _result
+                    _all82 = []
+                    while 1:
+                        _choice83 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all82.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice83
+                            break
+                    _result = _all82
+                    _result = self.__chars__(']')
+                    _all84 = []
+                    while 1:
+                        _choice85 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all84.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice85
+                            break
+                    _result = _all84
+                    _result = (Nonterminal('ignore', [what]))
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice79
+                _choice86 = self._pos
+                try:
+                    _before_discard87 = _result
+                    _result = self.__chars__('(')
+                    _all88 = []
+                    while 1:
+                        _choice89 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all88.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice89
+                            break
+                    _result = _all88
+                    _result = _before_discard87
+                    _call_status = self._or_()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _before_discard90 = _result
+                    _result = self.__chars__(')')
+                    _all91 = []
+                    while 1:
+                        _choice92 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all91.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice92
+                            break
+                    _result = _all91
+                    _result = _before_discard90
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice86
+                _choice93 = self._pos
+                try:
+                    _call_status = self._primary()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice93
+                    raise self._BacktrackException(_error)
+                _call_status = self._primary()
+                _result = _call_status.result
+                _error = self._combine_errors(_call_status.error, _error)
+                break
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._enclosed()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_primary(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def primary(self):
+        return self._primary().result
+    def _primary(self):
+        _status = self._dict_primary.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_primary[self._pos] = self._Status_primary()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            while 1:
+                _error = None
+                _choice94 = self._pos
+                try:
+                    _call_status = self._call()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice94
+                _choice95 = self._pos
+                try:
+                    _call_status = self._REGEX()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _before_discard96 = _result
+                    _all97 = []
+                    while 1:
+                        _choice98 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all97.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice98
+                            break
+                    _result = _all97
+                    _result = _before_discard96
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice95
+                _choice99 = self._pos
+                try:
+                    _call_status = self._QUOTE()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _before_discard100 = _result
+                    _all101 = []
+                    while 1:
+                        _choice102 = self._pos
+                        try:
+                            _call_status = self._IGNORE()
+                            _result = _call_status.result
+                            _error = self._combine_errors(_call_status.error, _error)
+                            _all101.append(_result)
+                        except self._BacktrackException, _exc:
+                            _error = self._combine_errors(_error, _exc.error)
+                            self._pos = _choice102
+                            break
+                    _result = _all101
+                    _result = _before_discard100
+                    break
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice99
+                    raise self._BacktrackException(_error)
+                _call_status = self._QUOTE()
+                _result = _call_status.result
+                _error = self._combine_errors(_call_status.error, _error)
+                _before_discard103 = _result
+                _all104 = []
+                while 1:
+                    _choice105 = self._pos
+                    try:
+                        _call_status = self._IGNORE()
+                        _result = _call_status.result
+                        _error = self._combine_errors(_call_status.error, _error)
+                        _all104.append(_result)
+                    except self._BacktrackException, _exc:
+                        _error = self._combine_errors(_error, _exc.error)
+                        self._pos = _choice105
+                        break
+                _result = _all104
+                _result = _before_discard103
+                break
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._primary()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    class _Status_call(_Status):
+        def __init__(self):
+            self.pos = 0
+            self.error = None
+            self.status = self.INPROGRESS
+            self.result = None
+    def call(self):
+        return self._call().result
+    def _call(self):
+        _status = self._dict_call.get(self._pos, None)
+        if _status is None:
+            _status = self._dict_call[self._pos] = self._Status_call()
+        elif _status.status == _status.NORMAL:
+            self._pos = _status.pos
+            return _status
+        elif _status.status == _status.ERROR:
+            raise self._BacktrackException(_status.error)
+        elif (_status.status == _status.INPROGRESS or
+              _status.status == _status.LEFTRECURSION):
+            _status.status = _status.LEFTRECURSION
+            if _status.result is not None:
+                self._pos = _status.pos
+                return _status
+            else:
+                raise self._BacktrackException(None)
+        elif _status.status == _status.SOMESOLUTIONS:
+            _status.status = _status.INPROGRESS
+        _startingpos = self._pos
+        try:
+            _result = None
+            _error = None
+            _call_status = self._NAME()
+            _result = _call_status.result
+            _error = self._combine_errors(_call_status.error, _error)
+            x = _result
+            _all106 = []
+            while 1:
+                _choice107 = self._pos
+                try:
+                    _call_status = self._IGNORE()
+                    _result = _call_status.result
+                    _error = self._combine_errors(_call_status.error, _error)
+                    _all106.append(_result)
+                except self._BacktrackException, _exc:
+                    _error = self._combine_errors(_error, _exc.error)
+                    self._pos = _choice107
+                    break
+            _result = _all106
+            _result = (Nonterminal("call", [x]))
+            if _status.status == _status.LEFTRECURSION:
+                if _status.result is not None:
+                    if _status.pos >= self._pos:
+                        _status.status = _status.NORMAL
+                        self._pos = _status.pos
+                        return _status
+                _status.pos = self._pos
+                _status.status = _status.SOMESOLUTIONS
+                _status.result = _result
+                _status.error = _error
+                self._pos = _startingpos
+                return self._call()
+            _status.status = _status.NORMAL
+            _status.pos = self._pos
+            _status.result = _result
+            _status.error = _error
+            return _status
+        except self._BacktrackException, _exc:
+            _status.pos = -1
+            _status.result = None
+            _error = self._combine_errors(_error, _exc.error)
+            _status.error = _error
+            _status.status = _status.ERROR
+            raise self._BacktrackException(_error)
+    def __init__(self, inputstream):
+        self._dict_NAME = {}
+        self._dict_SPACE = {}
+        self._dict_COMMENT = {}
+        self._dict_IGNORE = {}
+        self._dict_newline = {}
+        self._dict_REGEX = {}
+        self._dict_QUOTE = {}
+        self._dict_PYTHONCODE = {}
+        self._dict_EOF = {}
+        self._dict_file = {}
+        self._dict_list = {}
+        self._dict_production = {}
+        self._dict_or_ = {}
+        self._dict_commands = {}
+        self._dict_command = {}
+        self._dict_simplecommand = {}
+        self._dict_return_ = {}
+        self._dict_commandchain = {}
+        self._dict_named_command = {}
+        self._dict_repetition = {}
+        self._dict_negation = {}
+        self._dict_enclosed = {}
+        self._dict_primary = {}
+        self._dict_call = {}
+        self._pos = 0
+        self._inputstream = inputstream
+    def _regex299149370(self):
+        _choice108 = self._pos
+        _runner = self._Runner(self._inputstream, self._pos)
+        _i = _runner.recognize_299149370(self._pos)
+        if _runner.last_matched_state == -1:
+            self._pos = _choice108
+            raise self._BacktrackException
+        _upto = _runner.last_matched_index + 1
+        _result = self._inputstream[self._pos: _upto]
+        self._pos = _upto
+        return _result
+    def _regex1006631623(self):
+        _choice109 = self._pos
+        _runner = self._Runner(self._inputstream, self._pos)
+        _i = _runner.recognize_1006631623(self._pos)
+        if _runner.last_matched_state == -1:
+            self._pos = _choice109
+            raise self._BacktrackException
+        _upto = _runner.last_matched_index + 1
+        _result = self._inputstream[self._pos: _upto]
+        self._pos = _upto
+        return _result
+    def _regex528667127(self):
+        _choice110 = self._pos
+        _runner = self._Runner(self._inputstream, self._pos)
+        _i = _runner.recognize_528667127(self._pos)
+        if _runner.last_matched_state == -1:
+            self._pos = _choice110
+            raise self._BacktrackException
+        _upto = _runner.last_matched_index + 1
+        _result = self._inputstream[self._pos: _upto]
+        self._pos = _upto
+        return _result
+    def _regex291086639(self):
+        _choice111 = self._pos
+        _runner = self._Runner(self._inputstream, self._pos)
+        _i = _runner.recognize_291086639(self._pos)
+        if _runner.last_matched_state == -1:
+            self._pos = _choice111
+            raise self._BacktrackException
+        _upto = _runner.last_matched_index + 1
+        _result = self._inputstream[self._pos: _upto]
+        self._pos = _upto
+        return _result
+    def _regex1074651696(self):
+        _choice112 = self._pos
+        _runner = self._Runner(self._inputstream, self._pos)
+        _i = _runner.recognize_1074651696(self._pos)
+        if _runner.last_matched_state == -1:
+            self._pos = _choice112
+            raise self._BacktrackException
+        _upto = _runner.last_matched_index + 1
+        _result = self._inputstream[self._pos: _upto]
+        self._pos = _upto
+        return _result
+    def _regex1124192327(self):
+        _choice113 = self._pos
+        _runner = self._Runner(self._inputstream, self._pos)
+        _i = _runner.recognize_1124192327(self._pos)
+        if _runner.last_matched_state == -1:
+            self._pos = _choice113
+            raise self._BacktrackException
+        _upto = _runner.last_matched_index + 1
+        _result = self._inputstream[self._pos: _upto]
+        self._pos = _upto
+        return _result
+    def _regex1979538501(self):
+        _choice114 = self._pos
+        _runner = self._Runner(self._inputstream, self._pos)
+        _i = _runner.recognize_1979538501(self._pos)
+        if _runner.last_matched_state == -1:
+            self._pos = _choice114
+            raise self._BacktrackException
+        _upto = _runner.last_matched_index + 1
+        _result = self._inputstream[self._pos: _upto]
+        self._pos = _upto
+        return _result
+    class _Runner(object):
+        def __init__(self, text, pos):
+            self.text = text
+            self.pos = pos
+            self.last_matched_state = -1
+            self.last_matched_index = -1
+            self.state = -1
+        def recognize_299149370(runner, i):
+            assert i >= 0
+            input = runner.text
+            state = 0
+            while 1:
+                if state == 0:
+                    runner.last_matched_index = i - 1
+                    runner.last_matched_state = state
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 0
+                        return i
+                    if char == '\n':
+                        state = 1
+                    elif char == ' ':
+                        state = 2
+                    else:
+                        break
+                if state == 1:
+                    runner.last_matched_index = i - 1
+                    runner.last_matched_state = state
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 1
+                        return i
+                    if char == '\n':
+                        state = 1
+                        continue
+                    elif char == ' ':
+                        state = 1
+                        continue
+                    else:
+                        break
+                if state == 2:
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 2
+                        return ~i
+                    if char == '\n':
+                        state = 1
+                        continue
+                    elif char == ' ':
+                        state = 2
+                        continue
+                    else:
+                        break
+                runner.last_matched_state = state
+                runner.last_matched_index = i - 1
+                runner.state = state
+                if i == len(input):
+                    return i
+                else:
+                    return ~i
+                break
+            runner.state = state
+            return ~i
+        def recognize_1006631623(runner, i):
+            assert i >= 0
+            input = runner.text
+            state = 0
+            while 1:
+                if state == 0:
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 0
+                        return ~i
+                    if char == '`':
+                        state = 3
+                    else:
+                        break
+                if state == 2:
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 2
+                        return ~i
+                    if '\x00' <= char <= '\xff':
+                        state = 3
+                    else:
+                        break
+                if state == 3:
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 3
+                        return ~i
+                    if char == '`':
+                        state = 1
+                    elif char == '\\':
+                        state = 2
+                        continue
+                    elif '\x00' <= char <= '[':
+                        state = 3
+                        continue
+                    elif ']' <= char <= '_':
+                        state = 3
+                        continue
+                    elif 'a' <= char <= '\xff':
+                        state = 3
+                        continue
+                    else:
+                        break
+                runner.last_matched_state = state
+                runner.last_matched_index = i - 1
+                runner.state = state
+                if i == len(input):
+                    return i
+                else:
+                    return ~i
+                break
+            runner.state = state
+            return ~i
+        def recognize_528667127(runner, i):
+            assert i >= 0
+            input = runner.text
+            state = 0
+            while 1:
+                if state == 0:
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 0
+                        return ~i
+                    if char == ' ':
+                        state = 0
+                        continue
+                    elif char == '#':
+                        state = 2
+                    else:
+                        break
+                if state == 1:
+                    runner.last_matched_index = i - 1
+                    runner.last_matched_state = state
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 1
+                        return i
+                    if char == ' ':
+                        state = 0
+                        continue
+                    elif char == '#':
+                        state = 2
+                    else:
+                        break
+                if state == 2:
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 2
+                        return ~i
+                    if char == '\n':
+                        state = 1
+                        continue
+                    elif '\x00' <= char <= '\t':
+                        state = 2
+                        continue
+                    elif '\x0b' <= char <= '\xff':
+                        state = 2
+                        continue
+                    else:
+                        break
+                runner.last_matched_state = state
+                runner.last_matched_index = i - 1
+                runner.state = state
+                if i == len(input):
+                    return i
+                else:
+                    return ~i
+                break
+            runner.state = state
+            return ~i
+        def recognize_291086639(runner, i):
+            assert i >= 0
+            input = runner.text
+            state = 0
+            while 1:
+                if state == 0:
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 0
+                        return ~i
+                    if char == '{':
+                        state = 2
+                    else:
+                        break
+                if state == 2:
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 2
+                        return ~i
+                    if char == '}':
+                        state = 1
+                    elif '\x00' <= char <= '\t':
+                        state = 2
+                        continue
+                    elif '\x0b' <= char <= '|':
+                        state = 2
+                        continue
+                    elif '~' <= char <= '\xff':
+                        state = 2
+                        continue
+                    else:
+                        break
+                runner.last_matched_state = state
+                runner.last_matched_index = i - 1
+                runner.state = state
+                if i == len(input):
+                    return i
+                else:
+                    return ~i
+                break
+            runner.state = state
+            return ~i
+        def recognize_1074651696(runner, i):
+            assert i >= 0
+            input = runner.text
+            state = 0
+            while 1:
+                if state == 0:
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 0
+                        return ~i
+                    if 'A' <= char <= 'Z':
+                        state = 1
+                    elif char == '_':
+                        state = 1
+                    elif 'a' <= char <= 'z':
+                        state = 1
+                    else:
+                        break
+                if state == 1:
+                    runner.last_matched_index = i - 1
+                    runner.last_matched_state = state
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 1
+                        return i
+                    if '0' <= char <= '9':
+                        state = 1
+                        continue
+                    elif 'A' <= char <= 'Z':
+                        state = 1
+                        continue
+                    elif char == '_':
+                        state = 1
+                        continue
+                    elif 'a' <= char <= 'z':
+                        state = 1
+                        continue
+                    else:
+                        break
+                runner.last_matched_state = state
+                runner.last_matched_index = i - 1
+                runner.state = state
+                if i == len(input):
+                    return i
+                else:
+                    return ~i
+                break
+            runner.state = state
+            return ~i
+        def recognize_1124192327(runner, i):
+            assert i >= 0
+            input = runner.text
+            state = 0
+            while 1:
+                if state == 0:
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 0
+                        return ~i
+                    if char == "'":
+                        state = 1
+                    else:
+                        break
+                if state == 1:
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 1
+                        return ~i
+                    if '\x00' <= char <= '&':
+                        state = 1
+                        continue
+                    elif '(' <= char <= '\xff':
+                        state = 1
+                        continue
+                    elif char == "'":
+                        state = 2
+                    else:
+                        break
+                runner.last_matched_state = state
+                runner.last_matched_index = i - 1
+                runner.state = state
+                if i == len(input):
+                    return i
+                else:
+                    return ~i
+                break
+            runner.state = state
+            return ~i
+        def recognize_1979538501(runner, i):
+            assert i >= 0
+            input = runner.text
+            state = 0
+            while 1:
+                if state == 0:
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 0
+                        return ~i
+                    if char == '#':
+                        state = 1
+                    elif char == '\t':
+                        state = 2
+                    elif char == '\n':
+                        state = 2
+                    elif char == ' ':
+                        state = 2
+                    else:
+                        break
+                if state == 1:
+                    if i < len(input):
+                        char = input[i]
+                        i += 1
+                    else:
+                        runner.state = 1
+                        return ~i
+                    if '\x00' <= char <= '\t':
+                        state = 1
+                        continue
+                    elif '\x0b' <= char <= '\xff':
+                        state = 1
+                        continue
+                    elif char == '\n':
+                        state = 2
+                    else:
+                        break
+                runner.last_matched_state = state
+                runner.last_matched_index = i - 1
+                runner.state = state
+                if i == len(input):
+                    return i
+                else:
+                    return ~i
+                break
+            runner.state = state
+            return ~i
+class PyPackratSyntaxParser(PackratParser):
+    def __init__(self, stream):
+        self.init_parser(stream)
+forbidden = dict.fromkeys(("__weakref__ __doc__ "
+                           "__dict__ __module__").split())
+initthere = "__init__" in PyPackratSyntaxParser.__dict__
+for key, value in Parser.__dict__.iteritems():
+    if key not in PyPackratSyntaxParser.__dict__ and key not in forbidden:
+        setattr(PyPackratSyntaxParser, key, value)
+PyPackratSyntaxParser.init_parser = Parser.__init__.im_func

Added: pypy/dist/pypy/rlib/parsing/test/test_pypackrat.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rlib/parsing/test/test_pypackrat.py	Tue Jun 19 17:24:32 2007
@@ -0,0 +1,415 @@
+import py
+from pypy.rlib.parsing import regex
+from pypy.rlib.parsing.pypackrat import *
+import operator
+
+class TestPackrat(object):
+    def test_simple(self):
+        class parser(PackratParser):
+            """
+            a: 'a'*;
+            b: 'a'+;
+            c: ('a' | 'b')+;
+            """
+        print parser._code
+        p = parser("ababababa")
+        assert p.c() == list("ababababa")
+        p = parser("aaaaaaaa")
+        assert p.a() == list("aaaaaaaa")
+        p = parser("")
+        assert p.a() == []
+        p = parser("")
+        py.test.raises(BacktrackException, p.b)
+
+    def test_questionmark(self):
+        class parser(PackratParser):
+            """
+            a: 'a'? 'b';
+            """
+        print parser._code
+        p = parser("ab")
+        assert p.a() == 'b'
+        p = parser("b")
+        assert p.a() == 'b'
+
+    def test_call(self):
+        class parser(PackratParser):
+            """
+            a: 'a'? 'b';
+            b: a 'c';
+            """
+        print parser._code
+        p = parser("abc")
+        res = p.b()
+        assert res == 'c'
+        p = parser("bc")
+        res = p.b()
+        assert res == 'c'
+
+    def test_memoize(self):
+        class parser(PackratParser):
+            """
+            x: a 'end';
+            a: b c | b;
+            b: 'b';
+            c: 'c';
+            """
+        print parser._code
+        p = parser("bend")
+        res = p.x()
+        assert res == 'end'
+
+    def test_enclose(self):
+        class parser(PackratParser):
+            """
+            a: 'a' <'b'> 'c'+;
+            """
+        print parser._code
+        p = parser("abcccccc")
+        p.a() == 'b'
+
+    def test_not(self):
+        class parser(PackratParser):
+            """
+            a: 'bh' !'a';
+            """
+        print parser._code
+        p = parser('bhc')
+        assert p.a() == 'bh'
+        p.__chars__('c') == 'c'
+        p = parser('bh')
+        p.a() == 'bh'
+        py.test.raises(BacktrackException, p.__any__)
+
+    def test_lookahead(self):
+        class parser(PackratParser):
+            """
+            a: 'b' !!'a';
+            """
+        print parser._code
+        p = parser('ba')
+        res = p.a()
+        assert res == 'b'
+        assert p.__any__() == 'a'
+
+    def test_regex1(self):
+        class parser(PackratParser):
+            """
+            a: 'b' `a|b`;
+            """
+        print parser._code
+        p = parser('ba')
+        res = p.a()
+        assert res == 'a'
+        py.test.raises(BacktrackException, p.__any__)
+        p = parser('bb')
+        res = p.a()
+        assert res == 'b'
+        py.test.raises(BacktrackException, p.__any__)
+
+
+    def test_regex2(self):
+        class parser(PackratParser):
+            """
+            a: 'b' `[^\n]*`;
+            """
+        print parser._code
+        p = parser('ba#$@@$%\nbc')
+        res = p.a()
+        assert res == 'a#$@@$%'
+        assert p.__any__() == '\n'
+
+    def test_name(self):
+        class parser(PackratParser):
+            """
+            a: c = 'b'
+               r = `[^\n]*`
+               return {c + r};
+            """
+        print parser._code
+        p = parser('ba#$@@$%\nbc')
+        res = p.a()
+        assert res == 'ba#$@@$%'
+        assert p.__any__() == '\n'
+
+    def test_name2(self):
+        class parser(PackratParser):
+            """
+            a: c = 'b'*
+               r = `[^\n]*`
+               return {(len(c), r)};
+            """
+        print parser._code
+        p = parser('bbbbbba#$@@$%\nbc')
+        res = p.a()
+        assert res == (6, "a#$@@$%")
+        assert p.__any__() == '\n'
+
+    def test_name3(self):
+        class parser(PackratParser):
+            """
+            a: c = 'd'+
+               r = 'f'+
+               return {"".join(c) + "".join(r)}
+             | c = 'b'*
+               r = `[^\n]*`
+               return {(len(c), r)};
+            """
+        print parser._code
+        p = parser('bbbbbba#$@@$%\nbc')
+        res = p.a()
+        assert res == (6, "a#$@@$%")
+        assert p.__any__() == '\n'
+        p = parser('dddffffx')
+        res = p.a()
+        assert res == "dddffff"
+        assert p.__any__() == 'x'
+
+    def test_nested_repetition(self):
+        class parser(PackratParser):
+            """
+            a: ('a' 'b'*)+;
+            """
+        print parser._code
+        p = parser('aaabbbab')
+        res = p.a()
+        assert res == [[], [], ['b', 'b', 'b'], ['b']]
+
+
+    def test_ignore(self):
+        class parser(PackratParser):
+            """
+            a: ('a' ['b'])+;
+            """
+        print parser._code
+        p = parser('abababababab')
+        res = p.a()
+        assert res == list('aaaaaa')
+
+
+    def test_regex(self):
+        class parser(PackratParser):
+            r"""
+            a: `\"`;
+            """
+        print parser._code
+        p = parser('"')
+        res = p.a()
+        assert res == '"'
+
+
+    def test_memoize_exceptions(self):
+        class parser(PackratParser):
+            """
+            b: 'a';
+            """
+        print parser._code
+        p = parser("c")
+        excinfo = py.test.raises(BacktrackException, p.b)
+        excinfo = py.test.raises(BacktrackException, p.b)
+        excinfo = py.test.raises(BacktrackException, p.b)
+
+    def test_error_character(self):
+        class parser(PackratParser):
+            """
+            b: 'a';
+            """
+        print parser._code
+        p = parser("c")
+        excinfo = py.test.raises(BacktrackException, p.b)
+        assert excinfo.value.error.pos == 0
+        assert excinfo.value.error.expected == ['a']
+
+    def test_error_or(self):
+        class parser(PackratParser):
+            """
+            b: 'a' | 'b';
+            """
+        print parser._code
+        p = parser("c")
+        excinfo = py.test.raises(BacktrackException, p.b)
+        assert excinfo.value.error.pos == 0
+        assert excinfo.value.error.expected == ['a', 'b']
+
+    def test_error_not(self):
+        class parser(PackratParser):
+            """
+            b: 
+                'b' !'a';
+            """
+        p = parser("ba")
+        excinfo = py.test.raises(BacktrackException, p.b)
+        assert excinfo.value.error.pos == 1
+        assert excinfo.value.error.expected == ['NOT a']
+        print parser._code
+
+    def test_error_lookahead(self):
+        class parser(PackratParser):
+            """
+            b: 
+                'b' !!'a';
+            """
+        p = parser("bc")
+        print parser._code
+        excinfo = py.test.raises(BacktrackException, p.b)
+        assert excinfo.value.error.pos == 1
+        assert excinfo.value.error.expected == ['a']
+
+    def test_error_star(self):
+        class parser(PackratParser):
+            """
+            b: 
+                'b'* !__any__;
+            """
+        print parser._code
+        p = parser("bbc")
+        print parser._code
+        excinfo = py.test.raises(BacktrackException, p.b)
+        assert excinfo.value.error.pos == 2
+        assert excinfo.value.error.expected == ['b']
+
+    def test_leftrecursion(self):
+        class parser(PackratParser):
+            """
+            b: b 'a' | 'b';
+            """
+        print parser._code
+        p = parser("b")
+        res = p.b()
+        assert res == "b"
+        p = parser("bac")
+        res = p.b()
+        assert p._pos == 2
+        assert res == "a"
+        p = parser("baaaaaaaaaaaaaac")
+        res = p.b()
+        assert p._pos == 15
+        assert res == "a"
+
+    def test_leftrecursion_arithmetic(self):
+        class parser(PackratParser):
+            """
+            additive:
+                a = additive
+                '-'
+                b = multitive
+                return {a - b}
+              | multitive;
+            multitive:
+                a = multitive
+                '*'
+                b = simple
+                return {a * b}
+              | simple;
+            simple:
+                x = `0|([1-9][0-9]*)`
+                return {int(x)};
+            """
+        print parser._code
+        p = parser("5")
+        res = p.multitive()
+        assert res == 5
+        p._pos = 0
+        res = p.multitive()
+        assert res == 5
+        p = parser("5-5-5")
+        res = p.additive()
+        assert res == -5
+        assert p._pos == 5
+
+    def test_leftrecursion_more_choices(self):
+        class parser(PackratParser):
+            """
+            b:
+                b 'a'
+              | b 'c'
+              | 'b';
+            """
+        print parser._code
+        p = parser("b")
+        res = p.b()
+        assert res == "b"
+        p = parser("bcx")
+        res = p.b()
+        assert p._pos == 2
+        assert res == "c"
+
+    def test_regexparse(self):
+        py.test.skip()
+        class RegexParser(PackratParser):
+            """
+            regex:
+                r1 = concatenation
+                '|'
+                r2 = regex
+                return {r1 | r2}
+              | concatenation;
+
+            concatenation:
+                r1 = repetition
+                r2 = concatenation
+                return {r1 + r2}
+              | repetition;
+
+            repetition:
+                r1 = primary
+                '*'
+                return {r1.kleene()}
+              | r1 = primary
+                '+'
+                return {r1 + r1.kleene()}
+              | r1 = primary
+                '?'
+                return {regex.StringExpression("") | r1}
+              | r = primary
+                '{'
+                n = numrange
+                '}'
+                return {r * n[0] + reduce(operator.or_,
+                                          [r * i for i in range(n[1] - n[0])],
+                                          regex.StringExpression("")}
+              | primary;
+
+            primary:
+                ['('] regex [')']
+              | ['['] range [']']
+              | char
+              | '.'
+                return {regex.RangeExpression(chr(0), chr(255))};
+
+            char:
+                c = QUOTEDCHAR
+                return {regex.StringExpression(unescape(c))}
+              | c = CHAR
+                return {regex.StringExpression(c)};
+
+            range:
+                '^'
+                r = subrange
+                return {~r}
+              | subrange;
+
+            subrange:
+                l = rangeelement+
+                return {reduce(operator.or_, l, regex.StringExpression(""))};
+
+            rangeelement:
+                c1 = char
+                '-'
+                c2 = char
+                return {regex.RangeExpression(c1, c2)}
+              | c = char
+                return {regex.StringExpression(c)};
+
+            numrange:
+                n1 = NUM
+                ','
+                n2 = NUM
+                return {n1, n2}
+              | n1 = NUM
+                return {n1, n1};
+
+            NUM:
+                c = `0|([1-9][0-9]*)`
+                return {int(c)};
+            """



More information about the Pypy-commit mailing list