# Generated by ../generate_parser.py
"""
# Grammar definition:
```
import textwrap
```

ignored Space = /[ \\t]+/
ignored Comment = /#[^\\r\\n]*/

Newline = /[\\r\\n][\\s]*/
LineSep = Some(Newline | ";")
Name = /[_a-zA-Z][_a-zA-Z0-9]*/
Comma = wrap(",")

wrap(x) => Skip(Newline) >> x << Skip(Newline)

# Parse a full word, then see if it matches our keyword. The point is to make
# sure that we don't simply match the first part of a word. (For example, if
# the input string is "classify", we wouldn't want to match the keyword "class".)
kw(word) => Name where `lambda x: x == word`

Params = wrap("(") >> (wrap(Name) /? Comma) << ")"
IgnoreKeyword = kw("ignored") | kw("ignore")

class StringLiteral {
    value: (
        /(?s)[bB]?(\"\"\"([^\\\\]|\\\\.)*?\"\"\")[iI]?/
        | /(?s)[bB]?('''([^\\\\]|\\\\.)*?''')[iI]?/
        | /[bB]?("([^"\\\\]|\\\\.)*")[iI]?/
        | /[bB]?('([^'\\\\]|\\\\.)*')[iI]?/
    )
}

class RegexLiteral {
    value: /[bB]?\\/([^\\/\\\\]|\\\\.)*\\/[iI]?/
}

class PythonSection {
    # Strip the backticks and remove any common indentation.
    value: /(?s)```.*?```/ |> `lambda x: textwrap.dedent(x[3:-3])`
}

class PythonExpression {
    # Strip the backticks.
    value: /`.*?`/ |> `lambda x: x[1:-1]`
        | /\\d+/
        | "True"
        | "False"
        | "None"
}

class RuleDef {
    is_ignored: Opt(IgnoreKeyword) |> `bool`
    name: Name
    params: Opt(Params) << wrap("=>" | "=" | ":")
    expr: Expr
}

class ClassDef {
    name: kw("class") >> Name
    params: Opt(Params)
    members: wrap("{") >> (ClassMember /? LineSep) << "}"
}

class ClassMember {
    is_omitted: Opt("let") |> `bool`
    name: Name
    params: Opt(Params) << wrap("=>" | "=" | ":")
    expr: Expr
}

class IgnoreStmt {
    expr: IgnoreKeyword >> Expr
}

Stmt = ClassDef
    | RuleDef
    | IgnoreStmt
    | PythonSection
    | PythonExpression

class LetExpression {
    name: kw("let") >> Name << wrap("=>" | "=" | ":")
    expr: Expr << wrap(kw("in"))
    body: Expr
}

class Ref {
    value: Name
}

class ListLiteral {
    elements: "[" >> (wrap(Expr) /? Comma) << "]"
}

class ByteLiteral {
    prefix: /0[xX]/
    value: /[0-9a-fA-F]{2}/ |> `lambda x: int(x, 16)`
}

Atom = StringLiteral
    | RegexLiteral
    | LetExpression
    | ListLiteral
    | ByteLiteral
    | PythonExpression
    | Ref

class KeywordArg {
    name: Name << ("=>" | "=" | ":")
    expr: Expr
}

class ArgList {
    args: "(" >> (wrap(KeywordArg | Expr) /? Comma) << ")"
}

Expr = OperatorPrecedence(
    Atom,
    Mixfix("(" >> wrap(Expr) << ")"),
    Postfix(ArgList),
    Postfix("?" | "*" | "+" | Repeat),
    LeftAssoc(wrap("//" | "/?")),
    LeftAssoc(wrap("<<" | ">>")),
    LeftAssoc(wrap("<|" | "|>" | "where")),
    LeftAssoc(wrap("|")),
)

class Repeat {
    open: "{"
    start: RepeatArg?
    stop: ("," >> RepeatArg) | ("," >> None) | `start`
    close: "}"
}

RepeatArg = PythonExpression | Ref

ManyStmts = Sep(Stmt, LineSep, allow_trailer=True, allow_empty=False)
SingleExpr = Expr << Opt(LineSep)

start = Skip(Newline) >> (ManyStmts | SingleExpr)

"""

from collections import namedtuple as _nt
from re import compile as _compile_re, IGNORECASE as _IGNORECASE

class Node:
    _fields = ()

    def __init__(self):
        self._metadata = _Metadata()

    def __eq__(self, other):
        if not isinstance(other, self.__class__):
            return False
        for field in self._fields:
            if getattr(self, field) != getattr(other, field):
                return False
        return True

    def _asdict(self):
        return {k: getattr(self, k) for k in self._fields}

    def _replace(self, **kw):
        for field in self._fields:
            if field not in kw:
                kw[field] = getattr(self, field)
        result = self.__class__(**kw)
        result._metadata.update(self._metadata)
        return result


class _Metadata:
    def __init__(self, **fields):
        object.__setattr__(self, '_fields', fields)

    def __getattr__(self, name):
        return self._fields.get(name)

    def __setattr__(self, name, value):
        self._fields[name] = value

    def __len__(self):
        return len(self._fields)

    def copy(self):
        return _Metadata(**self._fields)

    def update(self, other):
        self._fields.update(other._fields)


class Rule:
    def __init__(self, name, parse, definition):
        self.name = name
        self.parse = parse
        self.definition = definition

    def __repr__(self):
        return (f'Rule(name={self.name!r}, parse={self.parse.__name__},'
            f' definition={self.definition!r})')


import textwrap


class SourcerError(Exception):
    """Common superclass for ParseError and PartialParseError."""


class ParseError(SourcerError):
    def __init__(self, message, index, line, column):
        super().__init__(message)
        self.position = _Position(index, line, column)


class PartialParseError(SourcerError):
    def __init__(self, partial_result, last_position, excerpt):
        super().__init__('Incomplete parse. Unexpected input on line'
            f' {last_position.line}, column {last_position.column}:\n{excerpt}')
        self.partial_result = partial_result
        self.last_position = last_position


class Infix(Node):
    _fields = ('left', 'operator', 'right')

    def __init__(self, left, operator, right):
        Node.__init__(self)
        self.left = left
        self.operator = operator
        self.right = right

    def __repr__(self):
        return f'Infix({self.left!r}, {self.operator!r}, {self.right!r})'


class Postfix(Node):
    _fields = ('left', 'operator')

    def __init__(self, left, operator):
        Node.__init__(self)
        self.left = left
        self.operator = operator

    def __repr__(self):
        return f'Postfix({self.left!r}, {self.operator!r})'


class Prefix(Node):
    _fields = ('operator', 'right')

    def __init__(self, operator, right):
        Node.__init__(self)
        self.operator = operator
        self.right = right

    def __repr__(self):
        return f'Prefix({self.operator!r}, {self.right!r})'


def parse(text, pos=0, fullparse=True):
    return _run(text, pos, _try_start, fullparse)


_PositionInfo = _nt('_PositionInfo', 'start, end')

_Position = _nt('_Position', 'index, line, column')


class _ParseFunction(_nt('_ParseFunction', 'func, args, kwargs')):
    def __call__(self, _text, _pos):
        return self.func(_text, _pos, *self.args, **dict(self.kwargs))


class _StringLiteral(str):
    def __call__(self, _text, _pos):
        return self._parse_function(_text, _pos)


def _wrap_string_literal(string_value, parse_function):
    result = _StringLiteral(string_value)
    result._parse_function = parse_function
    return result


class _ByteLiteral(int):
    def __call__(self, _text, _pos):
        return self._parse_function(_text, _pos)


def _wrap_byte_literal(byte_value, parse_function):
    result = _ByteLiteral(byte_value)
    result._parse_function = parse_function
    return result


def _run(text, pos, start, fullparse):
    memo = {}
    result = None

    key = (3, start, pos)
    gtor = start(text, pos)
    stack = [(key, gtor)]

    while stack:
        key, gtor = stack[-1]
        result = gtor.send(result)

        if result[0] != 3:
            stack.pop()
            memo[key] = result
        elif result in memo:
            result = memo[result]
        else:
            gtor = result[1](text, result[2])
            stack.append((result, gtor))
            result = None

    if result[0]:
        return _finalize_parse_info(text, result[1], result[2], fullparse)
    else:
        pos = result[2]
        message = result[1](text, pos)
        raise ParseError(message, pos)


def visit(node):
    visited = set()
    stack = [node]
    while stack:
        node = stack.pop()

        if isinstance(node, (list, tuple)):
            stack.extend(node)

        elif isinstance(node, dict):
            stack.extend(node.values())

        elif isinstance(node, Node):
            node_id = id(node)
            if node_id in visited:
                continue
            visited.add(node_id)

            yield node

            if hasattr(node, '_fields'):
                stack.extend(getattr(node, x) for x in node._fields)


_Traversing = _nt('_Traversing', 'parent, field, child, is_finished')


def traverse(node):
    visited = set()
    stack = [_Traversing(parent=None, field=None, child=node, is_finished=False)]
    while stack:
        traversing = stack.pop()

        if traversing.is_finished:
            yield traversing
            continue

        child = traversing.child
        child_id = id(child)

        if child_id in visited:
            continue

        visited.add(child_id)
        stack.append(traversing._replace(is_finished=True))
        yield traversing

        def extend(items):
            stack.extend(reversed(list(items)))

        if isinstance(child, (list, tuple)):
            extend(
                _Traversing(parent=child, field=i, child=x, is_finished=False)
                for i, x in enumerate(child)
            )

        elif isinstance(child, dict):
            extend(
                _Traversing(parent=child, field=k, child=v, is_finished=False)
                for k, v in child.items()
            )

        elif isinstance(child, Node) and hasattr(child, '_fields'):
            extend(
                _Traversing(
                    parent=child,
                    field=x,
                    child=getattr(child, x),
                    is_finished=False,
                )
                for x in child._fields
            )


def transform(node, *callbacks):
    if not callbacks:
        return node

    if len(callbacks) == 1:
        callback = callbacks[0]
    else:
        def callback(node):
            for f in callbacks:
                node = f(node)
            return node

    return _transform(node, callback)


def _transform(node, callback):
    if isinstance(node, list):
        return [_transform(x, callback) for x in node]

    if not isinstance(node, Node):
        return node

    updates = {}
    for field in node._fields:
        was = getattr(node, field)
        now = _transform(was, callback)
        if now is not was:
            updates[field] = now
            if isinstance(was, Node) and isinstance(now, Node) and not now._metadata:
                now._metadata.update(was._metadata)

    if updates:
        node = node._replace(**updates)

    return callback(node)


def _finalize_parse_info(text, nodes, pos, fullparse):
    line_numbers, column_numbers = _map_index_to_line_and_column(text)

    for node in visit(nodes):
        pos_info = node._metadata.position_info
        if pos_info:
            start, end = pos_info
            end -= 1
            node._metadata.position_info = _PositionInfo(
                start=_Position(start, line_numbers[start], column_numbers[start]),
                end=_Position(end, line_numbers[end], column_numbers[end]),
            )

    if fullparse and pos < len(text):
        line, col = line_numbers[pos], column_numbers[pos]
        position = _Position(pos, line, col)
        excerpt = _extract_excerpt(text, pos, col)
        raise PartialParseError(nodes, position, excerpt)

    return nodes


def _extract_excerpt(text, pos, col):
    if isinstance(text, bytes):
        return repr(text[max(0, pos - 1) : pos + 2])

    start = pos - (col - 1)
    match = _compile_re('\n').search(text, pos + 1)
    end = len(text) if match is None else match.start()

    if end - start < 96:
        return text[start : end] + _caret_at(col - 1)

    if col < 60:
        # Chop the line off at the end.
        return text[start : start + 90] + ' ...' + _caret_at(col - 1)

    elif end - pos < 40:
        # Chop the line off at the start.
        return '... ' + text[end - 90 : end] + _caret_at(pos - (end - 90) + 4)

    else:
        # Chop the line off at both ends.
        return '... ' + text[pos - 42 : pos + 42] + ' ...' + _caret_at(42 + 4)


