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

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

Newline = /[\\r\\n][\\s]*/
Sep = 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)
    fields: wrap("{") >> (RuleDef /? Sep) << "}"
}

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) << "]"
}

Atom = ("(" >> wrap(Expr) << ")")
    | StringLiteral
    | RegexLiteral
    | LetExpression
    | ListLiteral
    | PythonExpression
    | Ref

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

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

Expr = OperatorPrecedence(
    Atom,
    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, Sep, allow_trailer=True, allow_empty=False)
SingleExpr = Expr << Opt(Sep)

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 __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)
        return self.__class__(**kw)


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):
        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):
        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):
        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, _cont_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


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)


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 was is not now:
            updates[field] = now

    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 = getattr(node, '_position_info', None)
        if pos_info:
            start, end = pos_info
            end -= 1
            node._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


def _cont_Space(_text, _pos):
    # Rule 'Space'
    # <Regex pattern='[ \\t]+'>
    match1 = matcher1(_text, _pos)
    if match1:
        _pos = match1.end()
        _status = True
        _result = match1.group(0)
    else:
        _status = False
        _result = _raise_error2
    # </Regex>
    (yield (_status, _result, _pos,))


def _parse_Space(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_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 _cont_Comment(_text, _pos):
    # Rule 'Comment'
    # <Regex pattern='#[^\\r\\n]*'>
    match2 = matcher2(_text, _pos)
    if match2:
        _pos = match2.end()
        _status = True
        _result = match2.group(0)
    else:
        _status = False
        _result = _raise_error4
    # </Regex>
    (yield (_status, _result, _pos,))


def _parse_Comment(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_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 _cont_Newline(_text, _pos):
    # Rule 'Newline'
    # <Regex pattern='[\\r\\n][\\s]*'>
    match3 = matcher3(_text, _pos)
    if match3:
        _pos = (yield (3, _cont__ignored, match3.end(),))[2]
        _status = True
        _result = match3.group(0)
    else:
        _status = False
        _result = _raise_error6
    # </Regex>
    (yield (_status, _result, _pos,))


def _parse_Newline(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_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 _cont_Sep(_text, _pos):
    # Rule 'Sep'
    # <List>
    # (Newline | ';')+
    staging1 = []
    while True:
        checkpoint1 = _pos
        # <Choice>
        backtrack1 = farthest_pos1 = _pos
        farthest_err1 = _raise_error9
        while True:
            # Option 1:
            # <Ref name='Newline'>
            (_status, _result, _pos,) = (yield (3, _cont_Newline, _pos,))
            # </Ref>
            if _status:
                break
            if (farthest_pos1 < _pos):
                farthest_pos1 = _pos
                farthest_err1 = _result
            _pos = backtrack1
            # Option 2:
            # <String value=';'>
            value1 = ';'
            end1 = (_pos + 1)
            if (_text[_pos : end1] == value1):
                _pos = (yield (3, _cont__ignored, end1,))[2]
                _status = True
                _result = value1
            else:
                _status = False
                _result = _raise_error11
            # </String>
            if _status:
                break
            if (farthest_pos1 < _pos):
                farthest_pos1 = _pos
                farthest_err1 = _result
            _pos = farthest_pos1
            _result = farthest_err1
            break
        # </Choice>
        if (not _status):
            _pos = checkpoint1
            break
        staging1.append(_result)
    if staging1:
        _result = staging1
        _status = True
    # </List>
    (yield (_status, _result, _pos,))


def _parse_Sep(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_Sep, fullparse)


Sep = Rule('Sep', _parse_Sep, """
    Sep = (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 'Sep' 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 'Sep' rule, at the expression:\n"
    "    ';'\n\n"
    "Expected to match the string ';'"
    )
    raise ParseError((title + details), _pos, line, col)


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


def _parse_Name(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_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):
    # <String value=','>
    value2 = ','
    end2 = (_pos + 1)
    if (_text[_pos : end2] == value2):
        _pos = (yield (3, _cont__ignored, end2,))[2]
        _status = True
        _result = value2
    else:
        _status = False
        _result = _raise_error17
    # </String>
    (yield (_status, _result, _pos,))


def _cont_Comma(_text, _pos):
    # Rule 'Comma'
    # <Call>
    # wrap(',')
    arg1 = _wrap_string_literal(',', _parse_function_17)
    func1 = _ParseFunction(_cont_wrap, (arg1,), ())
    (_status, _result, _pos,) = (yield (3, func1, _pos,))
    # </Call>
    (yield (_status, _result, _pos,))


def _parse_Comma(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_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 _cont_wrap(_text, _pos, x):
    # Rule 'wrap'
    # <Discard>
    # (Skip(Newline) >> x) << Skip(Newline)
    while True:
        # <Discard>
        # Skip(Newline) >> x
        while True:
            # <Skip>
            # Skip(Newline)
            while True:
                checkpoint2 = _pos
                # <Ref name='Newline'>
                (_status, _result, _pos,) = (yield (3, _cont_Newline, _pos,))
                # </Ref>
                if _status:
                    continue
                else:
                    _pos = checkpoint2
                break
            _status = True
            _result = None
            # </Skip>
            # <Ref name='x'>
            (_status, _result, _pos,) = (yield (3, x, _pos,))
            # </Ref>
            break
        # </Discard>
        if (not _status):
            break
        staging2 = _result
        # <Skip>
        # Skip(Newline)
        while True:
            checkpoint3 = _pos
            # <Ref name='Newline'>
            (_status, _result, _pos,) = (yield (3, _cont_Newline, _pos,))
            # </Ref>
            if _status:
                continue
            else:
                _pos = checkpoint3
            break
        _status = True
        _result = None
        # </Skip>
        _result = staging2
        break
    # </Discard>
    (yield (_status, _result, _pos,))


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


wrap = Rule('wrap', _parse_wrap, """
    wrap(x) = (Skip(Newline) >> x) << Skip(Newline)
""")

def _cont_kw(_text, _pos, word):
    # Rule 'kw'
    # <Where>
    # Name where `lambda x: x == word`
    # <Ref name='Name'>
    (_status, _result, _pos,) = (yield (3, _cont_Name, _pos,))
    # </Ref>
    if _status:
        arg2 = _result
        _result = lambda x: x == word
        _status = True
        if _result(arg2):
            _result = arg2
        else:
            _status = False
            _result = _raise_error27
    # </Where>
    (yield (_status, _result, _pos,))


def _parse_kw(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_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):
    # <String value='('>
    value3 = '('
    end3 = (_pos + 1)
    if (_text[_pos : end3] == value3):
        _pos = (yield (3, _cont__ignored, end3,))[2]
        _status = True
        _result = value3
    else:
        _status = False
        _result = _raise_error35
    # </String>
    (yield (_status, _result, _pos,))


def _cont_Params(_text, _pos):
    # Rule 'Params'
    # <Discard>
    # (wrap('(') >> (wrap(Name) /? Comma)) << ')'
    while True:
        # <Discard>
        # wrap('(') >> (wrap(Name) /? Comma)
        while True:
            # <Call>
            # wrap('(')
            arg3 = _wrap_string_literal('(', _parse_function_35)
            func2 = _ParseFunction(_cont_wrap, (arg3,), ())
            (_status, _result, _pos,) = (yield (3, func2, _pos,))
            # </Call>
            if (not _status):
                break
            # <Sep>
            # wrap(Name) /? Comma
            staging3 = []
            checkpoint4 = _pos
            while True:
                # <Call>
                # wrap(Name)
                func3 = _ParseFunction(_cont_wrap, (_cont_Name,), ())
                (_status, _result, _pos,) = (yield (3, func3, _pos,))
                # </Call>
                if (not _status):
                    break
                staging3.append(_result)
                checkpoint4 = _pos
                # <Ref name='Comma'>
                (_status, _result, _pos,) = (yield (3, _cont_Comma, _pos,))
                # </Ref>
                if (not _status):
                    break
                checkpoint4 = _pos
            _result = staging3
            _status = True
            _pos = checkpoint4
            # </Sep>
            break
        # </Discard>
        if (not _status):
            break
        staging4 = _result
        # <String value=')'>
        value4 = ')'
        end4 = (_pos + 1)
        if (_text[_pos : end4] == value4):
            _pos = (yield (3, _cont__ignored, end4,))[2]
            _status = True
            _result = value4
        else:
            _status = False
            _result = _raise_error41
        # </String>
        if _status:
            _result = staging4
        break
    # </Discard>
    (yield (_status, _result, _pos,))


def _parse_Params(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_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):
    # <String value='ignored'>
    value5 = 'ignored'
    end5 = (_pos + 7)
    if (_text[_pos : end5] == value5):
        _pos = (yield (3, _cont__ignored, end5,))[2]
        _status = True
        _result = value5
    else:
        _status = False
        _result = _raise_error46
    # </String>
    (yield (_status, _result, _pos,))


def _parse_function_49(_text, _pos):
    # <String value='ignore'>
    value6 = 'ignore'
    end6 = (_pos + 6)
    if (_text[_pos : end6] == value6):
        _pos = (yield (3, _cont__ignored, end6,))[2]
        _status = True
        _result = value6
    else:
        _status = False
        _result = _raise_error49
    # </String>
    (yield (_status, _result, _pos,))


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


def _parse_IgnoreKeyword(text, pos=0, fullparse=True):
    return _run(text, pos, _cont_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):
        self.value = value
        self._position_info = None

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

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



def _cont_StringLiteral(_text, _pos):
    # <Seq>
    start_pos1 = _pos
    while True:
        # <Choice>
        backtrack3 = farthest_pos3 = _pos
        farthest_err3 = _raise_error53
        while True:
            # Option 1:
            # <Regex pattern='(?s)[bB]?("""([^\\\\]|\\\\.)*?""")[iI]?'>
            match5 = matcher5(_text, _pos)
            if match5:
                _pos = (yield (3, _cont__ignored, match5.end(),))[2]
                _status = True
                _result = match5.group(0)
            else:
                _status = False
                _result = _raise_error54
            # </Regex>
            if _status:
                break
            if (farthest_pos3 < _pos):
                farthest_pos3 = _pos
                farthest_err3 = _result
            _pos = backtrack3
            # Option 2:
            # <Regex pattern="(?s)[bB]?('''([^\\\\]|\\\\.)*?''')[iI]?">
            match6 = matcher6(_text, _pos)
            if match6:
                _pos = (yield (3, _cont__ignored, match6.end(),))[2]
                _status = True
                _result = match6.group(0)
            else:
                _status = False
                _result = _raise_error55
            # </Regex>
            if _status:
                break
            if (farthest_pos3 < _pos):
                farthest_pos3 = _pos
                farthest_err3 = _result
            _pos = backtrack3
            # Option 3:
            # <Regex pattern='[bB]?("([^"\\\\]|\\\\.)*")[iI]?'>
            match7 = matcher7(_text, _pos)
            if match7:
                _pos = (yield (3, _cont__ignored, match7.end(),))[2]
                _status = True
                _result = match7.group(0)
            else:
                _status = False
                _result = _raise_error56
            # </Regex>
            if _status:
                break
            if (farthest_pos3 < _pos):
                farthest_pos3 = _pos
                farthest_err3 = _result
            _pos = backtrack3
            # Option 4:
            # <Regex pattern="[bB]?('([^'\\\\]|\\\\.)*')[iI]?">
            match8 = matcher8(_text, _pos)
            if match8:
                _pos = (yield (3, _cont__ignored, match8.end(),))[2]
                _status = True
                _result = match8.group(0)
            else:
                _status = False
                _result = _raise_error57
            # </Regex>
            if _status:
                break
            if (farthest_pos3 < _pos):
                farthest_pos3 = _pos
                farthest_err3 = _result
            _pos = farthest_pos3
            _result = farthest_err3
            break
        # </Choice>
        if (not _status):
            break
        value = _result
        _result = StringLiteral(value)
        _result._position_info = (start_pos1, _pos,)
        break
    # </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):
        self.value = value
        self._position_info = None

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

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



def _cont_RegexLiteral(_text, _pos):
    # <Seq>
    start_pos2 = _pos
    while True:
        # <Regex pattern='[bB]?\\/([^\\/\\\\]|\\\\.)*\\/[iI]?'>
        match9 = matcher9(_text, _pos)
        if match9:
            _pos = (yield (3, _cont__ignored, match9.end(),))[2]
            _status = True
            _result = match9.group(0)
        else:
            _status = False
            _result = _raise_error61
        # </Regex>
        if (not _status):
            break
        value = _result
        _result = RegexLiteral(value)
        _result._position_info = (start_pos2, _pos,)
        break
    # </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):
        self.value = value
        self._position_info = None

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

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



def _cont_PythonSection(_text, _pos):
    # <Seq>
    start_pos3 = _pos
    while True:
        # <Apply>
        # /(?s)```.*?```/ |> `lambda x: textwrap.dedent(x[3:-3])`
        # <Regex pattern='(?s)```.*?```'>
        match10 = matcher10(_text, _pos)
        if match10:
            _pos = (yield (3, _cont__ignored, match10.end(),))[2]
            _status = True
            _result = match10.group(0)
        else:
            _status = False
            _result = _raise_error66
        # </Regex>
        if _status:
            arg6 = _result
            _result = lambda x: textwrap.dedent(x[3:-3])
            _status = True
            _result = _result(arg6)
        # </Apply>
        if (not _status):
            break
        value = _result
        _result = PythonSection(value)
        _result._position_info = (start_pos3, _pos,)
        break
    # </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):
        self.value = value
        self._position_info = None

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

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



def _cont_PythonExpression(_text, _pos):
    # <Seq>
    start_pos4 = _pos
    while True:
        # <Choice>
        backtrack4 = farthest_pos4 = _pos
        farthest_err4 = _raise_error71
        while True:
            # Option 1:
            # <Apply>
            # /`.*?`/ |> `lambda x: x[1:-1]`
            # <Regex pattern='`.*?`'>
            match11 = matcher11(_text, _pos)
            if match11:
                _pos = (yield (3, _cont__ignored, match11.end(),))[2]
                _status = True
                _result = match11.group(0)
            else:
                _status = False
                _result = _raise_error73
            # </Regex>
            if _status:
                arg7 = _result
                _result = lambda x: x[1:-1]
                _status = True
                _result = _result(arg7)
            # </Apply>
            if _status:
                break
            if (farthest_pos4 < _pos):
                farthest_pos4 = _pos
                farthest_err4 = _result
            _pos = backtrack4
            # Option 2:
            # <Regex pattern='\\d+'>
            match12 = matcher12(_text, _pos)
            if match12:
                _pos = (yield (3, _cont__ignored, match12.end(),))[2]
                _status = True
                _result = match12.group(0)
            else:
                _status = False
                _result = _raise_error75
            # </Regex>
            if _status:
                break
            if (farthest_pos4 < _pos):
                farthest_pos4 = _pos
                farthest_err4 = _result
            _pos = backtrack4
            # Option 3:
            # <String value='True'>
            value7 = 'True'
            end7 = (_pos + 4)
            if (_text[_pos : end7] == value7):
                _pos = (yield (3, _cont__ignored, end7,))[2]
                _status = True
                _result = value7
            else:
                _status = False
                _result = _raise_error76
            # </String>
            if _status:
                break
            if (farthest_pos4 < _pos):
                farthest_pos4 = _pos
                farthest_err4 = _result
            _pos = backtrack4
            # Option 4:
            # <String value='False'>
            value8 = 'False'
            end8 = (_pos + 5)
            if (_text[_pos : end8] == value8):
                _pos = (yield (3, _cont__ignored, end8,))[2]
                _status = True
                _result = value8
            else:
                _status = False
                _result = _raise_error77
            # </String>
            if _status:
                break
            if (farthest_pos4 < _pos):
                farthest_pos4 = _pos
                farthest_err4 = _result
            _pos = backtrack4
            # Option 5:
            # <String value='None'>
            value9 = 'None'
            end9 = (_pos + 4)
            if (_text[_pos : end9] == value9):
                _pos = (yield (3, _cont__ignored, end9,))[2]
                _status = True
                _result = value9
            else:
                _status = False
                _result = _raise_error78
            # </String>
            if _status:
                break
            if (farthest_pos4 < _pos):
                farthest_pos4 = _pos
                farthest_err4 = _result
            _pos = farthest_pos4
            _result = farthest_err4
            break
        # </Choice>
        if (not _status):
            break
        value = _result
        _result = PythonExpression(value)
        _result._position_info = (start_pos4, _pos,)
        break
    # </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):
        self.is_ignored = is_ignored
        self.name = name
        self.params = params
        self.expr = expr
        self._position_info = None

    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, _cont_RuleDef, fullparse)



def _parse_function_94(_text, _pos):
    # <Choice>
    backtrack5 = farthest_pos5 = _pos
    farthest_err5 = _raise_error94
    while True:
        # Option 1:
        # <String value='=>'>
        value10 = '=>'
        end10 = (_pos + 2)
        if (_text[_pos : end10] == value10):
            _pos = (yield (3, _cont__ignored, end10,))[2]
            _status = True
            _result = value10
        else:
            _status = False
            _result = _raise_error95
        # </String>
        if _status:
            break
        if (farthest_pos5 < _pos):
            farthest_pos5 = _pos
            farthest_err5 = _result
        _pos = backtrack5
        # Option 2:
        # <String value='='>
        value11 = '='
        end11 = (_pos + 1)
        if (_text[_pos : end11] == value11):
            _pos = (yield (3, _cont__ignored, end11,))[2]
            _status = True
            _result = value11
        else:
            _status = False
            _result = _raise_error96
        # </String>
        if _status:
            break
        if (farthest_pos5 < _pos):
            farthest_pos5 = _pos
            farthest_err5 = _result
        _pos = backtrack5
        # Option 3:
        # <String value=':'>
        value12 = ':'
        end12 = (_pos + 1)
        if (_text[_pos : end12] == value12):
            _pos = (yield (3, _cont__ignored, end12,))[2]
            _status = True
            _result = value12
        else:
            _status = False
            _result = _raise_error97
        # </String>
        if _status:
            break
        if (farthest_pos5 < _pos):
            farthest_pos5 = _pos
            farthest_err5 = _result
        _pos = farthest_pos5
        _result = farthest_err5
        break
    # </Choice>
    (yield (_status, _result, _pos,))


def _cont_RuleDef(_text, _pos):
    # <Seq>
    start_pos5 = _pos
    while True:
        # <Apply>
        # Opt(IgnoreKeyword) |> `bool`
        # <Opt>
        # Opt(IgnoreKeyword)
        backtrack6 = _pos
        # <Ref name='IgnoreKeyword'>
        (_status, _result, _pos,) = (yield (3, _cont_IgnoreKeyword, _pos,))
        # </Ref>
        if (not _status):
            _status = True
            _pos = backtrack6
            _result = None
        # </Opt>
        arg8 = _result
        _result = bool
        _status = True
        _result = _result(arg8)
        # </Apply>
        is_ignored = _result
        # <Ref name='Name'>
        (_status, _result, _pos,) = (yield (3, _cont_Name, _pos,))
        # </Ref>
        if (not _status):
            break
        name = _result
        # <Discard>
        # Opt(Params) << wrap('=>' | '=' | ':')
        while True:
            # <Opt>
            # Opt(Params)
            backtrack7 = _pos
            # <Ref name='Params'>
            (_status, _result, _pos,) = (yield (3, _cont_Params, _pos,))
            # </Ref>
            if (not _status):
                _status = True
                _pos = backtrack7
                _result = None
            # </Opt>
            staging5 = _result
            # <Call>
            # wrap('=>' | '=' | ':')
            func6 = _ParseFunction(_cont_wrap, (_parse_function_94,), ())
            (_status, _result, _pos,) = (yield (3, func6, _pos,))
            # </Call>
            if _status:
                _result = staging5
            break
        # </Discard>
        if (not _status):
            break
        params = _result
        # <Ref name='Expr'>
        (_status, _result, _pos,) = (yield (3, _cont_Expr, _pos,))
        # </Ref>
        if (not _status):
            break
        expr = _result
        _result = RuleDef(is_ignored, name, params, expr)
        _result._position_info = (start_pos5, _pos,)
        break
    # </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)
        fields: (wrap('{') >> (RuleDef /? Sep)) << '}'
    }
    """
    _fields = ('name', 'params', 'fields',)

    def __init__(self, name, params, fields):
        self.name = name
        self.params = params
        self.fields = fields
        self._position_info = None

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

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



def _parse_function_106(_text, _pos):
    # <String value='class'>
    value13 = 'class'
    end13 = (_pos + 5)
    if (_text[_pos : end13] == value13):
        _pos = (yield (3, _cont__ignored, end13,))[2]
        _status = True
        _result = value13
    else:
        _status = False
        _result = _raise_error106
    # </String>
    (yield (_status, _result, _pos,))


def _parse_function_116(_text, _pos):
    # <String value='{'>
    value14 = '{'
    end14 = (_pos + 1)
    if (_text[_pos : end14] == value14):
        _pos = (yield (3, _cont__ignored, end14,))[2]
        _status = True
        _result = value14
    else:
        _status = False
        _result = _raise_error116
    # </String>
    (yield (_status, _result, _pos,))


def _cont_ClassDef(_text, _pos):
    # <Seq>
    start_pos6 = _pos
    while True:
        # <Discard>
        # kw('class') >> Name
        while True:
            # <Call>
            # kw('class')
            arg9 = _wrap_string_literal('class', _parse_function_106)
            func7 = _ParseFunction(_cont_kw, (arg9,), ())
            (_status, _result, _pos,) = (yield (3, func7, _pos,))
            # </Call>
            if (not _status):
                break
            # <Ref name='Name'>
            (_status, _result, _pos,) = (yield (3, _cont_Name, _pos,))
            # </Ref>
            break
        # </Discard>
        if (not _status):
            break
        name = _result
        # <Opt>
        # Opt(Params)
        backtrack8 = _pos
        # <Ref name='Params'>
        (_status, _result, _pos,) = (yield (3, _cont_Params, _pos,))
        # </Ref>
        if (not _status):
            _status = True
            _pos = backtrack8
            _result = None
        # </Opt>
        params = _result
        # <Discard>
        # (wrap('{') >> (RuleDef /? Sep)) << '}'
        while True:
            # <Discard>
            # wrap('{') >> (RuleDef /? Sep)
            while True:
                # <Call>
                # wrap('{')
                arg10 = _wrap_string_literal('{', _parse_function_116)
                func8 = _ParseFunction(_cont_wrap, (arg10,), ())
                (_status, _result, _pos,) = (yield (3, func8, _pos,))
                # </Call>
                if (not _status):
                    break
                # <Sep>
                # RuleDef /? Sep
                staging6 = []
                checkpoint5 = _pos
                while True:
                    # <Ref name='RuleDef'>
                    (_status, _result, _pos,) = (yield (3, _cont_RuleDef, _pos,))
                    # </Ref>
                    if (not _status):
                        break
                    staging6.append(_result)
                    checkpoint5 = _pos
                    # <Ref name='Sep'>
                    (_status, _result, _pos,) = (yield (3, _cont_Sep, _pos,))
                    # </Ref>
                    if (not _status):
                        break
                    checkpoint5 = _pos
                _result = staging6
                _status = True
                _pos = checkpoint5
                # </Sep>
                break
            # </Discard>
            if (not _status):
                break
            staging7 = _result
            # <String value='}'>
            value15 = '}'
            end15 = (_pos + 1)
            if (_text[_pos : end15] == value15):
                _pos = (yield (3, _cont__ignored, end15,))[2]
                _status = True
                _result = value15
            else:
                _status = False
                _result = _raise_error120
            # </String>
            if _status:
                _result = staging7
            break
        # </Discard>
        if (not _status):
            break
        fields = _result
        _result = ClassDef(name, params, fields)
        _result._position_info = (start_pos6, _pos,)
        break
    # </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 IgnoreStmt(Node):
    """
    class IgnoreStmt {
        expr: IgnoreKeyword >> Expr
    }
    """
    _fields = ('expr',)

    def __init__(self, expr):
        self.expr = expr
        self._position_info = None

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

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



def _cont_IgnoreStmt(_text, _pos):
    # <Seq>
    start_pos7 = _pos
    while True:
        # <Discard>
        # IgnoreKeyword >> Expr
        while True:
            # <Ref name='IgnoreKeyword'>
            (_status, _result, _pos,) = (yield (3, _cont_IgnoreKeyword, _pos,))
            # </Ref>
            if (not _status):
                break
            # <Ref name='Expr'>
            (_status, _result, _pos,) = (yield (3, _cont_Expr, _pos,))
            # </Ref>
            break
        # </Discard>
        if (not _status):
            break
        expr = _result
        _result = IgnoreStmt(expr)
        _result._position_info = (start_pos7, _pos,)
        break
    # </Seq>
    (yield (_status, _result, _pos,))


def _cont_Stmt(_text, _pos):
    # Rule 'Stmt'
    # <Choice>
    backtrack9 = farthest_pos6 = _pos
    farthest_err6 = _raise_error128
    while True:
        # Option 1:
        # <Ref name='ClassDef'>
        (_status, _result, _pos,) = (yield (3, _cont_ClassDef, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos6 < _pos):
            farthest_pos6 = _pos
            farthest_err6 = _result
        _pos = backtrack9
        # Option 2:
        # <Ref name='RuleDef'>
        (_status, _result, _pos,) = (yield (3, _cont_RuleDef, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos6 < _pos):
            farthest_pos6 = _pos
            farthest_err6 = _result
        _pos = backtrack9
        # Option 3:
        # <Ref name='IgnoreStmt'>
        (_status, _result, _pos,) = (yield (3, _cont_IgnoreStmt, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos6 < _pos):
            farthest_pos6 = _pos
            farthest_err6 = _result
        _pos = backtrack9
        # Option 4:
        # <Ref name='PythonSection'>
        (_status, _result, _pos,) = (yield (3, _cont_PythonSection, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos6 < _pos):
            farthest_pos6 = _pos
            farthest_err6 = _result
        _pos = backtrack9
        # Option 5:
        # <Ref name='PythonExpression'>
        (_status, _result, _pos,) = (yield (3, _cont_PythonExpression, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos6 < _pos):
            farthest_pos6 = _pos
            farthest_err6 = _result
        _pos = farthest_pos6
        _result = farthest_err6
        break
    # </Choice>
    (yield (_status, _result, _pos,))


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


Stmt = Rule('Stmt', _parse_Stmt, """
    Stmt = ClassDef | RuleDef | IgnoreStmt | PythonSection | PythonExpression
""")

def _raise_error128(_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):
        self.name = name
        self.expr = expr
        self.body = body
        self._position_info = None

    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, _cont_LetExpression, fullparse)



def _parse_function_141(_text, _pos):
    # <String value='let'>
    value16 = 'let'
    end16 = (_pos + 3)
    if (_text[_pos : end16] == value16):
        _pos = (yield (3, _cont__ignored, end16,))[2]
        _status = True
        _result = value16
    else:
        _status = False
        _result = _raise_error141
    # </String>
    (yield (_status, _result, _pos,))


def _parse_function_145(_text, _pos):
    # <String value='='>
    value17 = '='
    end17 = (_pos + 1)
    if (_text[_pos : end17] == value17):
        _pos = (yield (3, _cont__ignored, end17,))[2]
        _status = True
        _result = value17
    else:
        _status = False
        _result = _raise_error145
    # </String>
    (yield (_status, _result, _pos,))


def _parse_function_153(_text, _pos):
    # <String value='in'>
    value18 = 'in'
    end18 = (_pos + 2)
    if (_text[_pos : end18] == value18):
        _pos = (yield (3, _cont__ignored, end18,))[2]
        _status = True
        _result = value18
    else:
        _status = False
        _result = _raise_error153
    # </String>
    (yield (_status, _result, _pos,))


def _parse_function_151(_text, _pos):
    # <Call>
    # kw('in')
    arg11 = _wrap_string_literal('in', _parse_function_153)
    func9 = _ParseFunction(_cont_kw, (arg11,), ())
    (_status, _result, _pos,) = (yield (3, func9, _pos,))
    # </Call>
    (yield (_status, _result, _pos,))


def _cont_LetExpression(_text, _pos):
    # <Seq>
    start_pos8 = _pos
    while True:
        # <Discard>
        # (kw('let') >> Name) << wrap('=')
        while True:
            # <Discard>
            # kw('let') >> Name
            while True:
                # <Call>
                # kw('let')
                arg12 = _wrap_string_literal('let', _parse_function_141)
                func10 = _ParseFunction(_cont_kw, (arg12,), ())
                (_status, _result, _pos,) = (yield (3, func10, _pos,))
                # </Call>
                if (not _status):
                    break
                # <Ref name='Name'>
                (_status, _result, _pos,) = (yield (3, _cont_Name, _pos,))
                # </Ref>
                break
            # </Discard>
            if (not _status):
                break
            staging8 = _result
            # <Call>
            # wrap('=')
            arg13 = _wrap_string_literal('=', _parse_function_145)
            func11 = _ParseFunction(_cont_wrap, (arg13,), ())
            (_status, _result, _pos,) = (yield (3, func11, _pos,))
            # </Call>
            if _status:
                _result = staging8
            break
        # </Discard>
        if (not _status):
            break
        name = _result
        # <Discard>
        # Expr << wrap(kw('in'))
        while True:
            # <Ref name='Expr'>
            (_status, _result, _pos,) = (yield (3, _cont_Expr, _pos,))
            # </Ref>
            if (not _status):
                break
            staging9 = _result
            # <Call>
            # wrap(kw('in'))
            func12 = _ParseFunction(_cont_wrap, (_parse_function_151,), ())
            (_status, _result, _pos,) = (yield (3, func12, _pos,))
            # </Call>
            if _status:
                _result = staging9
            break
        # </Discard>
        if (not _status):
            break
        expr = _result
        # <Ref name='Expr'>
        (_status, _result, _pos,) = (yield (3, _cont_Expr, _pos,))
        # </Ref>
        if (not _status):
            break
        body = _result
        _result = LetExpression(name, expr, body)
        _result._position_info = (start_pos8, _pos,)
        break
    # </Seq>
    (yield (_status, _result, _pos,))


def _raise_error141(_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_error145(_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_error153(_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):
        self.value = value
        self._position_info = None

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

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



def _cont_Ref(_text, _pos):
    # <Seq>
    start_pos9 = _pos
    while True:
        # <Ref name='Name'>
        (_status, _result, _pos,) = (yield (3, _cont_Name, _pos,))
        # </Ref>
        if (not _status):
            break
        value = _result
        _result = Ref(value)
        _result._position_info = (start_pos9, _pos,)
        break
    # </Seq>
    (yield (_status, _result, _pos,))


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

    def __init__(self, elements):
        self.elements = elements
        self._position_info = None

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

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



def _cont_ListLiteral(_text, _pos):
    # <Seq>
    start_pos10 = _pos
    while True:
        # <Discard>
        # ('[' >> (wrap(Expr) /? Comma)) << ']'
        while True:
            # <Discard>
            # '[' >> (wrap(Expr) /? Comma)
            while True:
                # <String value='['>
                value19 = '['
                end19 = (_pos + 1)
                if (_text[_pos : end19] == value19):
                    _pos = (yield (3, _cont__ignored, end19,))[2]
                    _status = True
                    _result = value19
                else:
                    _status = False
                    _result = _raise_error165
                # </String>
                if (not _status):
                    break
                # <Sep>
                # wrap(Expr) /? Comma
                staging10 = []
                checkpoint6 = _pos
                while True:
                    # <Call>
                    # wrap(Expr)
                    func13 = _ParseFunction(_cont_wrap, (_cont_Expr,), ())
                    (_status, _result, _pos,) = (yield (3, func13, _pos,))
                    # </Call>
                    if (not _status):
                        break
                    staging10.append(_result)
                    checkpoint6 = _pos
                    # <Ref name='Comma'>
                    (_status, _result, _pos,) = (yield (3, _cont_Comma, _pos,))
                    # </Ref>
                    if (not _status):
                        break
                    checkpoint6 = _pos
                _result = staging10
                _status = True
                _pos = checkpoint6
                # </Sep>
                break
            # </Discard>
            if (not _status):
                break
            staging11 = _result
            # <String value=']'>
            value20 = ']'
            end20 = (_pos + 1)
            if (_text[_pos : end20] == value20):
                _pos = (yield (3, _cont__ignored, end20,))[2]
                _status = True
                _result = value20
            else:
                _status = False
                _result = _raise_error171
            # </String>
            if _status:
                _result = staging11
            break
        # </Discard>
        if (not _status):
            break
        elements = _result
        _result = ListLiteral(elements)
        _result._position_info = (start_pos10, _pos,)
        break
    # </Seq>
    (yield (_status, _result, _pos,))


def _raise_error165(_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_error171(_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 _cont_Atom(_text, _pos):
    # Rule 'Atom'
    # <Choice>
    backtrack10 = farthest_pos7 = _pos
    farthest_err7 = _raise_error173
    while True:
        # Option 1:
        # <Discard>
        # ('(' >> wrap(Expr)) << ')'
        while True:
            # <Discard>
            # '(' >> wrap(Expr)
            while True:
                # <String value='('>
                value21 = '('
                end21 = (_pos + 1)
                if (_text[_pos : end21] == value21):
                    _pos = (yield (3, _cont__ignored, end21,))[2]
                    _status = True
                    _result = value21
                else:
                    _status = False
                    _result = _raise_error176
                # </String>
                if (not _status):
                    break
                # <Call>
                # wrap(Expr)
                func14 = _ParseFunction(_cont_wrap, (_cont_Expr,), ())
                (_status, _result, _pos,) = (yield (3, func14, _pos,))
                # </Call>
                break
            # </Discard>
            if (not _status):
                break
            staging12 = _result
            # <String value=')'>
            value22 = ')'
            end22 = (_pos + 1)
            if (_text[_pos : end22] == value22):
                _pos = (yield (3, _cont__ignored, end22,))[2]
                _status = True
                _result = value22
            else:
                _status = False
                _result = _raise_error180
            # </String>
            if _status:
                _result = staging12
            break
        # </Discard>
        if _status:
            break
        if (farthest_pos7 < _pos):
            farthest_pos7 = _pos
            farthest_err7 = _result
        _pos = backtrack10
        # Option 2:
        # <Ref name='StringLiteral'>
        (_status, _result, _pos,) = (yield (3, _cont_StringLiteral, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos7 < _pos):
            farthest_pos7 = _pos
            farthest_err7 = _result
        _pos = backtrack10
        # Option 3:
        # <Ref name='RegexLiteral'>
        (_status, _result, _pos,) = (yield (3, _cont_RegexLiteral, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos7 < _pos):
            farthest_pos7 = _pos
            farthest_err7 = _result
        _pos = backtrack10
        # Option 4:
        # <Ref name='LetExpression'>
        (_status, _result, _pos,) = (yield (3, _cont_LetExpression, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos7 < _pos):
            farthest_pos7 = _pos
            farthest_err7 = _result
        _pos = backtrack10
        # Option 5:
        # <Ref name='ListLiteral'>
        (_status, _result, _pos,) = (yield (3, _cont_ListLiteral, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos7 < _pos):
            farthest_pos7 = _pos
            farthest_err7 = _result
        _pos = backtrack10
        # Option 6:
        # <Ref name='PythonExpression'>
        (_status, _result, _pos,) = (yield (3, _cont_PythonExpression, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos7 < _pos):
            farthest_pos7 = _pos
            farthest_err7 = _result
        _pos = backtrack10
        # Option 7:
        # <Ref name='Ref'>
        (_status, _result, _pos,) = (yield (3, _cont_Ref, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos7 < _pos):
            farthest_pos7 = _pos
            farthest_err7 = _result
        _pos = farthest_pos7
        _result = farthest_err7
        break
    # </Choice>
    (yield (_status, _result, _pos,))


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


Atom = Rule('Atom', _parse_Atom, """
    Atom = ('(' >> wrap(Expr)) << ')' | StringLiteral | RegexLiteral | LetExpression | ListLiteral | PythonExpression | Ref
""")

def _raise_error173(_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"
    "    ('(' >> wrap(Expr)) << ')' | StringLiteral | RegexLiteral | LetExpression | ListLiteral | PythonExpression | Ref\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error176(_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"
    "    '('\n\n"
    "Expected to match the string '('"
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error180(_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"
    "    ')'\n\n"
    "Expected to match the string ')'"
    )
    raise ParseError((title + details), _pos, line, col)


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

    def __init__(self, name, expr):
        self.name = name
        self.expr = expr
        self._position_info = None

    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, _cont_KeywordArg, fullparse)



def _cont_KeywordArg(_text, _pos):
    # <Seq>
    start_pos11 = _pos
    while True:
        # <Discard>
        # Name << ('=' | ':')
        while True:
            # <Ref name='Name'>
            (_status, _result, _pos,) = (yield (3, _cont_Name, _pos,))
            # </Ref>
            if (not _status):
                break
            staging13 = _result
            # <Choice>
            backtrack11 = farthest_pos8 = _pos
            farthest_err8 = _raise_error192
            while True:
                # Option 1:
                # <String value='='>
                value23 = '='
                end23 = (_pos + 1)
                if (_text[_pos : end23] == value23):
                    _pos = (yield (3, _cont__ignored, end23,))[2]
                    _status = True
                    _result = value23
                else:
                    _status = False
                    _result = _raise_error193
                # </String>
                if _status:
                    break
                if (farthest_pos8 < _pos):
                    farthest_pos8 = _pos
                    farthest_err8 = _result
                _pos = backtrack11
                # Option 2:
                # <String value=':'>
                value24 = ':'
                end24 = (_pos + 1)
                if (_text[_pos : end24] == value24):
                    _pos = (yield (3, _cont__ignored, end24,))[2]
                    _status = True
                    _result = value24
                else:
                    _status = False
                    _result = _raise_error194
                # </String>
                if _status:
                    break
                if (farthest_pos8 < _pos):
                    farthest_pos8 = _pos
                    farthest_err8 = _result
                _pos = farthest_pos8
                _result = farthest_err8
                break
            # </Choice>
            if _status:
                _result = staging13
            break
        # </Discard>
        if (not _status):
            break
        name = _result
        # <Ref name='Expr'>
        (_status, _result, _pos,) = (yield (3, _cont_Expr, _pos,))
        # </Ref>
        if (not _status):
            break
        expr = _result
        _result = KeywordArg(name, expr)
        _result._position_info = (start_pos11, _pos,)
        break
    # </Seq>
    (yield (_status, _result, _pos,))


def _raise_error192(_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_error193(_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_error194(_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):
        self.args = args
        self._position_info = None

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

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



def _parse_function_206(_text, _pos):
    # <Choice>
    backtrack12 = farthest_pos9 = _pos
    farthest_err9 = _raise_error206
    while True:
        # Option 1:
        # <Ref name='KeywordArg'>
        (_status, _result, _pos,) = (yield (3, _cont_KeywordArg, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos9 < _pos):
            farthest_pos9 = _pos
            farthest_err9 = _result
        _pos = backtrack12
        # Option 2:
        # <Ref name='Expr'>
        (_status, _result, _pos,) = (yield (3, _cont_Expr, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos9 < _pos):
            farthest_pos9 = _pos
            farthest_err9 = _result
        _pos = farthest_pos9
        _result = farthest_err9
        break
    # </Choice>
    (yield (_status, _result, _pos,))


def _cont_ArgList(_text, _pos):
    # <Seq>
    start_pos12 = _pos
    while True:
        # <Discard>
        # ('(' >> (wrap(KeywordArg | Expr) /? Comma)) << ')'
        while True:
            # <Discard>
            # '(' >> (wrap(KeywordArg | Expr) /? Comma)
            while True:
                # <String value='('>
                value25 = '('
                end25 = (_pos + 1)
                if (_text[_pos : end25] == value25):
                    _pos = (yield (3, _cont__ignored, end25,))[2]
                    _status = True
                    _result = value25
                else:
                    _status = False
                    _result = _raise_error202
                # </String>
                if (not _status):
                    break
                # <Sep>
                # wrap(KeywordArg | Expr) /? Comma
                staging14 = []
                checkpoint7 = _pos
                while True:
                    # <Call>
                    # wrap(KeywordArg | Expr)
                    func15 = _ParseFunction(_cont_wrap, (_parse_function_206,), ())
                    (_status, _result, _pos,) = (yield (3, func15, _pos,))
                    # </Call>
                    if (not _status):
                        break
                    staging14.append(_result)
                    checkpoint7 = _pos
                    # <Ref name='Comma'>
                    (_status, _result, _pos,) = (yield (3, _cont_Comma, _pos,))
                    # </Ref>
                    if (not _status):
                        break
                    checkpoint7 = _pos
                _result = staging14
                _status = True
                _pos = checkpoint7
                # </Sep>
                break
            # </Discard>
            if (not _status):
                break
            staging15 = _result
            # <String value=')'>
            value26 = ')'
            end26 = (_pos + 1)
            if (_text[_pos : end26] == value26):
                _pos = (yield (3, _cont__ignored, end26,))[2]
                _status = True
                _result = value26
            else:
                _status = False
                _result = _raise_error210
            # </String>
            if _status:
                _result = staging15
            break
        # </Discard>
        if (not _status):
            break
        args = _result
        _result = ArgList(args)
        _result._position_info = (start_pos12, _pos,)
        break
    # </Seq>
    (yield (_status, _result, _pos,))


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 'ArgList' rule, at the expression:\n"
    "    '('\n\n"
    "Expected to match the string '('"
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error206(_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_error210(_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_225(_text, _pos):
    # <Choice>
    backtrack13 = farthest_pos10 = _pos
    farthest_err10 = _raise_error225
    while True:
        # Option 1:
        # <String value='//'>
        value27 = '//'
        end27 = (_pos + 2)
        if (_text[_pos : end27] == value27):
            _pos = (yield (3, _cont__ignored, end27,))[2]
            _status = True
            _result = value27
        else:
            _status = False
            _result = _raise_error226
        # </String>
        if _status:
            break
        if (farthest_pos10 < _pos):
            farthest_pos10 = _pos
            farthest_err10 = _result
        _pos = backtrack13
        # Option 2:
        # <String value='/?'>
        value28 = '/?'
        end28 = (_pos + 2)
        if (_text[_pos : end28] == value28):
            _pos = (yield (3, _cont__ignored, end28,))[2]
            _status = True
            _result = value28
        else:
            _status = False
            _result = _raise_error227
        # </String>
        if _status:
            break
        if (farthest_pos10 < _pos):
            farthest_pos10 = _pos
            farthest_err10 = _result
        _pos = farthest_pos10
        _result = farthest_err10
        break
    # </Choice>
    (yield (_status, _result, _pos,))


def _parse_function_231(_text, _pos):
    # <Choice>
    backtrack14 = farthest_pos11 = _pos
    farthest_err11 = _raise_error231
    while True:
        # Option 1:
        # <String value='<<'>
        value29 = '<<'
        end29 = (_pos + 2)
        if (_text[_pos : end29] == value29):
            _pos = (yield (3, _cont__ignored, end29,))[2]
            _status = True
            _result = value29
        else:
            _status = False
            _result = _raise_error232
        # </String>
        if _status:
            break
        if (farthest_pos11 < _pos):
            farthest_pos11 = _pos
            farthest_err11 = _result
        _pos = backtrack14
        # Option 2:
        # <String value='>>'>
        value30 = '>>'
        end30 = (_pos + 2)
        if (_text[_pos : end30] == value30):
            _pos = (yield (3, _cont__ignored, end30,))[2]
            _status = True
            _result = value30
        else:
            _status = False
            _result = _raise_error233
        # </String>
        if _status:
            break
        if (farthest_pos11 < _pos):
            farthest_pos11 = _pos
            farthest_err11 = _result
        _pos = farthest_pos11
        _result = farthest_err11
        break
    # </Choice>
    (yield (_status, _result, _pos,))


def _parse_function_237(_text, _pos):
    # <Choice>
    backtrack15 = farthest_pos12 = _pos
    farthest_err12 = _raise_error237
    while True:
        # Option 1:
        # <String value='<|'>
        value31 = '<|'
        end31 = (_pos + 2)
        if (_text[_pos : end31] == value31):
            _pos = (yield (3, _cont__ignored, end31,))[2]
            _status = True
            _result = value31
        else:
            _status = False
            _result = _raise_error238
        # </String>
        if _status:
            break
        if (farthest_pos12 < _pos):
            farthest_pos12 = _pos
            farthest_err12 = _result
        _pos = backtrack15
        # Option 2:
        # <String value='|>'>
        value32 = '|>'
        end32 = (_pos + 2)
        if (_text[_pos : end32] == value32):
            _pos = (yield (3, _cont__ignored, end32,))[2]
            _status = True
            _result = value32
        else:
            _status = False
            _result = _raise_error239
        # </String>
        if _status:
            break
        if (farthest_pos12 < _pos):
            farthest_pos12 = _pos
            farthest_err12 = _result
        _pos = backtrack15
        # Option 3:
        # <String value='where'>
        value33 = 'where'
        end33 = (_pos + 5)
        if (_text[_pos : end33] == value33):
            _pos = (yield (3, _cont__ignored, end33,))[2]
            _status = True
            _result = value33
        else:
            _status = False
            _result = _raise_error240
        # </String>
        if _status:
            break
        if (farthest_pos12 < _pos):
            farthest_pos12 = _pos
            farthest_err12 = _result
        _pos = farthest_pos12
        _result = farthest_err12
        break
    # </Choice>
    (yield (_status, _result, _pos,))


def _parse_function_244(_text, _pos):
    # <String value='|'>
    value34 = '|'
    end34 = (_pos + 1)
    if (_text[_pos : end34] == value34):
        _pos = (yield (3, _cont__ignored, end34,))[2]
        _status = True
        _result = value34
    else:
        _status = False
        _result = _raise_error244
    # </String>
    (yield (_status, _result, _pos,))


def _cont_Expr(_text, _pos):
    # Rule 'Expr'
    # <OperatorPrecedence>
    """
    OperatorPrecedence(
        Atom,
        Postfix(ArgList),
        Postfix('?' | '*' | '+' | Repeat),
        LeftAssoc(wrap('//' | '/?')),
        LeftAssoc(wrap('<<' | '>>')),
        LeftAssoc(wrap('<|' | '|>' | 'where')),
        LeftAssoc(wrap('|'))
    )
    """
    # <LeftAssoc>
    # LeftAssoc(wrap('|'))
    is_first1 = True
    staging16 = None
    while True:
        # <LeftAssoc>
        # LeftAssoc(wrap('<|' | '|>' | 'where'))
        is_first2 = True
        staging17 = None
        while True:
            # <LeftAssoc>
            # LeftAssoc(wrap('<<' | '>>'))
            is_first3 = True
            staging18 = None
            while True:
                # <LeftAssoc>
                # LeftAssoc(wrap('//' | '/?'))
                is_first4 = True
                staging19 = None
                while True:
                    # <Postfix>
                    # Postfix('?' | '*' | '+' | Repeat)
                    # <Postfix>
                    # Postfix(ArgList)
                    # <Ref name='Atom'>
                    (_status, _result, _pos,) = (yield (3, _cont_Atom, _pos,))
                    # </Ref>
                    if _status:
                        staging20 = _result
                        checkpoint8 = _pos
                        while True:
                            # <Ref name='ArgList'>
                            (_status, _result, _pos,) = (yield (3, _cont_ArgList, _pos,))
                            # </Ref>
                            if _status:
                                staging20 = Postfix(staging20, _result)
                                checkpoint8 = _pos
                            else:
                                _status = True
                                _result = staging20
                                _pos = checkpoint8
                                break
                    # </Postfix>
                    if _status:
                        staging21 = _result
                        checkpoint9 = _pos
                        while True:
                            # <Choice>
                            backtrack16 = farthest_pos13 = _pos
                            farthest_err13 = _raise_error217
                            while True:
                                # Option 1:
                                # <String value='?'>
                                value35 = '?'
                                end35 = (_pos + 1)
                                if (_text[_pos : end35] == value35):
                                    _pos = (yield (3, _cont__ignored, end35,))[2]
                                    _status = True
                                    _result = value35
                                else:
                                    _status = False
                                    _result = _raise_error218
                                # </String>
                                if _status:
                                    break
                                if (farthest_pos13 < _pos):
                                    farthest_pos13 = _pos
                                    farthest_err13 = _result
                                _pos = backtrack16
                                # Option 2:
                                # <String value='*'>
                                value36 = '*'
                                end36 = (_pos + 1)
                                if (_text[_pos : end36] == value36):
                                    _pos = (yield (3, _cont__ignored, end36,))[2]
                                    _status = True
                                    _result = value36
                                else:
                                    _status = False
                                    _result = _raise_error219
                                # </String>
                                if _status:
                                    break
                                if (farthest_pos13 < _pos):
                                    farthest_pos13 = _pos
                                    farthest_err13 = _result
                                _pos = backtrack16
                                # Option 3:
                                # <String value='+'>
                                value37 = '+'
                                end37 = (_pos + 1)
                                if (_text[_pos : end37] == value37):
                                    _pos = (yield (3, _cont__ignored, end37,))[2]
                                    _status = True
                                    _result = value37
                                else:
                                    _status = False
                                    _result = _raise_error220
                                # </String>
                                if _status:
                                    break
                                if (farthest_pos13 < _pos):
                                    farthest_pos13 = _pos
                                    farthest_err13 = _result
                                _pos = backtrack16
                                # Option 4:
                                # <Ref name='Repeat'>
                                (_status, _result, _pos,) = (yield (3, _cont_Repeat, _pos,))
                                # </Ref>
                                if _status:
                                    break
                                if (farthest_pos13 < _pos):
                                    farthest_pos13 = _pos
                                    farthest_err13 = _result
                                _pos = farthest_pos13
                                _result = farthest_err13
                                break
                            # </Choice>
                            if _status:
                                staging21 = Postfix(staging21, _result)
                                checkpoint9 = _pos
                            else:
                                _status = True
                                _result = staging21
                                _pos = checkpoint9
                                break
                    # </Postfix>
                    if (not _status):
                        break
                    checkpoint10 = _pos
                    if is_first4:
                        is_first4 = False
                        staging19 = _result
                    else:
                        staging19 = Infix(staging19, operator1, _result)
                    # <Call>
                    # wrap('//' | '/?')
                    func16 = _ParseFunction(_cont_wrap, (_parse_function_225,), ())
                    (_status, _result, _pos,) = (yield (3, func16, _pos,))
                    # </Call>
                    if (not _status):
                        break
                    operator1 = _result
                if (not is_first4):
                    _status = True
                    _result = staging19
                    _pos = checkpoint10
                # </LeftAssoc>
                if (not _status):
                    break
                checkpoint11 = _pos
                if is_first3:
                    is_first3 = False
                    staging18 = _result
                else:
                    staging18 = Infix(staging18, operator2, _result)
                # <Call>
                # wrap('<<' | '>>')
                func17 = _ParseFunction(_cont_wrap, (_parse_function_231,), ())
                (_status, _result, _pos,) = (yield (3, func17, _pos,))
                # </Call>
                if (not _status):
                    break
                operator2 = _result
            if (not is_first3):
                _status = True
                _result = staging18
                _pos = checkpoint11
            # </LeftAssoc>
            if (not _status):
                break
            checkpoint12 = _pos
            if is_first2:
                is_first2 = False
                staging17 = _result
            else:
                staging17 = Infix(staging17, operator3, _result)
            # <Call>
            # wrap('<|' | '|>' | 'where')
            func18 = _ParseFunction(_cont_wrap, (_parse_function_237,), ())
            (_status, _result, _pos,) = (yield (3, func18, _pos,))
            # </Call>
            if (not _status):
                break
            operator3 = _result
        if (not is_first2):
            _status = True
            _result = staging17
            _pos = checkpoint12
        # </LeftAssoc>
        if (not _status):
            break
        checkpoint13 = _pos
        if is_first1:
            is_first1 = False
            staging16 = _result
        else:
            staging16 = Infix(staging16, operator4, _result)
        # <Call>
        # wrap('|')
        arg14 = _wrap_string_literal('|', _parse_function_244)
        func19 = _ParseFunction(_cont_wrap, (arg14,), ())
        (_status, _result, _pos,) = (yield (3, func19, _pos,))
        # </Call>
        if (not _status):
            break
        operator4 = _result
    if (not is_first1):
        _status = True
        _result = staging16
        _pos = checkpoint13
    # </LeftAssoc>
    # </OperatorPrecedence>
    (yield (_status, _result, _pos,))


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


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

def _raise_error217(_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_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 'Expr' rule, at the expression:\n"
    "    '?'\n\n"
    "Expected to match the string '?'"
    )
    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 'Expr' 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 'Expr' rule, at the expression:\n"
    "    '+'\n\n"
    "Expected to match the string '+'"
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error225(_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_error226(_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_error227(_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_error231(_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_error232(_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_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 'Expr' rule, at the expression:\n"
    "    '>>'\n\n"
    "Expected to match the string '>>'"
    )
    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 'Expr' rule, at the expression:\n"
    "    '<|' | '|>' | 'where'\n\n"
    'Unexpected input'
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error238(_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_error239(_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_error240(_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_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)


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):
        self.open = open
        self.start = start
        self.stop = stop
        self.close = close
        self._position_info = None

    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, _cont_Repeat, fullparse)



def _cont_Repeat(_text, _pos):
    # <Seq>
    start_pos13 = _pos
    while True:
        # <String value='{'>
        value38 = '{'
        end38 = (_pos + 1)
        if (_text[_pos : end38] == value38):
            _pos = (yield (3, _cont__ignored, end38,))[2]
            _status = True
            _result = value38
        else:
            _status = False
            _result = _raise_error248
        # </String>
        if (not _status):
            break
        open = _result
        # <Opt>
        # Opt(RepeatArg)
        backtrack17 = _pos
        # <Ref name='RepeatArg'>
        (_status, _result, _pos,) = (yield (3, _cont_RepeatArg, _pos,))
        # </Ref>
        if (not _status):
            _status = True
            _pos = backtrack17
            _result = None
        # </Opt>
        start = _result
        # <Choice>
        backtrack18 = _pos
        while True:
            # Option 1:
            # <Discard>
            # ',' >> RepeatArg
            while True:
                # <String value=','>
                value39 = ','
                end39 = (_pos + 1)
                if (_text[_pos : end39] == value39):
                    _pos = (yield (3, _cont__ignored, end39,))[2]
                    _status = True
                    _result = value39
                else:
                    _status = False
                    _result = _raise_error255
                # </String>
                if (not _status):
                    break
                # <Ref name='RepeatArg'>
                (_status, _result, _pos,) = (yield (3, _cont_RepeatArg, _pos,))
                # </Ref>
                break
            # </Discard>
            if _status:
                break
            _pos = backtrack18
            # Option 2:
            # <Discard>
            # ',' >> `None`
            while True:
                # <String value=','>
                value40 = ','
                end40 = (_pos + 1)
                if (_text[_pos : end40] == value40):
                    _pos = (yield (3, _cont__ignored, end40,))[2]
                    _status = True
                    _result = value40
                else:
                    _status = False
                    _result = _raise_error258
                # </String>
                if (not _status):
                    break
                _result = None
                _status = True
                break
            # </Discard>
            if _status:
                break
            _pos = backtrack18
            # Option 3:
            _result = start
            _status = True
            break
            break
        # </Choice>
        stop = _result
        # <String value='}'>
        value41 = '}'
        end41 = (_pos + 1)
        if (_text[_pos : end41] == value41):
            _pos = (yield (3, _cont__ignored, end41,))[2]
            _status = True
            _result = value41
        else:
            _status = False
            _result = _raise_error262
        # </String>
        if (not _status):
            break
        close = _result
        _result = Repeat(open, start, stop, close)
        _result._position_info = (start_pos13, _pos,)
        break
    # </Seq>
    (yield (_status, _result, _pos,))


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 'Repeat' 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 'Repeat' rule, at the expression:\n"
    "    ','\n\n"
    "Expected to match the string ','"
    )
    raise ParseError((title + details), _pos, line, col)


def _raise_error258(_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_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 'Repeat' rule, at the expression:\n"
    "    '}'\n\n"
    "Expected to match the string '}'"
    )
    raise ParseError((title + details), _pos, line, col)


def _cont_RepeatArg(_text, _pos):
    # Rule 'RepeatArg'
    # <Choice>
    backtrack19 = farthest_pos14 = _pos
    farthest_err14 = _raise_error264
    while True:
        # Option 1:
        # <Ref name='PythonExpression'>
        (_status, _result, _pos,) = (yield (3, _cont_PythonExpression, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos14 < _pos):
            farthest_pos14 = _pos
            farthest_err14 = _result
        _pos = backtrack19
        # Option 2:
        # <Ref name='Ref'>
        (_status, _result, _pos,) = (yield (3, _cont_Ref, _pos,))
        # </Ref>
        if _status:
            break
        if (farthest_pos14 < _pos):
            farthest_pos14 = _pos
            farthest_err14 = _result
        _pos = farthest_pos14
        _result = farthest_err14
        break
    # </Choice>
    (yield (_status, _result, _pos,))


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


RepeatArg = Rule('RepeatArg', _parse_RepeatArg, """
    RepeatArg = PythonExpression | Ref
""")

def _raise_error264(_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 _cont_ManyStmts(_text, _pos):
    # Rule 'ManyStmts'
    # <Sep>
    # Stmt /? Sep
    staging22 = []
    checkpoint14 = _pos
    while True:
        # <Ref name='Stmt'>
        (_status, _result, _pos,) = (yield (3, _cont_Stmt, _pos,))
        # </Ref>
        if (not _status):
            break
        staging22.append(_result)
        checkpoint14 = _pos
        # <Ref name='Sep'>
        (_status, _result, _pos,) = (yield (3, _cont_Sep, _pos,))
        # </Ref>
        if (not _status):
            break
        checkpoint14 = _pos
    if staging22:
        _result = staging22
        _status = True
        _pos = checkpoint14
    # </Sep>
    (yield (_status, _result, _pos,))


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


ManyStmts = Rule('ManyStmts', _parse_ManyStmts, """
    ManyStmts = Stmt /? Sep
""")

def _cont_SingleExpr(_text, _pos):
    # Rule 'SingleExpr'
    # <Discard>
    # Expr << Opt(Sep)
    while True:
        # <Ref name='Expr'>
        (_status, _result, _pos,) = (yield (3, _cont_Expr, _pos,))
        # </Ref>
        if (not _status):
            break
        staging23 = _result
        # <Opt>
        # Opt(Sep)
        backtrack20 = _pos
        # <Ref name='Sep'>
        (_status, _result, _pos,) = (yield (3, _cont_Sep, _pos,))
        # </Ref>
        if (not _status):
            _status = True
            _pos = backtrack20
            _result = None
        # </Opt>
        _result = staging23
        break
    # </Discard>
    (yield (_status, _result, _pos,))


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


SingleExpr = Rule('SingleExpr', _parse_SingleExpr, """
    SingleExpr = Expr << Opt(Sep)
""")

def _cont_start(_text, _pos):
    # Rule 'start'
    # <Discard>
    # _cont__ignored >> (Skip(Newline) >> (ManyStmts | SingleExpr))
    while True:
        # <Ref name='_cont__ignored'>
        (_status, _result, _pos,) = (yield (3, _cont__ignored, _pos,))
        # </Ref>
        if (not _status):
            break
        # <Discard>
        # Skip(Newline) >> (ManyStmts | SingleExpr)
        while True:
            # <Skip>
            # Skip(Newline)
            while True:
                checkpoint15 = _pos
                # <Ref name='Newline'>
                (_status, _result, _pos,) = (yield (3, _cont_Newline, _pos,))
                # </Ref>
                if _status:
                    continue
                else:
                    _pos = checkpoint15
                break
            _status = True
            _result = None
            # </Skip>
            # <Choice>
            backtrack21 = farthest_pos15 = _pos
            farthest_err15 = _raise_error282
            while True:
                # Option 1:
                # <Ref name='ManyStmts'>
                (_status, _result, _pos,) = (yield (3, _cont_ManyStmts, _pos,))
                # </Ref>
                if _status:
                    break
                if (farthest_pos15 < _pos):
                    farthest_pos15 = _pos
                    farthest_err15 = _result
                _pos = backtrack21
                # Option 2:
                # <Ref name='SingleExpr'>
                (_status, _result, _pos,) = (yield (3, _cont_SingleExpr, _pos,))
                # </Ref>
                if _status:
                    break
                if (farthest_pos15 < _pos):
                    farthest_pos15 = _pos
                    farthest_err15 = _result
                _pos = farthest_pos15
                _result = farthest_err15
                break
            # </Choice>
            break
        # </Discard>
        break
    # </Discard>
    (yield (_status, _result, _pos,))


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


start = Rule('start', _parse_start, """
    start = _cont__ignored >> (Skip(Newline) >> (ManyStmts | SingleExpr))
""")

def _raise_error282(_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 _cont__ignored(_text, _pos):
    # Rule '_ignored'
    # <Skip>
    # Skip(Space, Comment)
    while True:
        checkpoint16 = _pos
        # <Ref name='Space'>
        (_status, _result, _pos,) = (yield (3, _cont_Space, _pos,))
        # </Ref>
        if _status:
            continue
        else:
            _pos = checkpoint16
        # <Ref name='Comment'>
        (_status, _result, _pos,) = (yield (3, _cont_Comment, _pos,))
        # </Ref>
        if _status:
            continue
        else:
            _pos = checkpoint16
        break
    _status = True
    _result = None
    # </Skip>
    (yield (_status, _result, _pos,))


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


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