def _caret_at(index):
    return '\n' + (' ' * index) + '^'


def _get_line_and_column(text, pos):
    line_numbers, column_numbers = _map_index_to_line_and_column(text)
    return line_numbers[pos], column_numbers[pos]


def _map_index_to_line_and_column(text):
    line_numbers = []
    column_numbers = []

    current_line = 1
    current_column = 0

    for c in text:
        if c == '\n':
            current_line += 1
            current_column = 0
        else:
            current_column += 1
        line_numbers.append(current_line)
        column_numbers.append(current_column)

    return line_numbers, column_numbers

matcher1 = _compile_re('[ \\t]+', flags=0).match
matcher2 = _compile_re('#[^\\r\\n]*', flags=0).match
matcher3 = _compile_re('[\\r\\n][\\s]*', flags=0).match
matcher4 = _compile_re('[_a-zA-Z][_a-zA-Z0-9]*', flags=0).match
matcher5 = _compile_re('(?s)[bB]?("""([^\\\\]|\\\\.)*?""")[iI]?', flags=0).match
matcher6 = _compile_re("(?s)[bB]?('''([^\\\\]|\\\\.)*?''')[iI]?", flags=0).match
matcher7 = _compile_re('[bB]?("([^"\\\\]|\\\\.)*")[iI]?', flags=0).match
matcher8 = _compile_re("[bB]?('([^'\\\\]|\\\\.)*')[iI]?", flags=0).match
matcher9 = _compile_re('[bB]?\\/([^\\/\\\\]|\\\\.)*\\/[iI]?', flags=0).match
matcher10 = _compile_re('(?s)```.*?```', flags=0).match
matcher11 = _compile_re('`.*?`', flags=0).match
matcher12 = _compile_re('\\d+', flags=0).match
matcher13 = _compile_re('0[xX]', flags=0).match
matcher14 = _compile_re('[0-9a-fA-F]{2}', flags=0).match

def _try_Space(_text, _pos):
    # Rule 'Space'
    # Begin Regex
    # /[ \\t]+/
    match1 = matcher1(_text, _pos)
    if match1:
        _result = match1.group(0)
        _pos = (yield (3, _try__ignored, match1.end()))[2]
        _status = True
    else:
        _result = _raise_error2
        _status = False
    # End Regex
    yield (_status, _result, _pos)

def _parse_Space(text, pos=0, fullparse=True):
    return _run(text, pos, _try_Space, fullparse)

Space = Rule('Space', _parse_Space, """
    Space = /[ \\t]+/
""")
def _raise_error2(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Space' rule, at the expression:\n"
    '    /[ \\\\t]+/\n\n'
    'Expected to match the regular expression /[ \\t]+/'
    )
    raise ParseError((title + details), _pos, line, col)

def _try_Comment(_text, _pos):
    # Rule 'Comment'
    # Begin Regex
    # /#[^\\r\\n]*/
    match2 = matcher2(_text, _pos)
    if match2:
        _result = match2.group(0)
        _pos = (yield (3, _try__ignored, match2.end()))[2]
        _status = True
    else:
        _result = _raise_error4
        _status = False
    # End Regex
    yield (_status, _result, _pos)

def _parse_Comment(text, pos=0, fullparse=True):
    return _run(text, pos, _try_Comment, fullparse)

Comment = Rule('Comment', _parse_Comment, """
    Comment = /#[^\\r\\n]*/
""")
def _raise_error4(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Comment' rule, at the expression:\n"
    '    /#[^\\\\r\\\\n]*/\n\n'
    'Expected to match the regular expression /#[^\\r\\n]*/'
    )
    raise ParseError((title + details), _pos, line, col)

def _try_Newline(_text, _pos):
    # Rule 'Newline'
    # Begin Regex
    # /[\\r\\n][\\s]*/
    match3 = matcher3(_text, _pos)
    if match3:
        _result = match3.group(0)
        _pos = (yield (3, _try__ignored, match3.end()))[2]
        _status = True
    else:
        _result = _raise_error6
        _status = False
    # End Regex
    yield (_status, _result, _pos)

def _parse_Newline(text, pos=0, fullparse=True):
    return _run(text, pos, _try_Newline, fullparse)

Newline = Rule('Newline', _parse_Newline, """
    Newline = /[\\r\\n][\\s]*/
""")
def _raise_error6(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Newline' rule, at the expression:\n"
    '    /[\\\\r\\\\n][\\\\s]*/\n\n'
    'Expected to match the regular expression /[\\r\\n][\\s]*/'
    )
    raise ParseError((title + details), _pos, line, col)

def _try_LineSep(_text, _pos):
    # Rule 'LineSep'
    # Begin List
    # (Newline | ';')+
    staging1 = []
    while True:
        checkpoint1 = _pos
        # Begin Choice
        farthest_err1 = _raise_error9
        backtrack1 = farthest_pos1 = _pos
        while True:
            # Option 1:
            # Begin Ref
            (_status, _result, _pos) = (yield (3, _try_Newline, _pos))
            # End Ref
            if _status:
                break
            if (farthest_pos1 < _pos):
                farthest_pos1 = _pos
                farthest_err1 = _result
            _pos = backtrack1
            # Option 2:
            # Begin Str
            value1 = ';'
            end1 = (_pos + 1)
            if (_text[slice(_pos, end1, None)] == value1):
                _result = value1
                _pos = (yield (3, _try__ignored, end1))[2]
                _status = True
            else:
                _result = _raise_error11
                _status = False
            # End Str
            if _status:
                break
            _pos = farthest_pos1
            _result = farthest_err1
            break
        # End Choice
        if not (_status):
            _pos = checkpoint1
            break
        staging1.append(_result)
    if staging1:
        _result = staging1
        _status = True
    # End List
    yield (_status, _result, _pos)

def _parse_LineSep(text, pos=0, fullparse=True):
    return _run(text, pos, _try_LineSep, fullparse)

LineSep = Rule('LineSep', _parse_LineSep, """
    LineSep = (Newline | ';')+
""")
def _raise_error9(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'LineSep' rule, at the expression:\n"
    "    Newline | ';'\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error11(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'LineSep' rule, at the expression:\n"
    "    ';'\n\n"
    "Expected to match the string ';'"
    )
    raise ParseError((title + details), _pos, line, col)

def _try_Name(_text, _pos):
    # Rule 'Name'
    # Begin Regex
    # /[_a-zA-Z][_a-zA-Z0-9]*/
    match4 = matcher4(_text, _pos)
    if match4:
        _result = match4.group(0)
        _pos = (yield (3, _try__ignored, match4.end()))[2]
        _status = True
    else:
        _result = _raise_error13
        _status = False
    # End Regex
    yield (_status, _result, _pos)

def _parse_Name(text, pos=0, fullparse=True):
    return _run(text, pos, _try_Name, fullparse)

Name = Rule('Name', _parse_Name, """
    Name = /[_a-zA-Z][_a-zA-Z0-9]*/
""")
def _raise_error13(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Name' rule, at the expression:\n"
    '    /[_a-zA-Z][_a-zA-Z0-9]*/\n\n'
    'Expected to match the regular expression /[_a-zA-Z][_a-zA-Z0-9]*/'
    )
    raise ParseError((title + details), _pos, line, col)

def _parse_function_17(_text, _pos):
    # Begin Str
    value2 = ','
    end2 = (_pos + 1)
    if (_text[slice(_pos, end2, None)] == value2):
        _result = value2
        _pos = (yield (3, _try__ignored, end2))[2]
        _status = True
    else:
        _result = _raise_error17
        _status = False
    # End Str
    yield (_status, _result, _pos)

def _try_Comma(_text, _pos):
    # Rule 'Comma'
    # Begin Call
    # wrap(',')
    arg1 = _wrap_string_literal(',', _parse_function_17)
    func1 = _ParseFunction(_try_wrap, (arg1,), ())
    (_status, _result, _pos) = (yield (3, func1, _pos))
    # End Call
    yield (_status, _result, _pos)

def _parse_Comma(text, pos=0, fullparse=True):
    return _run(text, pos, _try_Comma, fullparse)

Comma = Rule('Comma', _parse_Comma, """
    Comma = wrap(',')
""")
def _raise_error17(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Comma' rule, at the expression:\n"
    "    ','\n\n"
    "Expected to match the string ','"
    )
    raise ParseError((title + details), _pos, line, col)

def _try_wrap(_text, _pos, x):
    # Rule 'wrap'
    # Begin Discard
    # (Skip(Newline) >> x) << Skip(Newline)
    while True:
        # Begin Discard
        # Skip(Newline) >> x
        while True:
            # Begin Skip
            # Skip(Newline)
            while True:
                checkpoint2 = _pos
                # Begin Ref
                (_status, _result, _pos) = (yield (3, _try_Newline, _pos))
                # End Ref
                if _status:
                    continue
                else:
                    _pos = checkpoint2
                break
            _result = None
            _status = True
            # End Skip
            # Begin Ref
            (_status, _result, _pos) = (yield (3, x, _pos))
            # End Ref
            break
        # End Discard
        if not (_status):
            break
        staging2 = _result
        # Begin Skip
        # Skip(Newline)
        while True:
            checkpoint3 = _pos
            # Begin Ref
            (_status, _result, _pos) = (yield (3, _try_Newline, _pos))
            # End Ref
            if _status:
                continue
            else:
                _pos = checkpoint3
            break
        _result = None
        _status = True
        # End Skip
        _result = staging2
        break
    # End Discard
    yield (_status, _result, _pos)

def _parse_wrap(text, pos=0, fullparse=True):
    return _run(text, pos, _try_wrap, fullparse)

wrap = Rule('wrap', _parse_wrap, """
    wrap(x) = (Skip(Newline) >> x) << Skip(Newline)
""")
def _try_kw(_text, _pos, word):
    # Rule 'kw'
    # Begin Where
    # Name where `lambda x: x == word`
    # Begin Ref
    (_status, _result, _pos) = (yield (3, _try_Name, _pos))
    # End Ref
    if _status:
        arg2 = _result
        _result = lambda x: x == word
        _status = True
        if _result(arg2):
            _result = arg2
        else:
            _result = _raise_error27
            _status = False
    # End Where
    yield (_status, _result, _pos)

def _parse_kw(text, pos=0, fullparse=True):
    return _run(text, pos, _try_kw, fullparse)

kw = Rule('kw', _parse_kw, """
    kw(word) = Name where `lambda x: x == word`
""")
def _raise_error27(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'kw' rule, at the expression:\n"
    '    Name where `lambda x: x == word`\n\n'
    'Expected to satisfy the predicate: `lambda x: x == word`'
    )
    raise ParseError((title + details), _pos, line, col)

def _parse_function_35(_text, _pos):
    # Begin Str
    value3 = '('
    end3 = (_pos + 1)
    if (_text[slice(_pos, end3, None)] == value3):
        _result = value3
        _pos = (yield (3, _try__ignored, end3))[2]
        _status = True
    else:
        _result = _raise_error35
        _status = False
    # End Str
    yield (_status, _result, _pos)

def _try_Params(_text, _pos):
    # Rule 'Params'
    # Begin Discard
    # (wrap('(') >> (wrap(Name) /? Comma)) << ')'
    while True:
        # Begin Discard
        # wrap('(') >> (wrap(Name) /? Comma)
        while True:
            # Begin Call
            # wrap('(')
            arg3 = _wrap_string_literal('(', _parse_function_35)
            func2 = _ParseFunction(_try_wrap, (arg3,), ())
            (_status, _result, _pos) = (yield (3, func2, _pos))
            # End Call
            if not (_status):
                break
            # Begin Sep
            # wrap(Name) /? Comma
            staging3 = []
            checkpoint4 = _pos
            while True:
                # Begin Call
                # wrap(Name)
                func3 = _ParseFunction(_try_wrap, (_try_Name,), ())
                (_status, _result, _pos) = (yield (3, func3, _pos))
                # End Call
                if not (_status):
                    break
                staging3.append(_result)
                checkpoint4 = _pos
                # Begin Ref
                (_status, _result, _pos) = (yield (3, _try_Comma, _pos))
                # End Ref
                if not (_status):
                    break
                checkpoint4 = _pos
            _result = staging3
            _pos = checkpoint4
            _status = True
            # End Sep
            break
        # End Discard
        if not (_status):
            break
        staging4 = _result
        # Begin Str
        value4 = ')'
        end4 = (_pos + 1)
        if (_text[slice(_pos, end4, None)] == value4):
            _result = value4
            _pos = (yield (3, _try__ignored, end4))[2]
            _status = True
        else:
            _result = _raise_error41
            _status = False
        # End Str
        if _status:
            _result = staging4
        break
    # End Discard
    yield (_status, _result, _pos)

def _parse_Params(text, pos=0, fullparse=True):
    return _run(text, pos, _try_Params, fullparse)

Params = Rule('Params', _parse_Params, """
    Params = (wrap('(') >> (wrap(Name) /? Comma)) << ')'
""")
def _raise_error35(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Params' rule, at the expression:\n"
    "    '('\n\n"
    "Expected to match the string '('"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error41(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Params' rule, at the expression:\n"
    "    ')'\n\n"
    "Expected to match the string ')'"
    )
    raise ParseError((title + details), _pos, line, col)

def _parse_function_46(_text, _pos):
    # Begin Str
    value5 = 'ignored'
    end5 = (_pos + 7)
    if (_text[slice(_pos, end5, None)] == value5):
        _result = value5
        _pos = (yield (3, _try__ignored, end5))[2]
        _status = True
    else:
        _result = _raise_error46
        _status = False
    # End Str
    yield (_status, _result, _pos)

def _parse_function_49(_text, _pos):
    # Begin Str
    value6 = 'ignore'
    end6 = (_pos + 6)
    if (_text[slice(_pos, end6, None)] == value6):
        _result = value6
        _pos = (yield (3, _try__ignored, end6))[2]
        _status = True
    else:
        _result = _raise_error49
        _status = False
    # End Str
    yield (_status, _result, _pos)

def _try_IgnoreKeyword(_text, _pos):
    # Rule 'IgnoreKeyword'
    # Begin Choice
    farthest_err2 = _raise_error43
    backtrack2 = farthest_pos2 = _pos
    while True:
        # Option 1:
        # Begin Call
        # kw('ignored')
        arg4 = _wrap_string_literal('ignored', _parse_function_46)
        func4 = _ParseFunction(_try_kw, (arg4,), ())
        (_status, _result, _pos) = (yield (3, func4, _pos))
        # End Call
        if _status:
            break
        if (farthest_pos2 < _pos):
            farthest_pos2 = _pos
            farthest_err2 = _result
        _pos = backtrack2
        # Option 2:
        # Begin Call
        # kw('ignore')
        arg5 = _wrap_string_literal('ignore', _parse_function_49)
        func5 = _ParseFunction(_try_kw, (arg5,), ())
        (_status, _result, _pos) = (yield (3, func5, _pos))
        # End Call
        if _status:
            break
        if (farthest_pos2 < _pos):
            farthest_pos2 = _pos
            farthest_err2 = _result
        _pos = farthest_pos2
        _result = farthest_err2
        break
    # End Choice
    yield (_status, _result, _pos)

def _parse_IgnoreKeyword(text, pos=0, fullparse=True):
    return _run(text, pos, _try_IgnoreKeyword, fullparse)

IgnoreKeyword = Rule('IgnoreKeyword', _parse_IgnoreKeyword, """
    IgnoreKeyword = kw('ignored') | kw('ignore')
""")
def _raise_error43(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'IgnoreKeyword' rule, at the expression:\n"
    "    kw('ignored') | kw('ignore')\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error46(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'IgnoreKeyword' rule, at the expression:\n"
    "    'ignored'\n\n"
    "Expected to match the string 'ignored'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error49(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'IgnoreKeyword' rule, at the expression:\n"
    "    'ignore'\n\n"
    "Expected to match the string 'ignore'"
    )
    raise ParseError((title + details), _pos, line, col)

class StringLiteral(Node):
    """
    class StringLiteral {
        value: /(?s)[bB]?(\"\"\"([^\\\\\\\\]|\\\\\\\\.)*?\"\"\")[iI]?/ | /(?s)[bB]?('''([^\\\\\\\\]|\\\\\\\\.)*?''')[iI]?/ | /[bB]?("([^"\\\\\\\\]|\\\\\\\\.)*")[iI]?/ | /[bB]?('([^'\\\\\\\\]|\\\\\\\\.)*')[iI]?/
    }
    """
    _fields = ('value',)

    def __init__(self, value):
        Node.__init__(self)
        self.value = value

    def __repr__(self):
        return f'StringLiteral(value={self.value!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_StringLiteral, fullparse)


def _try_StringLiteral(_text, _pos):
    # Begin Seq
    start_pos1 = _pos
    while True:
        # Begin Choice
        farthest_err3 = _raise_error53
        farthest_pos3 = _pos
        while True:
            # Option 1:
            # Begin Regex
            # /(?s)[bB]?("""([^\\\\]|\\\\.)*?""")[iI]?/
            match5 = matcher5(_text, _pos)
            if match5:
                _result = match5.group(0)
                _pos = (yield (3, _try__ignored, match5.end()))[2]
                _status = True
            else:
                _result = _raise_error54
                _status = False
            # End Regex
            if _status:
                break
            # Option 2:
            # Begin Regex
            # /(?s)[bB]?('''([^\\\\]|\\\\.)*?''')[iI]?/
            match6 = matcher6(_text, _pos)
            if match6:
                _result = match6.group(0)
                _pos = (yield (3, _try__ignored, match6.end()))[2]
                _status = True
            else:
                _result = _raise_error55
                _status = False
            # End Regex
            if _status:
                break
            # Option 3:
            # Begin Regex
            # /[bB]?("([^"\\\\]|\\\\.)*")[iI]?/
            match7 = matcher7(_text, _pos)
            if match7:
                _result = match7.group(0)
                _pos = (yield (3, _try__ignored, match7.end()))[2]
                _status = True
            else:
                _result = _raise_error56
                _status = False
            # End Regex
            if _status:
                break
            # Option 4:
            # Begin Regex
            # /[bB]?('([^'\\\\]|\\\\.)*')[iI]?/
            match8 = matcher8(_text, _pos)
            if match8:
                _result = match8.group(0)
                _pos = (yield (3, _try__ignored, match8.end()))[2]
                _status = True
            else:
                _result = _raise_error57
                _status = False
            # End Regex
            if _status:
                break
            _pos = farthest_pos3
            _result = farthest_err3
            break
        # End Choice
        if not (_status):
            break
        value = _result
        _result = StringLiteral(value)
        _result._metadata.position_info = (start_pos1, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _raise_error53(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'StringLiteral' rule, at the expression:\n"
    '    /(?s)[bB]?("""([^\\\\\\\\]|\\\\\\\\.)*?""")[iI]?/ | /(?s)[bB]?(\'\'\'([^\\\\\\\\]|\\\\\\\\.)*?\'\'\')[iI]?/ | /[bB]?("([^"\\\\\\\\]|\\\\\\\\.)*")[iI]?/ | /[bB]?(\'([^\'\\\\\\\\]|\\\\\\\\.)*\')[iI]?/\n\n'
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error54(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'StringLiteral' rule, at the expression:\n"
    '    /(?s)[bB]?("""([^\\\\\\\\]|\\\\\\\\.)*?""")[iI]?/\n\n'
    'Expected to match the regular expression /(?s)[bB]?("""([^\\\\]|\\\\.)*?""")[iI]?/'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error55(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'StringLiteral' rule, at the expression:\n"
    "    /(?s)[bB]?('''([^\\\\\\\\]|\\\\\\\\.)*?''')[iI]?/\n\n"
    "Expected to match the regular expression /(?s)[bB]?('''([^\\\\]|\\\\.)*?''')[iI]?/"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error56(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'StringLiteral' rule, at the expression:\n"
    '    /[bB]?("([^"\\\\\\\\]|\\\\\\\\.)*")[iI]?/\n\n'
    'Expected to match the regular expression /[bB]?("([^"\\\\]|\\\\.)*")[iI]?/'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error57(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'StringLiteral' rule, at the expression:\n"
    "    /[bB]?('([^'\\\\\\\\]|\\\\\\\\.)*')[iI]?/\n\n"
    "Expected to match the regular expression /[bB]?('([^'\\\\]|\\\\.)*')[iI]?/"
    )
    raise ParseError((title + details), _pos, line, col)

class RegexLiteral(Node):
    """
    class RegexLiteral {
        value: /[bB]?\\\\/([^\\\\/\\\\\\\\]|\\\\\\\\.)*\\\\/[iI]?/
    }
    """
    _fields = ('value',)

    def __init__(self, value):
        Node.__init__(self)
        self.value = value

    def __repr__(self):
        return f'RegexLiteral(value={self.value!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_RegexLiteral, fullparse)


def _try_RegexLiteral(_text, _pos):
    # Begin Seq
    start_pos2 = _pos
    while True:
        # Begin Regex
        # /[bB]?\\/([^\\/\\\\]|\\\\.)*\\/[iI]?/
        match9 = matcher9(_text, _pos)
        if match9:
            _result = match9.group(0)
            _pos = (yield (3, _try__ignored, match9.end()))[2]
            _status = True
        else:
            _result = _raise_error61
            _status = False
        # End Regex
        if not (_status):
            break
        value = _result
        _result = RegexLiteral(value)
        _result._metadata.position_info = (start_pos2, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _raise_error61(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'RegexLiteral' rule, at the expression:\n"
    '    /[bB]?\\\\/([^\\\\/\\\\\\\\]|\\\\\\\\.)*\\\\/[iI]?/\n\n'
    'Expected to match the regular expression /[bB]?\\/([^\\/\\\\]|\\\\.)*\\/[iI]?/'
    )
    raise ParseError((title + details), _pos, line, col)

class PythonSection(Node):
    """
    class PythonSection {
        value: /(?s)```.*?```/ |> `lambda x: textwrap.dedent(x[3:-3])`
    }
    """
    _fields = ('value',)

    def __init__(self, value):
        Node.__init__(self)
        self.value = value

    def __repr__(self):
        return f'PythonSection(value={self.value!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_PythonSection, fullparse)


def _try_PythonSection(_text, _pos):
    # Begin Seq
    start_pos3 = _pos
    while True:
        # Begin Apply
        # /(?s)```.*?```/ |> `lambda x: textwrap.dedent(x[3:-3])`
        # Begin Regex
        # /(?s)```.*?```/
        match10 = matcher10(_text, _pos)
        if match10:
            _result = match10.group(0)
            _pos = (yield (3, _try__ignored, match10.end()))[2]
            _status = True
        else:
            _result = _raise_error66
            _status = False
        # End Regex
        if _status:
            arg6 = _result
            _result = lambda x: textwrap.dedent(x[3:-3])
            _status = True
            _result = _result(arg6)
        # End Apply
        if not (_status):
            break
        value = _result
        _result = PythonSection(value)
        _result._metadata.position_info = (start_pos3, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _raise_error66(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'PythonSection' rule, at the expression:\n"
    '    /(?s)```.*?```/\n\n'
    'Expected to match the regular expression /(?s)```.*?```/'
    )
    raise ParseError((title + details), _pos, line, col)

class PythonExpression(Node):
    """
    class PythonExpression {
        value: /`.*?`/ |> `lambda x: x[1:-1]` | /\\\\d+/ | 'True' | 'False' | 'None'
    }
    """
    _fields = ('value',)

    def __init__(self, value):
        Node.__init__(self)
        self.value = value

    def __repr__(self):
        return f'PythonExpression(value={self.value!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_PythonExpression, fullparse)


def _try_PythonExpression(_text, _pos):
    # Begin Seq
    start_pos4 = _pos
    while True:
        # Begin Choice
        farthest_err4 = _raise_error71
        backtrack3 = farthest_pos4 = _pos
        while True:
            # Option 1:
            # Begin Apply
            # /`.*?`/ |> `lambda x: x[1:-1]`
            # Begin Regex
            # /`.*?`/
            match11 = matcher11(_text, _pos)
            if match11:
                _result = match11.group(0)
                _pos = (yield (3, _try__ignored, match11.end()))[2]
                _status = True
            else:
                _result = _raise_error73
                _status = False
            # End Regex
            if _status:
                arg7 = _result
                _result = lambda x: x[1:-1]
                _status = True
                _result = _result(arg7)
            # End Apply
            if _status:
                break
            if (farthest_pos4 < _pos):
                farthest_pos4 = _pos
                farthest_err4 = _result
            _pos = backtrack3
            # Option 2:
            # Begin Regex
            # /\\d+/
            match12 = matcher12(_text, _pos)
            if match12:
                _result = match12.group(0)
                _pos = (yield (3, _try__ignored, match12.end()))[2]
                _status = True
            else:
                _result = _raise_error75
                _status = False
            # End Regex
            if _status:
                break
            # Option 3:
            # Begin Str
            value7 = 'True'
            end7 = (_pos + 4)
            if (_text[slice(_pos, end7, None)] == value7):
                _result = value7
                _pos = (yield (3, _try__ignored, end7))[2]
                _status = True
            else:
                _result = _raise_error76
                _status = False
            # End Str
            if _status:
                break
            # Option 4:
            # Begin Str
            value8 = 'False'
            end8 = (_pos + 5)
            if (_text[slice(_pos, end8, None)] == value8):
                _result = value8
                _pos = (yield (3, _try__ignored, end8))[2]
                _status = True
            else:
                _result = _raise_error77
                _status = False
            # End Str
            if _status:
                break
            # Option 5:
            # Begin Str
            value9 = 'None'
            end9 = (_pos + 4)
            if (_text[slice(_pos, end9, None)] == value9):
                _result = value9
                _pos = (yield (3, _try__ignored, end9))[2]
                _status = True
            else:
                _result = _raise_error78
                _status = False
            # End Str
            if _status:
                break
            _pos = farthest_pos4
            _result = farthest_err4
            break
        # End Choice
        if not (_status):
            break
        value = _result
        _result = PythonExpression(value)
        _result._metadata.position_info = (start_pos4, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _raise_error71(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'PythonExpression' rule, at the expression:\n"
    "    /`.*?`/ |> `lambda x: x[1:-1]` | /\\\\d+/ | 'True' | 'False' | 'None'\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error73(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'PythonExpression' rule, at the expression:\n"
    '    /`.*?`/\n\n'
    'Expected to match the regular expression /`.*?`/'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error75(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'PythonExpression' rule, at the expression:\n"
    '    /\\\\d+/\n\n'
    'Expected to match the regular expression /\\d+/'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error76(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'PythonExpression' rule, at the expression:\n"
    "    'True'\n\n"
    "Expected to match the string 'True'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error77(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'PythonExpression' rule, at the expression:\n"
    "    'False'\n\n"
    "Expected to match the string 'False'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error78(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'PythonExpression' rule, at the expression:\n"
    "    'None'\n\n"
    "Expected to match the string 'None'"
    )
    raise ParseError((title + details), _pos, line, col)

class RuleDef(Node):
    """
    class RuleDef {
        is_ignored: Opt(IgnoreKeyword) |> `bool`
        name: Name
        params: Opt(Params) << wrap('=>' | '=' | ':')
        expr: Expr
    }
    """
    _fields = ('is_ignored', 'name', 'params', 'expr')

    def __init__(self, is_ignored, name, params, expr):
        Node.__init__(self)
        self.is_ignored = is_ignored
        self.name = name
        self.params = params
        self.expr = expr

    def __repr__(self):
        return f'RuleDef(is_ignored={self.is_ignored!r}, name={self.name!r}, params={self.params!r}, expr={self.expr!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_RuleDef, fullparse)


def _parse_function_94(_text, _pos):
    # Begin Choice
    farthest_err5 = _raise_error94
    farthest_pos5 = _pos
    while True:
        # Option 1:
        # Begin Str
        value10 = '=>'
        end10 = (_pos + 2)
        if (_text[slice(_pos, end10, None)] == value10):
            _result = value10
            _pos = (yield (3, _try__ignored, end10))[2]
            _status = True
        else:
            _result = _raise_error95
            _status = False
        # End Str
        if _status:
            break
        # Option 2:
        # Begin Str
        value11 = '='
        end11 = (_pos + 1)
        if (_text[slice(_pos, end11, None)] == value11):
            _result = value11
            _pos = (yield (3, _try__ignored, end11))[2]
            _status = True
        else:
            _result = _raise_error96
            _status = False
        # End Str
        if _status:
            break
        # Option 3:
        # Begin Str
        value12 = ':'
        end12 = (_pos + 1)
        if (_text[slice(_pos, end12, None)] == value12):
            _result = value12
            _pos = (yield (3, _try__ignored, end12))[2]
            _status = True
        else:
            _result = _raise_error97
            _status = False
        # End Str
        if _status:
            break
        _pos = farthest_pos5
        _result = farthest_err5
        break
    # End Choice
    yield (_status, _result, _pos)

def _try_RuleDef(_text, _pos):
    # Begin Seq
    start_pos5 = _pos
    while True:
        # Begin Apply
        # Opt(IgnoreKeyword) |> `bool`
        # Begin Opt
        # Opt(IgnoreKeyword)
        backtrack4 = _pos
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_IgnoreKeyword, _pos))
        # End Ref
        if not (_status):
            _pos = backtrack4
            _result = None
            _status = True
        # End Opt
        arg8 = _result
        _result = bool
        _status = True
        _result = _result(arg8)
        # End Apply
        is_ignored = _result
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Name, _pos))
        # End Ref
        if not (_status):
            break
        name = _result
        # Begin Discard
        # Opt(Params) << wrap('=>' | '=' | ':')
        while True:
            # Begin Opt
            # Opt(Params)
            backtrack5 = _pos
            # Begin Ref
            (_status, _result, _pos) = (yield (3, _try_Params, _pos))
            # End Ref
            if not (_status):
                _pos = backtrack5
                _result = None
                _status = True
            # End Opt
            staging5 = _result
            # Begin Call
            # wrap('=>' | '=' | ':')
            func6 = _ParseFunction(_try_wrap, (_parse_function_94,), ())
            (_status, _result, _pos) = (yield (3, func6, _pos))
            # End Call
            if _status:
                _result = staging5
            break
        # End Discard
        if not (_status):
            break
        params = _result
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Expr, _pos))
        # End Ref
        if not (_status):
            break
        expr = _result
        _result = RuleDef(is_ignored, name, params, expr)
        _result._metadata.position_info = (start_pos5, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _raise_error94(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'RuleDef' rule, at the expression:\n"
    "    '=>' | '=' | ':'\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error95(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'RuleDef' rule, at the expression:\n"
    "    '=>'\n\n"
    "Expected to match the string '=>'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error96(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'RuleDef' rule, at the expression:\n"
    "    '='\n\n"
    "Expected to match the string '='"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error97(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'RuleDef' rule, at the expression:\n"
    "    ':'\n\n"
    "Expected to match the string ':'"
    )
    raise ParseError((title + details), _pos, line, col)

class ClassDef(Node):
    """
    class ClassDef {
        name: kw('class') >> Name
        params: Opt(Params)
        members: (wrap('{') >> (ClassMember /? LineSep)) << '}'
    }
    """
    _fields = ('name', 'params', 'members')

    def __init__(self, name, params, members):
        Node.__init__(self)
        self.name = name
        self.params = params
        self.members = members

    def __repr__(self):
        return f'ClassDef(name={self.name!r}, params={self.params!r}, members={self.members!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_ClassDef, fullparse)


def _parse_function_106(_text, _pos):
    # Begin Str
    value13 = 'class'
    end13 = (_pos + 5)
    if (_text[slice(_pos, end13, None)] == value13):
        _result = value13
        _pos = (yield (3, _try__ignored, end13))[2]
        _status = True
    else:
        _result = _raise_error106
        _status = False
    # End Str
    yield (_status, _result, _pos)

def _parse_function_116(_text, _pos):
    # Begin Str
    value14 = '{'
    end14 = (_pos + 1)
    if (_text[slice(_pos, end14, None)] == value14):
        _result = value14
        _pos = (yield (3, _try__ignored, end14))[2]
        _status = True
    else:
        _result = _raise_error116
        _status = False
    # End Str
    yield (_status, _result, _pos)

def _try_ClassDef(_text, _pos):
    # Begin Seq
    start_pos6 = _pos
    while True:
        # Begin Discard
        # kw('class') >> Name
        while True:
            # Begin Call
            # kw('class')
            arg9 = _wrap_string_literal('class', _parse_function_106)
            func7 = _ParseFunction(_try_kw, (arg9,), ())
            (_status, _result, _pos) = (yield (3, func7, _pos))
            # End Call
            if not (_status):
                break
            # Begin Ref
            (_status, _result, _pos) = (yield (3, _try_Name, _pos))
            # End Ref
            break
        # End Discard
        if not (_status):
            break
        name = _result
        # Begin Opt
        # Opt(Params)
        backtrack6 = _pos
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Params, _pos))
        # End Ref
        if not (_status):
            _pos = backtrack6
            _result = None
            _status = True
        # End Opt
        params = _result
        # Begin Discard
        # (wrap('{') >> (ClassMember /? LineSep)) << '}'
        while True:
            # Begin Discard
            # wrap('{') >> (ClassMember /? LineSep)
            while True:
                # Begin Call
                # wrap('{')
                arg10 = _wrap_string_literal('{', _parse_function_116)
                func8 = _ParseFunction(_try_wrap, (arg10,), ())
                (_status, _result, _pos) = (yield (3, func8, _pos))
                # End Call
                if not (_status):
                    break
                # Begin Sep
                # ClassMember /? LineSep
                staging6 = []
                checkpoint5 = _pos
                while True:
                    # Begin Ref
                    (_status, _result, _pos) = (yield (3, _try_ClassMember, _pos))
                    # End Ref
                    if not (_status):
                        break
                    staging6.append(_result)
                    checkpoint5 = _pos
                    # Begin Ref
                    (_status, _result, _pos) = (yield (3, _try_LineSep, _pos))
                    # End Ref
                    if not (_status):
                        break
                    checkpoint5 = _pos
                _result = staging6
                _pos = checkpoint5
                _status = True
                # End Sep
                break
            # End Discard
            if not (_status):
                break
            staging7 = _result
            # Begin Str
            value15 = '}'
            end15 = (_pos + 1)
            if (_text[slice(_pos, end15, None)] == value15):
                _result = value15
                _pos = (yield (3, _try__ignored, end15))[2]
                _status = True
            else:
                _result = _raise_error120
                _status = False
            # End Str
            if _status:
                _result = staging7
            break
        # End Discard
        if not (_status):
            break
        members = _result
        _result = ClassDef(name, params, members)
        _result._metadata.position_info = (start_pos6, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _raise_error106(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ClassDef' rule, at the expression:\n"
    "    'class'\n\n"
    "Expected to match the string 'class'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error116(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ClassDef' rule, at the expression:\n"
    "    '{'\n\n"
    "Expected to match the string '{'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error120(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ClassDef' rule, at the expression:\n"
    "    '}'\n\n"
    "Expected to match the string '}'"
    )
    raise ParseError((title + details), _pos, line, col)

class ClassMember(Node):
    """
    class ClassMember {
        is_omitted: Opt('let') |> `bool`
        name: Name
        params: Opt(Params) << wrap('=>' | '=' | ':')
        expr: Expr
    }
    """
    _fields = ('is_omitted', 'name', 'params', 'expr')

    def __init__(self, is_omitted, name, params, expr):
        Node.__init__(self)
        self.is_omitted = is_omitted
        self.name = name
        self.params = params
        self.expr = expr

    def __repr__(self):
        return f'ClassMember(is_omitted={self.is_omitted!r}, name={self.name!r}, params={self.params!r}, expr={self.expr!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_ClassMember, fullparse)


def _parse_function_136(_text, _pos):
    # Begin Choice
    farthest_err6 = _raise_error136
    farthest_pos6 = _pos
    while True:
        # Option 1:
        # Begin Str
        value17 = '=>'
        end17 = (_pos + 2)
        if (_text[slice(_pos, end17, None)] == value17):
            _result = value17
            _pos = (yield (3, _try__ignored, end17))[2]
            _status = True
        else:
            _result = _raise_error137
            _status = False
        # End Str
        if _status:
            break
        # Option 2:
        # Begin Str
        value18 = '='
        end18 = (_pos + 1)
        if (_text[slice(_pos, end18, None)] == value18):
            _result = value18
            _pos = (yield (3, _try__ignored, end18))[2]
            _status = True
        else:
            _result = _raise_error138
            _status = False
        # End Str
        if _status:
            break
        # Option 3:
        # Begin Str
        value19 = ':'
        end19 = (_pos + 1)
        if (_text[slice(_pos, end19, None)] == value19):
            _result = value19
            _pos = (yield (3, _try__ignored, end19))[2]
            _status = True
        else:
            _result = _raise_error139
            _status = False
        # End Str
        if _status:
            break
        _pos = farthest_pos6
        _result = farthest_err6
        break
    # End Choice
    yield (_status, _result, _pos)

def _try_ClassMember(_text, _pos):
    # Begin Seq
    start_pos7 = _pos
    while True:
        # Begin Apply
        # Opt('let') |> `bool`
        # Begin Opt
        # Opt('let')
        backtrack7 = _pos
        # Begin Str
        value16 = 'let'
        end16 = (_pos + 3)
        if (_text[slice(_pos, end16, None)] == value16):
            _result = value16
            _pos = (yield (3, _try__ignored, end16))[2]
            _status = True
        else:
            _result = _raise_error126
            _status = False
        # End Str
        if not (_status):
            _pos = backtrack7
            _result = None
            _status = True
        # End Opt
        arg11 = _result
        _result = bool
        _status = True
        _result = _result(arg11)
        # End Apply
        is_omitted = _result
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Name, _pos))
        # End Ref
        if not (_status):
            break
        name = _result
        # Begin Discard
        # Opt(Params) << wrap('=>' | '=' | ':')
        while True:
            # Begin Opt
            # Opt(Params)
            backtrack8 = _pos
            # Begin Ref
            (_status, _result, _pos) = (yield (3, _try_Params, _pos))
            # End Ref
            if not (_status):
                _pos = backtrack8
                _result = None
                _status = True
            # End Opt
            staging8 = _result
            # Begin Call
            # wrap('=>' | '=' | ':')
            func9 = _ParseFunction(_try_wrap, (_parse_function_136,), ())
            (_status, _result, _pos) = (yield (3, func9, _pos))
            # End Call
            if _status:
                _result = staging8
            break
        # End Discard
        if not (_status):
            break
        params = _result
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Expr, _pos))
        # End Ref
        if not (_status):
            break
        expr = _result
        _result = ClassMember(is_omitted, name, params, expr)
        _result._metadata.position_info = (start_pos7, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _raise_error126(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ClassMember' rule, at the expression:\n"
    "    'let'\n\n"
    "Expected to match the string 'let'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error136(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ClassMember' rule, at the expression:\n"
    "    '=>' | '=' | ':'\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error137(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ClassMember' rule, at the expression:\n"
    "    '=>'\n\n"
    "Expected to match the string '=>'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error138(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ClassMember' rule, at the expression:\n"
    "    '='\n\n"
    "Expected to match the string '='"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error139(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ClassMember' rule, at the expression:\n"
    "    ':'\n\n"
    "Expected to match the string ':'"
    )
    raise ParseError((title + details), _pos, line, col)

class IgnoreStmt(Node):
    """
    class IgnoreStmt {
        expr: IgnoreKeyword >> Expr
    }
    """
    _fields = ('expr',)

    def __init__(self, expr):
        Node.__init__(self)
        self.expr = expr

    def __repr__(self):
        return f'IgnoreStmt(expr={self.expr!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_IgnoreStmt, fullparse)


def _try_IgnoreStmt(_text, _pos):
    # Begin Seq
    start_pos8 = _pos
    while True:
        # Begin Discard
        # IgnoreKeyword >> Expr
        while True:
            # Begin Ref
            (_status, _result, _pos) = (yield (3, _try_IgnoreKeyword, _pos))
            # End Ref
            if not (_status):
                break
            # Begin Ref
            (_status, _result, _pos) = (yield (3, _try_Expr, _pos))
            # End Ref
            break
        # End Discard
        if not (_status):
            break
        expr = _result
        _result = IgnoreStmt(expr)
        _result._metadata.position_info = (start_pos8, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _try_Stmt(_text, _pos):
    # Rule 'Stmt'
    # Begin Choice
    farthest_err7 = _raise_error149
    backtrack9 = farthest_pos7 = _pos
    while True:
        # Option 1:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_ClassDef, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos7 < _pos):
            farthest_pos7 = _pos
            farthest_err7 = _result
        _pos = backtrack9
        # Option 2:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_RuleDef, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos7 < _pos):
            farthest_pos7 = _pos
            farthest_err7 = _result
        _pos = backtrack9
        # Option 3:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_IgnoreStmt, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos7 < _pos):
            farthest_pos7 = _pos
            farthest_err7 = _result
        _pos = backtrack9
        # Option 4:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_PythonSection, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos7 < _pos):
            farthest_pos7 = _pos
            farthest_err7 = _result
        _pos = backtrack9
        # Option 5:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_PythonExpression, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos7 < _pos):
            farthest_pos7 = _pos
            farthest_err7 = _result
        _pos = farthest_pos7
        _result = farthest_err7
        break
    # End Choice
    yield (_status, _result, _pos)

def _parse_Stmt(text, pos=0, fullparse=True):
    return _run(text, pos, _try_Stmt, fullparse)

Stmt = Rule('Stmt', _parse_Stmt, """
    Stmt = ClassDef | RuleDef | IgnoreStmt | PythonSection | PythonExpression
""")
def _raise_error149(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Stmt' rule, at the expression:\n"
    '    ClassDef | RuleDef | IgnoreStmt | PythonSection | PythonExpression\n\n'
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

class LetExpression(Node):
    """
    class LetExpression {
        name: (kw('let') >> Name) << wrap('=>' | '=' | ':')
        expr: Expr << wrap(kw('in'))
        body: Expr
    }
    """
    _fields = ('name', 'expr', 'body')

    def __init__(self, name, expr, body):
        Node.__init__(self)
        self.name = name
        self.expr = expr
        self.body = body

    def __repr__(self):
        return f'LetExpression(name={self.name!r}, expr={self.expr!r}, body={self.body!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_LetExpression, fullparse)


def _parse_function_162(_text, _pos):
    # Begin Str
    value20 = 'let'
    end20 = (_pos + 3)
    if (_text[slice(_pos, end20, None)] == value20):
        _result = value20
        _pos = (yield (3, _try__ignored, end20))[2]
        _status = True
    else:
        _result = _raise_error162
        _status = False
    # End Str
    yield (_status, _result, _pos)

def _parse_function_166(_text, _pos):
    # Begin Choice
    farthest_err8 = _raise_error166
    farthest_pos8 = _pos
    while True:
        # Option 1:
        # Begin Str
        value21 = '=>'
        end21 = (_pos + 2)
        if (_text[slice(_pos, end21, None)] == value21):
            _result = value21
            _pos = (yield (3, _try__ignored, end21))[2]
            _status = True
        else:
            _result = _raise_error167
            _status = False
        # End Str
        if _status:
            break
        # Option 2:
        # Begin Str
        value22 = '='
        end22 = (_pos + 1)
        if (_text[slice(_pos, end22, None)] == value22):
            _result = value22
            _pos = (yield (3, _try__ignored, end22))[2]
            _status = True
        else:
            _result = _raise_error168
            _status = False
        # End Str
        if _status:
            break
        # Option 3:
        # Begin Str
        value23 = ':'
        end23 = (_pos + 1)
        if (_text[slice(_pos, end23, None)] == value23):
            _result = value23
            _pos = (yield (3, _try__ignored, end23))[2]
            _status = True
        else:
            _result = _raise_error169
            _status = False
        # End Str
        if _status:
            break
        _pos = farthest_pos8
        _result = farthest_err8
        break
    # End Choice
    yield (_status, _result, _pos)

def _parse_function_177(_text, _pos):
    # Begin Str
    value24 = 'in'
    end24 = (_pos + 2)
    if (_text[slice(_pos, end24, None)] == value24):
        _result = value24
        _pos = (yield (3, _try__ignored, end24))[2]
        _status = True
    else:
        _result = _raise_error177
        _status = False
    # End Str
    yield (_status, _result, _pos)

def _parse_function_175(_text, _pos):
    # Begin Call
    # kw('in')
    arg13 = _wrap_string_literal('in', _parse_function_177)
    func12 = _ParseFunction(_try_kw, (arg13,), ())
    (_status, _result, _pos) = (yield (3, func12, _pos))
    # End Call
    yield (_status, _result, _pos)

def _try_LetExpression(_text, _pos):
    # Begin Seq
    start_pos9 = _pos
    while True:
        # Begin Discard
        # (kw('let') >> Name) << wrap('=>' | '=' | ':')
        while True:
            # Begin Discard
            # kw('let') >> Name
            while True:
                # Begin Call
                # kw('let')
                arg12 = _wrap_string_literal('let', _parse_function_162)
                func10 = _ParseFunction(_try_kw, (arg12,), ())
                (_status, _result, _pos) = (yield (3, func10, _pos))
                # End Call
                if not (_status):
                    break
                # Begin Ref
                (_status, _result, _pos) = (yield (3, _try_Name, _pos))
                # End Ref
                break
            # End Discard
            if not (_status):
                break
            staging9 = _result
            # Begin Call
            # wrap('=>' | '=' | ':')
            func11 = _ParseFunction(_try_wrap, (_parse_function_166,), ())
            (_status, _result, _pos) = (yield (3, func11, _pos))
            # End Call
            if _status:
                _result = staging9
            break
        # End Discard
        if not (_status):
            break
        name = _result
        # Begin Discard
        # Expr << wrap(kw('in'))
        while True:
            # Begin Ref
            (_status, _result, _pos) = (yield (3, _try_Expr, _pos))
            # End Ref
            if not (_status):
                break
            staging10 = _result
            # Begin Call
            # wrap(kw('in'))
            func13 = _ParseFunction(_try_wrap, (_parse_function_175,), ())
            (_status, _result, _pos) = (yield (3, func13, _pos))
            # End Call
            if _status:
                _result = staging10
            break
        # End Discard
        if not (_status):
            break
        expr = _result
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Expr, _pos))
        # End Ref
        if not (_status):
            break
        body = _result
        _result = LetExpression(name, expr, body)
        _result._metadata.position_info = (start_pos9, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _raise_error162(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'LetExpression' rule, at the expression:\n"
    "    'let'\n\n"
    "Expected to match the string 'let'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error166(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'LetExpression' rule, at the expression:\n"
    "    '=>' | '=' | ':'\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error167(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'LetExpression' rule, at the expression:\n"
    "    '=>'\n\n"
    "Expected to match the string '=>'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error168(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'LetExpression' rule, at the expression:\n"
    "    '='\n\n"
    "Expected to match the string '='"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error169(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'LetExpression' rule, at the expression:\n"
    "    ':'\n\n"
    "Expected to match the string ':'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error177(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'LetExpression' rule, at the expression:\n"
    "    'in'\n\n"
    "Expected to match the string 'in'"
    )
    raise ParseError((title + details), _pos, line, col)

class Ref(Node):
    """
    class Ref {
        value: Name
    }
    """
    _fields = ('value',)

    def __init__(self, value):
        Node.__init__(self)
        self.value = value

    def __repr__(self):
        return f'Ref(value={self.value!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_Ref, fullparse)


def _try_Ref(_text, _pos):
    # Begin Seq
    start_pos10 = _pos
    while True:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Name, _pos))
        # End Ref
        if not (_status):
            break
        value = _result
        _result = Ref(value)
        _result._metadata.position_info = (start_pos10, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

class ListLiteral(Node):
    """
    class ListLiteral {
        elements: ('[' >> (wrap(Expr) /? Comma)) << ']'
    }
    """
    _fields = ('elements',)

    def __init__(self, elements):
        Node.__init__(self)
        self.elements = elements

    def __repr__(self):
        return f'ListLiteral(elements={self.elements!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_ListLiteral, fullparse)


def _try_ListLiteral(_text, _pos):
    # Begin Seq
    start_pos11 = _pos
    while True:
        # Begin Discard
        # ('[' >> (wrap(Expr) /? Comma)) << ']'
        while True:
            # Begin Discard
            # '[' >> (wrap(Expr) /? Comma)
            while True:
                # Begin Str
                value25 = '['
                end25 = (_pos + 1)
                if (_text[slice(_pos, end25, None)] == value25):
                    _result = value25
                    _pos = (yield (3, _try__ignored, end25))[2]
                    _status = True
                else:
                    _result = _raise_error189
                    _status = False
                # End Str
                if not (_status):
                    break
                # Begin Sep
                # wrap(Expr) /? Comma
                staging11 = []
                checkpoint6 = _pos
                while True:
                    # Begin Call
                    # wrap(Expr)
                    func14 = _ParseFunction(_try_wrap, (_try_Expr,), ())
                    (_status, _result, _pos) = (yield (3, func14, _pos))
                    # End Call
                    if not (_status):
                        break
                    staging11.append(_result)
                    checkpoint6 = _pos
                    # Begin Ref
                    (_status, _result, _pos) = (yield (3, _try_Comma, _pos))
                    # End Ref
                    if not (_status):
                        break
                    checkpoint6 = _pos
                _result = staging11
                _pos = checkpoint6
                _status = True
                # End Sep
                break
            # End Discard
            if not (_status):
                break
            staging12 = _result
            # Begin Str
            value26 = ']'
            end26 = (_pos + 1)
            if (_text[slice(_pos, end26, None)] == value26):
                _result = value26
                _pos = (yield (3, _try__ignored, end26))[2]
                _status = True
            else:
                _result = _raise_error195
                _status = False
            # End Str
            if _status:
                _result = staging12
            break
        # End Discard
        if not (_status):
            break
        elements = _result
        _result = ListLiteral(elements)
        _result._metadata.position_info = (start_pos11, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _raise_error189(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ListLiteral' rule, at the expression:\n"
    "    '['\n\n"
    "Expected to match the string '['"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error195(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ListLiteral' rule, at the expression:\n"
    "    ']'\n\n"
    "Expected to match the string ']'"
    )
    raise ParseError((title + details), _pos, line, col)

class ByteLiteral(Node):
    """
    class ByteLiteral {
        prefix: /0[xX]/
        value: /[0-9a-fA-F]{2}/ |> `lambda x: int(x, 16)`
    }
    """
    _fields = ('prefix', 'value')

    def __init__(self, prefix, value):
        Node.__init__(self)
        self.prefix = prefix
        self.value = value

    def __repr__(self):
        return f'ByteLiteral(prefix={self.prefix!r}, value={self.value!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_ByteLiteral, fullparse)


def _try_ByteLiteral(_text, _pos):
    # Begin Seq
    start_pos12 = _pos
    while True:
        # Begin Regex
        # /0[xX]/
        match13 = matcher13(_text, _pos)
        if match13:
            _result = match13.group(0)
            _pos = (yield (3, _try__ignored, match13.end()))[2]
            _status = True
        else:
            _result = _raise_error199
            _status = False
        # End Regex
        if not (_status):
            break
        prefix = _result
        # Begin Apply
        # /[0-9a-fA-F]{2}/ |> `lambda x: int(x, 16)`
        # Begin Regex
        # /[0-9a-fA-F]{2}/
        match14 = matcher14(_text, _pos)
        if match14:
            _result = match14.group(0)
            _pos = (yield (3, _try__ignored, match14.end()))[2]
            _status = True
        else:
            _result = _raise_error202
            _status = False
        # End Regex
        if _status:
            arg14 = _result
            _result = lambda x: int(x, 16)
            _status = True
            _result = _result(arg14)
        # End Apply
        if not (_status):
            break
        value = _result
        _result = ByteLiteral(prefix, value)
        _result._metadata.position_info = (start_pos12, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _raise_error199(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ByteLiteral' rule, at the expression:\n"
    '    /0[xX]/\n\n'
    'Expected to match the regular expression /0[xX]/'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error202(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ByteLiteral' rule, at the expression:\n"
    '    /[0-9a-fA-F]{2}/\n\n'
    'Expected to match the regular expression /[0-9a-fA-F]{2}/'
    )
    raise ParseError((title + details), _pos, line, col)

def _try_Atom(_text, _pos):
    # Rule 'Atom'
    # Begin Choice
    farthest_err9 = _raise_error205
    backtrack10 = farthest_pos9 = _pos
    while True:
        # Option 1:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_StringLiteral, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos9 < _pos):
            farthest_pos9 = _pos
            farthest_err9 = _result
        _pos = backtrack10
        # Option 2:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_RegexLiteral, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos9 < _pos):
            farthest_pos9 = _pos
            farthest_err9 = _result
        _pos = backtrack10
        # Option 3:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_LetExpression, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos9 < _pos):
            farthest_pos9 = _pos
            farthest_err9 = _result
        _pos = backtrack10
        # Option 4:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_ListLiteral, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos9 < _pos):
            farthest_pos9 = _pos
            farthest_err9 = _result
        _pos = backtrack10
        # Option 5:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_ByteLiteral, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos9 < _pos):
            farthest_pos9 = _pos
            farthest_err9 = _result
        _pos = backtrack10
        # Option 6:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_PythonExpression, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos9 < _pos):
            farthest_pos9 = _pos
            farthest_err9 = _result
        _pos = backtrack10
        # Option 7:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Ref, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos9 < _pos):
            farthest_pos9 = _pos
            farthest_err9 = _result
        _pos = farthest_pos9
        _result = farthest_err9
        break
    # End Choice
    yield (_status, _result, _pos)

def _parse_Atom(text, pos=0, fullparse=True):
    return _run(text, pos, _try_Atom, fullparse)

Atom = Rule('Atom', _parse_Atom, """
    Atom = StringLiteral | RegexLiteral | LetExpression | ListLiteral | ByteLiteral | PythonExpression | Ref
""")
def _raise_error205(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Atom' rule, at the expression:\n"
    '    StringLiteral | RegexLiteral | LetExpression | ListLiteral | ByteLiteral | PythonExpression | Ref\n\n'
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

class KeywordArg(Node):
    """
    class KeywordArg {
        name: Name << ('=>' | '=' | ':')
        expr: Expr
    }
    """
    _fields = ('name', 'expr')

    def __init__(self, name, expr):
        Node.__init__(self)
        self.name = name
        self.expr = expr

    def __repr__(self):
        return f'KeywordArg(name={self.name!r}, expr={self.expr!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_KeywordArg, fullparse)


def _try_KeywordArg(_text, _pos):
    # Begin Seq
    start_pos13 = _pos
    while True:
        # Begin Discard
        # Name << ('=>' | '=' | ':')
        while True:
            # Begin Ref
            (_status, _result, _pos) = (yield (3, _try_Name, _pos))
            # End Ref
            if not (_status):
                break
            staging13 = _result
            # Begin Choice
            farthest_err10 = _raise_error218
            farthest_pos10 = _pos
            while True:
                # Option 1:
                # Begin Str
                value27 = '=>'
                end27 = (_pos + 2)
                if (_text[slice(_pos, end27, None)] == value27):
                    _result = value27
                    _pos = (yield (3, _try__ignored, end27))[2]
                    _status = True
                else:
                    _result = _raise_error219
                    _status = False
                # End Str
                if _status:
                    break
                # Option 2:
                # Begin Str
                value28 = '='
                end28 = (_pos + 1)
                if (_text[slice(_pos, end28, None)] == value28):
                    _result = value28
                    _pos = (yield (3, _try__ignored, end28))[2]
                    _status = True
                else:
                    _result = _raise_error220
                    _status = False
                # End Str
                if _status:
                    break
                # Option 3:
                # Begin Str
                value29 = ':'
                end29 = (_pos + 1)
                if (_text[slice(_pos, end29, None)] == value29):
                    _result = value29
                    _pos = (yield (3, _try__ignored, end29))[2]
                    _status = True
                else:
                    _result = _raise_error221
                    _status = False
                # End Str
                if _status:
                    break
                _pos = farthest_pos10
                _result = farthest_err10
                break
            # End Choice
            if _status:
                _result = staging13
            break
        # End Discard
        if not (_status):
            break
        name = _result
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Expr, _pos))
        # End Ref
        if not (_status):
            break
        expr = _result
        _result = KeywordArg(name, expr)
        _result._metadata.position_info = (start_pos13, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _raise_error218(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'KeywordArg' rule, at the expression:\n"
    "    '=>' | '=' | ':'\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error219(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'KeywordArg' rule, at the expression:\n"
    "    '=>'\n\n"
    "Expected to match the string '=>'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error220(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'KeywordArg' rule, at the expression:\n"
    "    '='\n\n"
    "Expected to match the string '='"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error221(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'KeywordArg' rule, at the expression:\n"
    "    ':'\n\n"
    "Expected to match the string ':'"
    )
    raise ParseError((title + details), _pos, line, col)

class ArgList(Node):
    """
    class ArgList {
        args: ('(' >> (wrap(KeywordArg | Expr) /? Comma)) << ')'
    }
    """
    _fields = ('args',)

    def __init__(self, args):
        Node.__init__(self)
        self.args = args

    def __repr__(self):
        return f'ArgList(args={self.args!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_ArgList, fullparse)


def _parse_function_233(_text, _pos):
    # Begin Choice
    farthest_err11 = _raise_error233
    backtrack11 = farthest_pos11 = _pos
    while True:
        # Option 1:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_KeywordArg, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos11 < _pos):
            farthest_pos11 = _pos
            farthest_err11 = _result
        _pos = backtrack11
        # Option 2:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Expr, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos11 < _pos):
            farthest_pos11 = _pos
            farthest_err11 = _result
        _pos = farthest_pos11
        _result = farthest_err11
        break
    # End Choice
    yield (_status, _result, _pos)

def _try_ArgList(_text, _pos):
    # Begin Seq
    start_pos14 = _pos
    while True:
        # Begin Discard
        # ('(' >> (wrap(KeywordArg | Expr) /? Comma)) << ')'
        while True:
            # Begin Discard
            # '(' >> (wrap(KeywordArg | Expr) /? Comma)
            while True:
                # Begin Str
                value30 = '('
                end30 = (_pos + 1)
                if (_text[slice(_pos, end30, None)] == value30):
                    _result = value30
                    _pos = (yield (3, _try__ignored, end30))[2]
                    _status = True
                else:
                    _result = _raise_error229
                    _status = False
                # End Str
                if not (_status):
                    break
                # Begin Sep
                # wrap(KeywordArg | Expr) /? Comma
                staging14 = []
                checkpoint7 = _pos
                while True:
                    # Begin Call
                    # wrap(KeywordArg | Expr)
                    func15 = _ParseFunction(_try_wrap, (_parse_function_233,), ())
                    (_status, _result, _pos) = (yield (3, func15, _pos))
                    # End Call
                    if not (_status):
                        break
                    staging14.append(_result)
                    checkpoint7 = _pos
                    # Begin Ref
                    (_status, _result, _pos) = (yield (3, _try_Comma, _pos))
                    # End Ref
                    if not (_status):
                        break
                    checkpoint7 = _pos
                _result = staging14
                _pos = checkpoint7
                _status = True
                # End Sep
                break
            # End Discard
            if not (_status):
                break
            staging15 = _result
            # Begin Str
            value31 = ')'
            end31 = (_pos + 1)
            if (_text[slice(_pos, end31, None)] == value31):
                _result = value31
                _pos = (yield (3, _try__ignored, end31))[2]
                _status = True
            else:
                _result = _raise_error237
                _status = False
            # End Str
            if _status:
                _result = staging15
            break
        # End Discard
        if not (_status):
            break
        args = _result
        _result = ArgList(args)
        _result._metadata.position_info = (start_pos14, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _raise_error229(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ArgList' rule, at the expression:\n"
    "    '('\n\n"
    "Expected to match the string '('"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error233(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ArgList' rule, at the expression:\n"
    '    KeywordArg | Expr\n\n'
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error237(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'ArgList' rule, at the expression:\n"
    "    ')'\n\n"
    "Expected to match the string ')'"
    )
    raise ParseError((title + details), _pos, line, col)

def _parse_function_260(_text, _pos):
    # Begin Choice
    farthest_err13 = _raise_error260
    farthest_pos13 = _pos
    while True:
        # Option 1:
        # Begin Str
        value37 = '//'
        end37 = (_pos + 2)
        if (_text[slice(_pos, end37, None)] == value37):
            _result = value37
            _pos = (yield (3, _try__ignored, end37))[2]
            _status = True
        else:
            _result = _raise_error261
            _status = False
        # End Str
        if _status:
            break
        # Option 2:
        # Begin Str
        value38 = '/?'
        end38 = (_pos + 2)
        if (_text[slice(_pos, end38, None)] == value38):
            _result = value38
            _pos = (yield (3, _try__ignored, end38))[2]
            _status = True
        else:
            _result = _raise_error262
            _status = False
        # End Str
        if _status:
            break
        _pos = farthest_pos13
        _result = farthest_err13
        break
    # End Choice
    yield (_status, _result, _pos)

def _parse_function_266(_text, _pos):
    # Begin Choice
    farthest_err14 = _raise_error266
    farthest_pos14 = _pos
    while True:
        # Option 1:
        # Begin Str
        value39 = '<<'
        end39 = (_pos + 2)
        if (_text[slice(_pos, end39, None)] == value39):
            _result = value39
            _pos = (yield (3, _try__ignored, end39))[2]
            _status = True
        else:
            _result = _raise_error267
            _status = False
        # End Str
        if _status:
            break
        # Option 2:
        # Begin Str
        value40 = '>>'
        end40 = (_pos + 2)
        if (_text[slice(_pos, end40, None)] == value40):
            _result = value40
            _pos = (yield (3, _try__ignored, end40))[2]
            _status = True
        else:
            _result = _raise_error268
            _status = False
        # End Str
        if _status:
            break
        _pos = farthest_pos14
        _result = farthest_err14
        break
    # End Choice
    yield (_status, _result, _pos)

def _parse_function_272(_text, _pos):
    # Begin Choice
    farthest_err15 = _raise_error272
    farthest_pos15 = _pos
    while True:
        # Option 1:
        # Begin Str
        value41 = '<|'
        end41 = (_pos + 2)
        if (_text[slice(_pos, end41, None)] == value41):
            _result = value41
            _pos = (yield (3, _try__ignored, end41))[2]
            _status = True
        else:
            _result = _raise_error273
            _status = False
        # End Str
        if _status:
            break
        # Option 2:
        # Begin Str
        value42 = '|>'
        end42 = (_pos + 2)
        if (_text[slice(_pos, end42, None)] == value42):
            _result = value42
            _pos = (yield (3, _try__ignored, end42))[2]
            _status = True
        else:
            _result = _raise_error274
            _status = False
        # End Str
        if _status:
            break
        # Option 3:
        # Begin Str
        value43 = 'where'
        end43 = (_pos + 5)
        if (_text[slice(_pos, end43, None)] == value43):
            _result = value43
            _pos = (yield (3, _try__ignored, end43))[2]
            _status = True
        else:
            _result = _raise_error275
            _status = False
        # End Str
        if _status:
            break
        _pos = farthest_pos15
        _result = farthest_err15
        break
    # End Choice
    yield (_status, _result, _pos)

def _parse_function_279(_text, _pos):
    # Begin Str
    value44 = '|'
    end44 = (_pos + 1)
    if (_text[slice(_pos, end44, None)] == value44):
        _result = value44
        _pos = (yield (3, _try__ignored, end44))[2]
        _status = True
    else:
        _result = _raise_error279
        _status = False
    # End Str
    yield (_status, _result, _pos)

def _try_Expr(_text, _pos):
    # Rule 'Expr'
    # Begin OperatorPrecedence
    # OperatorPrecedence(
    #     Atom,
    #     Mixfix(('(' >> wrap(Expr)) << ')'),
    #     Postfix(ArgList),
    #     Postfix('?' | '*' | '+' | Repeat),
    #     LeftAssoc(wrap('//' | '/?')),
    #     LeftAssoc(wrap('<<' | '>>')),
    #     LeftAssoc(wrap('<|' | '|>' | 'where')),
    #     LeftAssoc(wrap('|'))
    # )
    # Begin LeftAssoc
    # LeftAssoc(wrap('|'))
    is_first1 = True
    staging16 = None
    while True:
        # Begin LeftAssoc
        # LeftAssoc(wrap('<|' | '|>' | 'where'))
        is_first2 = True
        staging17 = None
        while True:
            # Begin LeftAssoc
            # LeftAssoc(wrap('<<' | '>>'))
            is_first3 = True
            staging18 = None
            while True:
                # Begin LeftAssoc
                # LeftAssoc(wrap('//' | '/?'))
                is_first4 = True
                staging19 = None
                while True:
                    # Begin Postfix
                    # Postfix('?' | '*' | '+' | Repeat)
                    # Begin Postfix
                    # Postfix(ArgList)
                    # Begin Mixfix
                    # Mixfix(('(' >> wrap(Expr)) << ')')
                    backtrack12 = _pos
                    while True:
                        # Begin Discard
                        # ('(' >> wrap(Expr)) << ')'
                        while True:
                            # Begin Discard
                            # '(' >> wrap(Expr)
                            while True:
                                # Begin Str
                                value32 = '('
                                end32 = (_pos + 1)
                                if (_text[slice(_pos, end32, None)] == value32):
                                    _result = value32
                                    _pos = (yield (3, _try__ignored, end32))[2]
                                    _status = True
                                else:
                                    _result = _raise_error244
                                    _status = False
                                # End Str
                                if not (_status):
                                    break
                                # Begin Call
                                # wrap(Expr)
                                func16 = _ParseFunction(_try_wrap, (_try_Expr,), ())
                                (_status, _result, _pos) = (yield (3, func16, _pos))
                                # End Call
                                break
                            # End Discard
                            if not (_status):
                                break
                            staging20 = _result
                            # Begin Str
                            value33 = ')'
                            end33 = (_pos + 1)
                            if (_text[slice(_pos, end33, None)] == value33):
                                _result = value33
                                _pos = (yield (3, _try__ignored, end33))[2]
                                _status = True
                            else:
                                _result = _raise_error248
                                _status = False
                            # End Str
                            if _status:
                                _result = staging20
                            break
                        # End Discard
                        if _status:
                            break
                        _pos = backtrack12
                        # Begin Ref
                        (_status, _result, _pos) = (yield (3, _try_Atom, _pos))
                        # End Ref
                        break
                    # End Mixfix
                    if _status:
                        staging21 = _result
                        checkpoint8 = _pos
                        while True:
                            # Begin Ref
                            (_status, _result, _pos) = (yield (3, _try_ArgList, _pos))
                            # End Ref
                            if _status:
                                staging21 = Postfix(staging21, _result)
                                checkpoint8 = _pos
                            else:
                                _pos = checkpoint8
                                _result = staging21
                                _status = True
                                break
                    # End Postfix
                    if _status:
                        staging22 = _result
                        checkpoint9 = _pos
                        while True:
                            # Begin Choice
                            farthest_err12 = _raise_error252
                            backtrack13 = farthest_pos12 = _pos
                            while True:
                                # Option 1:
                                # Begin Str
                                value34 = '?'
                                end34 = (_pos + 1)
                                if (_text[slice(_pos, end34, None)] == value34):
                                    _result = value34
                                    _pos = (yield (3, _try__ignored, end34))[2]
                                    _status = True
                                else:
                                    _result = _raise_error253
                                    _status = False
                                # End Str
                                if _status:
                                    break
                                # Option 2:
                                # Begin Str
                                value35 = '*'
                                end35 = (_pos + 1)
                                if (_text[slice(_pos, end35, None)] == value35):
                                    _result = value35
                                    _pos = (yield (3, _try__ignored, end35))[2]
                                    _status = True
                                else:
                                    _result = _raise_error254
                                    _status = False
                                # End Str
                                if _status:
                                    break
                                # Option 3:
                                # Begin Str
                                value36 = '+'
                                end36 = (_pos + 1)
                                if (_text[slice(_pos, end36, None)] == value36):
                                    _result = value36
                                    _pos = (yield (3, _try__ignored, end36))[2]
                                    _status = True
                                else:
                                    _result = _raise_error255
                                    _status = False
                                # End Str
                                if _status:
                                    break
                                # Option 4:
                                # Begin Ref
                                (_status, _result, _pos) = (yield (3, _try_Repeat, _pos))
                                # End Ref
                                if _status:
                                    break
                                if (farthest_pos12 < _pos):
                                    farthest_pos12 = _pos
                                    farthest_err12 = _result
                                _pos = farthest_pos12
                                _result = farthest_err12
                                break
                            # End Choice
                            if _status:
                                staging22 = Postfix(staging22, _result)
                                checkpoint9 = _pos
                            else:
                                _pos = checkpoint9
                                _result = staging22
                                _status = True
                                break
                    # End Postfix
                    if not (_status):
                        break
                    checkpoint10 = _pos
                    if is_first4:
                        is_first4 = False
                        staging19 = _result
                    else:
                        staging19 = Infix(staging19, operator4, _result)
                    # Begin Call
                    # wrap('//' | '/?')
                    func17 = _ParseFunction(_try_wrap, (_parse_function_260,), ())
                    (_status, _result, _pos) = (yield (3, func17, _pos))
                    # End Call
                    if not (_status):
                        break
                    operator4 = _result
                if not (is_first4):
                    _status = True
                    _result = staging19
                    _pos = checkpoint10
                # End LeftAssoc
                if not (_status):
                    break
                checkpoint11 = _pos
                if is_first3:
                    is_first3 = False
                    staging18 = _result
                else:
                    staging18 = Infix(staging18, operator3, _result)
                # Begin Call
                # wrap('<<' | '>>')
                func18 = _ParseFunction(_try_wrap, (_parse_function_266,), ())
                (_status, _result, _pos) = (yield (3, func18, _pos))
                # End Call
                if not (_status):
                    break
                operator3 = _result
            if not (is_first3):
                _status = True
                _result = staging18
                _pos = checkpoint11
            # End LeftAssoc
            if not (_status):
                break
            checkpoint12 = _pos
            if is_first2:
                is_first2 = False
                staging17 = _result
            else:
                staging17 = Infix(staging17, operator2, _result)
            # Begin Call
            # wrap('<|' | '|>' | 'where')
            func19 = _ParseFunction(_try_wrap, (_parse_function_272,), ())
            (_status, _result, _pos) = (yield (3, func19, _pos))
            # End Call
            if not (_status):
                break
            operator2 = _result
        if not (is_first2):
            _status = True
            _result = staging17
            _pos = checkpoint12
        # End LeftAssoc
        if not (_status):
            break
        checkpoint13 = _pos
        if is_first1:
            is_first1 = False
            staging16 = _result
        else:
            staging16 = Infix(staging16, operator1, _result)
        # Begin Call
        # wrap('|')
        arg15 = _wrap_string_literal('|', _parse_function_279)
        func20 = _ParseFunction(_try_wrap, (arg15,), ())
        (_status, _result, _pos) = (yield (3, func20, _pos))
        # End Call
        if not (_status):
            break
        operator1 = _result
    if not (is_first1):
        _status = True
        _result = staging16
        _pos = checkpoint13
    # End LeftAssoc
    # End OperatorPrecedence
    yield (_status, _result, _pos)

def _parse_Expr(text, pos=0, fullparse=True):
    return _run(text, pos, _try_Expr, fullparse)

Expr = Rule('Expr', _parse_Expr, """
    Expr = OperatorPrecedence(
        Atom,
        Mixfix(('(' >> wrap(Expr)) << ')'),
        Postfix(ArgList),
        Postfix('?' | '*' | '+' | Repeat),
        LeftAssoc(wrap('//' | '/?')),
        LeftAssoc(wrap('<<' | '>>')),
        LeftAssoc(wrap('<|' | '|>' | 'where')),
        LeftAssoc(wrap('|'))
    )
""")
def _raise_error244(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '('\n\n"
    "Expected to match the string '('"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error248(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    ')'\n\n"
    "Expected to match the string ')'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error252(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '?' | '*' | '+' | Repeat\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error253(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '?'\n\n"
    "Expected to match the string '?'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error254(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '*'\n\n"
    "Expected to match the string '*'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error255(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '+'\n\n"
    "Expected to match the string '+'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error260(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '//' | '/?'\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error261(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '//'\n\n"
    "Expected to match the string '//'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error262(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '/?'\n\n"
    "Expected to match the string '/?'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error266(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '<<' | '>>'\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error267(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '<<'\n\n"
    "Expected to match the string '<<'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error268(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '>>'\n\n"
    "Expected to match the string '>>'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error272(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '<|' | '|>' | 'where'\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error273(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '<|'\n\n"
    "Expected to match the string '<|'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error274(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '|>'\n\n"
    "Expected to match the string '|>'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error275(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    'where'\n\n"
    "Expected to match the string 'where'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error279(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Expr' rule, at the expression:\n"
    "    '|'\n\n"
    "Expected to match the string '|'"
    )
    raise ParseError((title + details), _pos, line, col)

class Repeat(Node):
    """
    class Repeat {
        open: '{'
        start: Opt(RepeatArg)
        stop: ',' >> RepeatArg | ',' >> `None` | `start`
        close: '}'
    }
    """
    _fields = ('open', 'start', 'stop', 'close')

    def __init__(self, open, start, stop, close):
        Node.__init__(self)
        self.open = open
        self.start = start
        self.stop = stop
        self.close = close

    def __repr__(self):
        return f'Repeat(open={self.open!r}, start={self.start!r}, stop={self.stop!r}, close={self.close!r})'

    @staticmethod
    def parse(text, pos=0, fullparse=True):
        return _run(text, pos, _try_Repeat, fullparse)


def _try_Repeat(_text, _pos):
    # Begin Seq
    start_pos15 = _pos
    while True:
        # Begin Str
        value45 = '{'
        end45 = (_pos + 1)
        if (_text[slice(_pos, end45, None)] == value45):
            _result = value45
            _pos = (yield (3, _try__ignored, end45))[2]
            _status = True
        else:
            _result = _raise_error283
            _status = False
        # End Str
        if not (_status):
            break
        open = _result
        # Begin Opt
        # Opt(RepeatArg)
        backtrack14 = _pos
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_RepeatArg, _pos))
        # End Ref
        if not (_status):
            _pos = backtrack14
            _result = None
            _status = True
        # End Opt
        start = _result
        # Begin Choice
        backtrack15 = _pos
        while True:
            # Option 1:
            # Begin Discard
            # ',' >> RepeatArg
            while True:
                # Begin Str
                value46 = ','
                end46 = (_pos + 1)
                if (_text[slice(_pos, end46, None)] == value46):
                    _result = value46
                    _pos = (yield (3, _try__ignored, end46))[2]
                    _status = True
                else:
                    _result = _raise_error290
                    _status = False
                # End Str
                if not (_status):
                    break
                # Begin Ref
                (_status, _result, _pos) = (yield (3, _try_RepeatArg, _pos))
                # End Ref
                break
            # End Discard
            if _status:
                break
            _pos = backtrack15
            # Option 2:
            # Begin Discard
            # ',' >> `None`
            while True:
                # Begin Str
                value47 = ','
                end47 = (_pos + 1)
                if (_text[slice(_pos, end47, None)] == value47):
                    _result = value47
                    _pos = (yield (3, _try__ignored, end47))[2]
                    _status = True
                else:
                    _result = _raise_error293
                    _status = False
                # End Str
                if not (_status):
                    break
                _result = None
                _status = True
                break
            # End Discard
            if _status:
                break
            _pos = backtrack15
            # Option 3: (always_succeeds)
            _result = start
            _status = True
            break
        # End Choice
        stop = _result
        # Begin Str
        value48 = '}'
        end48 = (_pos + 1)
        if (_text[slice(_pos, end48, None)] == value48):
            _result = value48
            _pos = (yield (3, _try__ignored, end48))[2]
            _status = True
        else:
            _result = _raise_error297
            _status = False
        # End Str
        if not (_status):
            break
        close = _result
        _result = Repeat(open, start, stop, close)
        _result._metadata.position_info = (start_pos15, _pos)
        break
    # End Seq
    yield (_status, _result, _pos)

def _raise_error283(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Repeat' rule, at the expression:\n"
    "    '{'\n\n"
    "Expected to match the string '{'"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error290(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Repeat' rule, at the expression:\n"
    "    ','\n\n"
    "Expected to match the string ','"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error293(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Repeat' rule, at the expression:\n"
    "    ','\n\n"
    "Expected to match the string ','"
    )
    raise ParseError((title + details), _pos, line, col)

def _raise_error297(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'Repeat' rule, at the expression:\n"
    "    '}'\n\n"
    "Expected to match the string '}'"
    )
    raise ParseError((title + details), _pos, line, col)

def _try_RepeatArg(_text, _pos):
    # Rule 'RepeatArg'
    # Begin Choice
    farthest_err16 = _raise_error299
    backtrack16 = farthest_pos16 = _pos
    while True:
        # Option 1:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_PythonExpression, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos16 < _pos):
            farthest_pos16 = _pos
            farthest_err16 = _result
        _pos = backtrack16
        # Option 2:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Ref, _pos))
        # End Ref
        if _status:
            break
        if (farthest_pos16 < _pos):
            farthest_pos16 = _pos
            farthest_err16 = _result
        _pos = farthest_pos16
        _result = farthest_err16
        break
    # End Choice
    yield (_status, _result, _pos)

def _parse_RepeatArg(text, pos=0, fullparse=True):
    return _run(text, pos, _try_RepeatArg, fullparse)

RepeatArg = Rule('RepeatArg', _parse_RepeatArg, """
    RepeatArg = PythonExpression | Ref
""")
def _raise_error299(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'RepeatArg' rule, at the expression:\n"
    '    PythonExpression | Ref\n\n'
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _try_ManyStmts(_text, _pos):
    # Rule 'ManyStmts'
    # Begin Sep
    # Stmt /? LineSep
    staging23 = []
    checkpoint14 = _pos
    while True:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Stmt, _pos))
        # End Ref
        if not (_status):
            break
        staging23.append(_result)
        checkpoint14 = _pos
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_LineSep, _pos))
        # End Ref
        if not (_status):
            break
        checkpoint14 = _pos
    if staging23:
        _result = staging23
        _pos = checkpoint14
        _status = True
    # End Sep
    yield (_status, _result, _pos)

def _parse_ManyStmts(text, pos=0, fullparse=True):
    return _run(text, pos, _try_ManyStmts, fullparse)

ManyStmts = Rule('ManyStmts', _parse_ManyStmts, """
    ManyStmts = Stmt /? LineSep
""")
def _try_SingleExpr(_text, _pos):
    # Rule 'SingleExpr'
    # Begin Discard
    # Expr << Opt(LineSep)
    while True:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Expr, _pos))
        # End Ref
        if not (_status):
            break
        staging24 = _result
        # Begin Opt
        # Opt(LineSep)
        backtrack17 = _pos
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_LineSep, _pos))
        # End Ref
        if not (_status):
            _pos = backtrack17
            _result = None
            _status = True
        # End Opt
        _result = staging24
        break
    # End Discard
    yield (_status, _result, _pos)

def _parse_SingleExpr(text, pos=0, fullparse=True):
    return _run(text, pos, _try_SingleExpr, fullparse)

SingleExpr = Rule('SingleExpr', _parse_SingleExpr, """
    SingleExpr = Expr << Opt(LineSep)
""")
def _try_start(_text, _pos):
    # Rule 'start'
    # Begin Discard
    # _try__ignored >> (Skip(Newline) >> (ManyStmts | SingleExpr))
    while True:
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try__ignored, _pos))
        # End Ref
        if not (_status):
            break
        # Begin Discard
        # Skip(Newline) >> (ManyStmts | SingleExpr)
        while True:
            # Begin Skip
            # Skip(Newline)
            while True:
                checkpoint15 = _pos
                # Begin Ref
                (_status, _result, _pos) = (yield (3, _try_Newline, _pos))
                # End Ref
                if _status:
                    continue
                else:
                    _pos = checkpoint15
                break
            _result = None
            _status = True
            # End Skip
            # Begin Choice
            farthest_err17 = _raise_error317
            backtrack18 = farthest_pos17 = _pos
            while True:
                # Option 1:
                # Begin Ref
                (_status, _result, _pos) = (yield (3, _try_ManyStmts, _pos))
                # End Ref
                if _status:
                    break
                if (farthest_pos17 < _pos):
                    farthest_pos17 = _pos
                    farthest_err17 = _result
                _pos = backtrack18
                # Option 2:
                # Begin Ref
                (_status, _result, _pos) = (yield (3, _try_SingleExpr, _pos))
                # End Ref
                if _status:
                    break
                if (farthest_pos17 < _pos):
                    farthest_pos17 = _pos
                    farthest_err17 = _result
                _pos = farthest_pos17
                _result = farthest_err17
                break
            # End Choice
            break
        # End Discard
        break
    # End Discard
    yield (_status, _result, _pos)

def _parse_start(text, pos=0, fullparse=True):
    return _run(text, pos, _try_start, fullparse)

start = Rule('start', _parse_start, """
    start = _try__ignored >> (Skip(Newline) >> (ManyStmts | SingleExpr))
""")
def _raise_error317(_text, _pos):
    if (len(_text) <= _pos):
        title = 'Unexpected end of input.'
        line = None
        col = None
    else:
        (line, col) = _get_line_and_column(_text, _pos)
        excerpt = _extract_excerpt(_text, _pos, col)
        title = f'Error on line {line}, column {col}:\n{excerpt}\n'
    details = (
    "Failed to parse the 'start' rule, at the expression:\n"
    '    ManyStmts | SingleExpr\n\n'
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)

def _try__ignored(_text, _pos):
    # Rule '_ignored'
    # Begin Skip
    # Skip(Space, Comment)
    while True:
        checkpoint16 = _pos
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Space, _pos))
        # End Ref
        if _status:
            continue
        else:
            _pos = checkpoint16
        # Begin Ref
        (_status, _result, _pos) = (yield (3, _try_Comment, _pos))
        # End Ref
        if _status:
            continue
        else:
            _pos = checkpoint16
        break
    _result = None
    _status = True
    # End Skip
    yield (_status, _result, _pos)

def _parse__ignored(text, pos=0, fullparse=True):
    return _run(text, pos, _try__ignored, fullparse)

_ignored = Rule('_ignored', _parse__ignored, """
    _ignored = Skip(Space, Comment)
""")
