#!/usr/bin/env python3
# copyright: ignore
#
# CAVEAT UTILITOR
#
#  This file was automatically generated by 竜TatSu v5.18.0b1
#
#     https://pypi.python.org/pypi/tatsu/
#
#  Any changes you make to it will be overwritten the next time
#  the file is generated.
#
# noqa # type: ignore # ruff: noqa
# fmt: off

from __future__ import annotations

from typing import Any

from tatsu import decorators as tatsu
from tatsu.contexts import Ctx
from tatsu.parserconfig import ParserConfig
from tatsu.parsing import Parser, generic_main
from tatsu.tokenizing.buffer import Buffer
from tatsu.tokenizing.textlines import TextLinesTokenizer


KEYWORDS: set[str] = set()


class TatSuBootstrapTokenizer(TextLinesTokenizer):
    def __init__(
        self,
        text, /,
        config: ParserConfig | None = None,
        **settings,
    ) -> None:
        config = ParserConfig.new(
            config=config,
            whitespace=r'(?m)\s+',
            nameguard=None,
            ignorecase=False,
            namechars='',
            parseinfo=True,
            comments=r'(?ms)[(][*]\s*((?:.|\n)*?)\s*[*][)]|[\/][*]\s*((?:.|\n)*?)\s*[*][\/]',
            eol_comments=r'(?ms)(?:[#]|[\/][\/])(.*?)$',
            keywords=KEYWORDS,
            start='start',
        )
        assert isinstance(config, ParserConfig)
        config = config.override(**settings)

        super().__init__(text, config=config)


class TatSuBootstrapBuffer(Buffer):  # NOTE: backwards compatibility
    def __init__(
        self,
        text, /,
        config: ParserConfig | None = None,
        **settings,
    ) -> None:
        config = ParserConfig.new(
            config=config,
            whitespace=r'(?m)\s+',
            nameguard=None,
            ignorecase=False,
            namechars='',
            parseinfo=True,
            comments=r'(?ms)[(][*]\s*((?:.|\n)*?)\s*[*][)]|[\/][*]\s*((?:.|\n)*?)\s*[*][\/]',
            eol_comments=r'(?ms)(?:[#]|[\/][\/])(.*?)$',
            keywords=KEYWORDS,
            start='start',
        )
        assert isinstance(config, ParserConfig)
        config = config.override(**settings)

        super().__init__(text, config=config)


class TatSuBootstrapParser(Parser):
    def __init__(self, /, config: ParserConfig | None = None, **settings):
        config = ParserConfig.new(config, **settings)
        rulessource = TatSuBootstrapRules()
        assert isinstance(config, ParserConfig)
        tokenizercls = config.tokenizercls or TatSuBootstrapTokenizer

        super().__init__(rulessource, config=config, tokenizercls=tokenizercls)


class TatSuBootstrapRules:
    def __init__(self, /, config: ParserConfig | None = None, **settings):
        config = ParserConfig.new(
            config=config,
            whitespace=r'(?m)\s+',
            nameguard=None,
            ignorecase=False,
            namechars='',
            parseinfo=True,
            comments=r'(?ms)[(][*]\s*((?:.|\n)*?)\s*[*][)]|[\/][*]\s*((?:.|\n)*?)\s*[*][\/]',
            eol_comments=r'(?ms)(?:[#]|[\/][\/])(.*?)$',
            keywords=KEYWORDS,
            start='start',
        )
        assert isinstance(config, ParserConfig)
        config = config.override(**settings)
        self._config = config


    @tatsu.rule
    def start(self, ctx: Ctx) -> Any:
        self.grammar(ctx)

    @tatsu.rule('Grammar')
    def grammar(self, ctx: Ctx) -> Any:
        ctx.define(['title'], ['directives', 'keywords', 'rules'])
        with ctx.nameset('title'):
            ctx.constant('TATSU')
        with ctx.loopopt() as cl:
            cl.expecting('<directive>', '<keyword>')

            @cl.exp
            def 〇(ctx: Ctx) -> Any:
                with ctx.choice() as α:
                    @α.option
                    def 〇(ctx: Ctx) -> Any:
                        with ctx.nameadd('directives'):
                            self.directive(ctx)
                    @α.option
                    def 〇(ctx: Ctx) -> Any:
                        with ctx.nameadd('keywords'):
                            self.keyword(ctx)
        with ctx.nameadd('rules'):
            self.rule(ctx)
        with ctx.loopopt() as clβ:
            clβ.expecting('<keyword>', '<rule>')

            @clβ.exp
            def 〇(ctx: Ctx) -> Any:
                with ctx.choice() as α:
                    @α.option
                    def 〇(ctx: Ctx) -> Any:
                        with ctx.nameadd('rules'):
                            self.rule(ctx)
                    @α.option
                    def 〇(ctx: Ctx) -> Any:
                        with ctx.nameadd('keywords'):
                            self.keyword(ctx)
        ctx.eofcheck()

    @tatsu.rule
    def directive(self, ctx: Ctx) -> Any:
        ctx.define(['name', 'value'], [])
        ctx.token('@@')
        with ctx.ifnot_():
            ctx.token('keyword')
        ctx.cut()
        with ctx.group():
            with ctx.choice() as α:
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    ctx.define(['name', 'value'], [])
                    with ctx.nameset('name'):
                        with ctx.group():
                            with ctx.choice() as β:
                                @β.option
                                def 〇(ctx: Ctx) -> Any:
                                    ctx.token('comments')
                                @β.option
                                def 〇(ctx: Ctx) -> Any:
                                    ctx.token('eol_comments')
                    ctx.cut()
                    ctx.token('::')
                    ctx.cut()
                    with ctx.nameset('value'):
                        self.regex(ctx)
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    ctx.define(['name', 'value'], [])
                    with ctx.nameset('name'):
                        ctx.token('whitespace')
                    ctx.cut()
                    ctx.token('::')
                    ctx.cut()
                    with ctx.nameset('value'):
                        with ctx.group():
                            with ctx.choice() as β:
                                @β.option
                                def 〇(ctx: Ctx) -> Any:
                                    self.regex(ctx)
                                @β.option
                                def 〇(ctx: Ctx) -> Any:
                                    self.string(ctx)
                                @β.option
                                def 〇(ctx: Ctx) -> Any:
                                    ctx.token('None')
                                @β.option
                                def 〇(ctx: Ctx) -> Any:
                                    ctx.token('False')
                                @β.option
                                def 〇(ctx: Ctx) -> Any:
                                    ctx.constant('None')
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    ctx.define(['name', 'value'], [])
                    with ctx.nameset('name'):
                        with ctx.group():
                            with ctx.choice() as β:
                                @β.option
                                def 〇(ctx: Ctx) -> Any:
                                    ctx.token('nameguard')
                                @β.option
                                def 〇(ctx: Ctx) -> Any:
                                    ctx.token('ignorecase')
                                @β.option
                                def 〇(ctx: Ctx) -> Any:
                                    ctx.token('left_recursion')
                                @β.option
                                def 〇(ctx: Ctx) -> Any:
                                    ctx.token('parseinfo')
                                @β.option
                                def 〇(ctx: Ctx) -> Any:
                                    ctx.token('memoization')
                    ctx.cut()
                    with ctx.group():
                        with ctx.choice() as β:
                            @β.option
                            def 〇(ctx: Ctx) -> Any:
                                ctx.define(['value'], [])
                                ctx.token('::')
                                ctx.cut()
                                with ctx.nameset('value'):
                                    self.boolean(ctx)
                            @β.option
                            def 〇(ctx: Ctx) -> Any:
                                with ctx.nameset('value'):
                                    ctx.constant(True)
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    ctx.define(['name', 'value'], [])
                    with ctx.nameset('name'):
                        ctx.token('grammar')
                    ctx.cut()
                    ctx.token('::')
                    ctx.cut()
                    with ctx.nameset('value'):
                        self.word(ctx)
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    ctx.define(['name', 'value'], [])
                    with ctx.nameset('name'):
                        ctx.token('namechars')
                    ctx.cut()
                    ctx.token('::')
                    ctx.cut()
                    with ctx.nameset('value'):
                        self.string(ctx)
        ctx.cut()

    @tatsu.rule
    def keywords(self, ctx: Ctx) -> Any:
        with ctx.loopplus() as cl:
            cl.expecting('<keyword>')

            @cl.exp
            def 〇(ctx: Ctx) -> Any:
                self.keyword(ctx)

    @tatsu.rule
    def keyword(self, ctx: Ctx) -> Any:
        ctx.token('@@keyword')
        ctx.cut()
        ctx.token('::')
        ctx.cut()
        with ctx.loopopt() as cl:
            cl.expecting('<string>', '<word>')

            @cl.exp
            def 〇(ctx: Ctx) -> Any:
                with ctx.nameadd('@'):
                    with ctx.group():
                        with ctx.choice() as α:
                            @α.option
                            def 〇(ctx: Ctx) -> Any:
                                self.word(ctx)
                            @α.option
                            def 〇(ctx: Ctx) -> Any:
                                self.string(ctx)
                with ctx.ifnot_():
                    with ctx.group():
                        with ctx.choice() as α:
                            @α.option
                            def 〇(ctx: Ctx) -> Any:
                                ctx.token(':')
                            @α.option
                            def 〇(ctx: Ctx) -> Any:
                                ctx.token('=')

    @tatsu.rule
    def params(self, ctx: Ctx) -> Any:
        with ctx.nameadd('@'):
            self.first_param(ctx)
        with ctx.loopopt() as cl:
            cl.expecting(',')

            @cl.exp
            def 〇(ctx: Ctx) -> Any:
                ctx.token(',')
                with ctx.nameadd('@'):
                    self.literal(ctx)
                with ctx.ifnot_():
                    ctx.token('=')
                ctx.cut()

    @tatsu.rule
    def first_param(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.path(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.literal(ctx)

    @tatsu.rule
    def kwparams(self, ctx: Ctx) -> Any:
        with ctx.gatherplus() as g:
            g.expecting('<pair>')

            @g.sep
            def 〇(ctx: Ctx) -> Any:
                ctx.token(',')

            @g.exp
            def 〇(ctx: Ctx) -> Any:
                self.pair(ctx)

    @tatsu.rule
    def the_params_at_last(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                with ctx.nameset('kwparams'):
                    self.kwparams(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.define(['kwparams', 'params'], [])
                with ctx.nameset('params'):
                    self.params(ctx)
                ctx.token(',')
                ctx.cut()
                with ctx.nameset('kwparams'):
                    self.kwparams(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                with ctx.nameset('params'):
                    self.params(ctx)

    @tatsu.rule
    def paramdef(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.define(['kwparams', 'params'], [])
                ctx.token('[')
                ctx.cut()
                with ctx.choice() as β:
                    @β.option
                    def 〇(ctx: Ctx) -> Any:
                        with ctx.nameset('kwparams'):
                            self.kwparams(ctx)
                    @β.option
                    def 〇(ctx: Ctx) -> Any:
                        ctx.define(['kwparams', 'params'], [])
                        with ctx.nameset('params'):
                            self.params(ctx)
                        ctx.token(',')
                        ctx.cut()
                        with ctx.nameset('kwparams'):
                            self.kwparams(ctx)
                    @β.option
                    def 〇(ctx: Ctx) -> Any:
                        with ctx.nameset('params'):
                            self.params(ctx)
                ctx.token(']')
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.define(['kwparams', 'params'], [])
                ctx.token('(')
                ctx.cut()
                with ctx.choice() as β:
                    @β.option
                    def 〇(ctx: Ctx) -> Any:
                        with ctx.nameset('kwparams'):
                            self.kwparams(ctx)
                    @β.option
                    def 〇(ctx: Ctx) -> Any:
                        ctx.define(['kwparams', 'params'], [])
                        with ctx.nameset('params'):
                            self.params(ctx)
                        ctx.token(',')
                        ctx.cut()
                        with ctx.nameset('kwparams'):
                            self.kwparams(ctx)
                    @β.option
                    def 〇(ctx: Ctx) -> Any:
                        with ctx.nameset('params'):
                            self.params(ctx)
                ctx.token(')')
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.define(['params'], [])
                ctx.token('::')
                ctx.cut()
                with ctx.nameset('params'):
                    self.params(ctx)

    @tatsu.rule('Rule')
    def rule(self, ctx: Ctx) -> Any:
        ctx.define(['base', 'decorators', 'exp', 'kwparams', 'name', 'params'], [])
        with ctx.nameset('decorators'):
            with ctx.loopopt() as cl:
                cl.expecting('<decorator>')

                @cl.exp
                def 〇(ctx: Ctx) -> Any:
                    self.decorator(ctx)
        with ctx.nameset('name'):
            self.name(ctx)
        ctx.cut()
        with ctx.optional():
            with ctx.choice() as α:
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    ctx.define(['kwparams', 'params'], [])
                    ctx.token('[')
                    ctx.cut()
                    with ctx.choice() as β:
                        @β.option
                        def 〇(ctx: Ctx) -> Any:
                            with ctx.nameset('kwparams'):
                                self.kwparams(ctx)
                        @β.option
                        def 〇(ctx: Ctx) -> Any:
                            ctx.define(['kwparams', 'params'], [])
                            with ctx.nameset('params'):
                                self.params(ctx)
                            ctx.token(',')
                            ctx.cut()
                            with ctx.nameset('kwparams'):
                                self.kwparams(ctx)
                        @β.option
                        def 〇(ctx: Ctx) -> Any:
                            with ctx.nameset('params'):
                                self.params(ctx)
                    ctx.token(']')
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    ctx.define(['kwparams', 'params'], [])
                    ctx.token('(')
                    ctx.cut()
                    with ctx.choice() as β:
                        @β.option
                        def 〇(ctx: Ctx) -> Any:
                            with ctx.nameset('kwparams'):
                                self.kwparams(ctx)
                        @β.option
                        def 〇(ctx: Ctx) -> Any:
                            ctx.define(['kwparams', 'params'], [])
                            with ctx.nameset('params'):
                                self.params(ctx)
                            ctx.token(',')
                            ctx.cut()
                            with ctx.nameset('kwparams'):
                                self.kwparams(ctx)
                        @β.option
                        def 〇(ctx: Ctx) -> Any:
                            with ctx.nameset('params'):
                                self.params(ctx)
                    ctx.token(')')
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    ctx.define(['params'], [])
                    ctx.token('::')
                    ctx.cut()
                    with ctx.nameset('params'):
                        self.params(ctx)
        with ctx.optional():
            ctx.define(['base'], [])
            ctx.token('<')
            ctx.cut()
            with ctx.nameset('base'):
                self.known_name(ctx)
        ctx.void()
        ctx.pattern(r'=|:=?')
        ctx.cut()
        with ctx.nameset('exp'):
            self.expre(ctx)
        self.ENDRULE(ctx)
        ctx.cut()

    @tatsu.rule
    def ENDRULE(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                with ctx.if_():
                    self.UNINDENTED(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.EMPTYLINE(ctx)
                with ctx.optional():
                    ctx.token(';')
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.eofcheck()
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.token(';')

    @tatsu.rule
    def UNINDENTED(self, ctx: Ctx) -> Any:
        ctx.pattern(r'(?=\s*(?:\r?\n|\r)[^\s])')

    @tatsu.rule
    def EMPTYLINE(self, ctx: Ctx) -> Any:
        ctx.pattern(r'(?:\s*(?:\r?\n|\r)){2,}')

    @tatsu.rule
    def decorator(self, ctx: Ctx) -> Any:
        ctx.token('@')
        with ctx.ifnot_():
            ctx.token('@')
        ctx.cut()
        with ctx.nameset('@'):
            with ctx.group():
                with ctx.choice() as α:
                    @α.option
                    def 〇(ctx: Ctx) -> Any:
                        ctx.token('override')
                    @α.option
                    def 〇(ctx: Ctx) -> Any:
                        ctx.token('name')
                    @α.option
                    def 〇(ctx: Ctx) -> Any:
                        ctx.token('isname')
                    @α.option
                    def 〇(ctx: Ctx) -> Any:
                        ctx.token('nomemo')

    @tatsu.rule
    def pair(self, ctx: Ctx) -> Any:
        with ctx.nameadd('@'):
            self.word(ctx)
        ctx.token('=')
        ctx.cut()
        with ctx.nameadd('@'):
            self.literal(ctx)

    @tatsu.rule
    def firstexpre(self, ctx: Ctx) -> Any:
        self.firstchoice(ctx)

    @tatsu.rule('FirstChoice')
    def firstchoice(self, ctx: Ctx) -> Any:
        with ctx.optional():
            ctx.token('|')
            ctx.cut()
        with ctx.nameadd('@'):
            self.firstoption(ctx)
        ctx.cut()
        with ctx.loopopt() as cl:
            cl.expecting('|')

            @cl.exp
            def 〇(ctx: Ctx) -> Any:
                ctx.token('|')
                ctx.cut()
                with ctx.nameadd('@'):
                    self.firstoption(ctx)

    @tatsu.rule('FirstOption')
    def firstoption(self, ctx: Ctx) -> Any:
        self.sequence(ctx)

    @tatsu.rule
    def expre(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.choice(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.sequence(ctx)

    @tatsu.rule('Choice')
    def choice(self, ctx: Ctx) -> Any:
        with ctx.optional():
            ctx.token('|')
            ctx.cut()
        with ctx.nameadd('@'):
            self.option(ctx)
        with ctx.loopplus() as cl:
            cl.expecting('|')

            @cl.exp
            def 〇(ctx: Ctx) -> Any:
                ctx.token('|')
                ctx.cut()
                with ctx.nameadd('@'):
                    self.option(ctx)

    @tatsu.rule('Option')
    def option(self, ctx: Ctx) -> Any:
        self.sequence(ctx)

    @tatsu.rule('Sequence')
    def sequence(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                with ctx.if_():
                    with ctx.group():
                        self.element(ctx)
                        ctx.token(',')
                with ctx.gatherplus() as g:
                    g.expecting('<element>')

                    @g.sep
                    def 〇(ctx: Ctx) -> Any:
                        ctx.token(',')

                    @g.exp
                    def 〇(ctx: Ctx) -> Any:
                        self.element(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                with ctx.loopplus() as cl:
                    cl.expecting(
                      '(?:\\s*(?:\\r?\\n|\\r)){2,}',
                      '(?=\\s*(?:\\r?\\n|\\r)[^\\s])',
                      ';',
                      '<EMPTYLINE>',
                      '<ENDRULE>',
                      '<UNINDENTED>'
                    )

                    @cl.exp
                    def 〇(ctx: Ctx) -> Any:
                        with ctx.ifnot_():
                            self.ENDRULE(ctx)
                        self.element(ctx)

    @tatsu.rule
    def element(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.rule_include(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.named(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.override(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.term(ctx)

    @tatsu.rule('RuleInclude')
    def rule_include(self, ctx: Ctx) -> Any:
        ctx.token('>')
        ctx.cut()
        with ctx.nameset('@'):
            self.known_name(ctx)

    @tatsu.rule
    def named(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.named_list(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.named_single(ctx)

    @tatsu.rule('NamedList')
    def named_list(self, ctx: Ctx) -> Any:
        ctx.define(['exp', 'name'], [])
        with ctx.nameset('name'):
            self.name(ctx)
        ctx.pattern(r'\+[:=]')
        ctx.cut()
        with ctx.nameset('exp'):
            self.term(ctx)

    @tatsu.rule('Named')
    def named_single(self, ctx: Ctx) -> Any:
        ctx.define(['exp', 'name'], [])
        with ctx.nameset('name'):
            self.name(ctx)
        ctx.pattern(r'[:=]')
        ctx.cut()
        with ctx.nameset('exp'):
            self.term(ctx)

    @tatsu.rule
    def override(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.override_list(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.override_single(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.override_single_deprecated(ctx)

    @tatsu.rule('OverrideList')
    def override_list(self, ctx: Ctx) -> Any:
        ctx.pattern(r'\+=|@\+:')
        ctx.cut()
        with ctx.nameset('@'):
            self.term(ctx)

    @tatsu.rule('Override')
    def override_single(self, ctx: Ctx) -> Any:
        ctx.pattern(r'=|@:')
        ctx.cut()
        with ctx.nameset('@'):
            self.term(ctx)

    @tatsu.rule('Override')
    def override_single_deprecated(self, ctx: Ctx) -> Any:
        ctx.token('@')
        ctx.cut()
        with ctx.nameset('@'):
            self.term(ctx)

    @tatsu.rule
    def term(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.void(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.gather(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.join(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.left_join(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.right_join(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.empty_closure(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.positive_closure(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.closure(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.optional(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.skip_to(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.lookahead(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.negative_lookahead(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.cut(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.cut_deprecated(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.atom(ctx)

    @tatsu.rule('Group')
    def group(self, ctx: Ctx) -> Any:
        with ctx.ifnot_():
            ctx.token('(?:')
        ctx.token('(')
        ctx.cut()
        with ctx.nameset('@'):
            self.expre(ctx)
        ctx.token(')')
        ctx.cut()

    @tatsu.rule('Skip')
    def skip(self, ctx: Ctx) -> Any:
        ctx.token('(?:')
        ctx.cut()
        with ctx.nameset('@'):
            self.expre(ctx)
        ctx.token(')')
        ctx.cut()

    @tatsu.rule
    def gather(self, ctx: Ctx) -> Any:
        with ctx.if_():
            with ctx.group():
                self.atom(ctx)
                ctx.token('.{')
        ctx.cut()
        with ctx.group():
            with ctx.choice() as α:
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    self.positive_gather(ctx)
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    self.normal_gather(ctx)

    @tatsu.rule('PositiveGather')
    def positive_gather(self, ctx: Ctx) -> Any:
        ctx.define(['exp', 'sep'], [])
        with ctx.nameset('sep'):
            self.atom(ctx)
        ctx.token('.{')
        with ctx.nameset('exp'):
            self.expre(ctx)
        ctx.token('}')
        ctx.pattern(r'(?!\+=)[+-]')
        ctx.cut()

    @tatsu.rule('Gather')
    def normal_gather(self, ctx: Ctx) -> Any:
        ctx.define(['exp', 'sep'], [])
        with ctx.nameset('sep'):
            self.atom(ctx)
        ctx.token('.{')
        ctx.cut()
        with ctx.nameset('exp'):
            self.expre(ctx)
        ctx.token('}')
        with ctx.optional():
            ctx.token('*')
            ctx.cut()
        ctx.cut()

    @tatsu.rule
    def join(self, ctx: Ctx) -> Any:
        with ctx.if_():
            with ctx.group():
                self.atom(ctx)
                ctx.token('%{')
        ctx.cut()
        with ctx.group():
            with ctx.choice() as α:
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    self.positive_join(ctx)
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    self.normal_join(ctx)

    @tatsu.rule('PositiveJoin')
    def positive_join(self, ctx: Ctx) -> Any:
        ctx.define(['exp', 'sep'], [])
        with ctx.nameset('sep'):
            self.atom(ctx)
        ctx.token('%{')
        with ctx.nameset('exp'):
            self.expre(ctx)
        ctx.token('}')
        ctx.pattern(r'(?!\+=)[+-]')
        ctx.cut()

    @tatsu.rule('Join')
    def normal_join(self, ctx: Ctx) -> Any:
        ctx.define(['exp', 'sep'], [])
        with ctx.nameset('sep'):
            self.atom(ctx)
        ctx.token('%{')
        ctx.cut()
        with ctx.nameset('exp'):
            self.expre(ctx)
        ctx.token('}')
        with ctx.optional():
            ctx.token('*')
            ctx.cut()
        ctx.cut()

    @tatsu.rule('LeftJoin')
    def left_join(self, ctx: Ctx) -> Any:
        ctx.define(['exp', 'sep'], [])
        with ctx.nameset('sep'):
            self.atom(ctx)
        ctx.token('<{')
        ctx.cut()
        with ctx.nameset('exp'):
            self.expre(ctx)
        ctx.token('}')
        ctx.pattern(r'(?!\+=)[+-]')
        ctx.cut()

    @tatsu.rule('RightJoin')
    def right_join(self, ctx: Ctx) -> Any:
        ctx.define(['exp', 'sep'], [])
        with ctx.nameset('sep'):
            self.atom(ctx)
        ctx.token('>{')
        ctx.cut()
        with ctx.nameset('exp'):
            self.expre(ctx)
        ctx.token('}')
        ctx.pattern(r'(?!\+=)[+-]')
        ctx.cut()

    @tatsu.rule('PositiveClosure')
    def positive_closure(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.token('{')
                with ctx.nameset('@'):
                    self.expre(ctx)
                ctx.token('}')
                ctx.pattern(r'(?!\+=)[+-]')
                ctx.cut()
            @α.option
            def 〇(ctx: Ctx) -> Any:
                with ctx.nameset('@'):
                    self.atom(ctx)
                ctx.pattern(r'(?!\+=)[+]')
                ctx.cut()

    @tatsu.rule('Closure')
    def closure(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.token('{')
                with ctx.nameset('@'):
                    self.expre(ctx)
                ctx.token('}')
                with ctx.optional():
                    ctx.token('*')
                ctx.cut()
            @α.option
            def 〇(ctx: Ctx) -> Any:
                with ctx.nameset('@'):
                    self.atom(ctx)
                ctx.token('*')
                ctx.cut()

    @tatsu.rule('EmptyClosure')
    def empty_closure(self, ctx: Ctx) -> Any:
        ctx.token('{}')
        ctx.cut()
        with ctx.nameset('@'):
            ctx.void()

    @tatsu.rule('Optional')
    def optional(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.token('[')
                ctx.cut()
                with ctx.nameset('@'):
                    self.expre(ctx)
                ctx.token(']')
                ctx.cut()
            @α.option
            def 〇(ctx: Ctx) -> Any:
                with ctx.nameset('@'):
                    self.atom(ctx)
                with ctx.ifnot_():
                    with ctx.group():
                        with ctx.choice() as β:
                            @β.option
                            def 〇(ctx: Ctx) -> Any:
                                ctx.token('?"')
                            @β.option
                            def 〇(ctx: Ctx) -> Any:
                                ctx.token("?'")
                            @β.option
                            def 〇(ctx: Ctx) -> Any:
                                ctx.token('?/')
                ctx.token('?')
                ctx.cut()

    @tatsu.rule('Lookahead')
    def lookahead(self, ctx: Ctx) -> Any:
        ctx.token('&')
        ctx.cut()
        with ctx.nameset('@'):
            self.term(ctx)

    @tatsu.rule('NegativeLookahead')
    def negative_lookahead(self, ctx: Ctx) -> Any:
        ctx.token('!')
        ctx.cut()
        with ctx.nameset('@'):
            self.term(ctx)

    @tatsu.rule('SkipTo')
    def skip_to(self, ctx: Ctx) -> Any:
        ctx.token('->')
        ctx.cut()
        with ctx.nameset('@'):
            self.term(ctx)

    @tatsu.rule
    def atom(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.skip(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.group(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.token(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.alert(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.constant(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.call(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.pattern(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.dot(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.eof(ctx)

    @tatsu.rule('Call')
    def call(self, ctx: Ctx) -> Any:
        self.word(ctx)

    @tatsu.rule('Void')
    def void(self, ctx: Ctx) -> Any:
        ctx.token('()')
        ctx.cut()

    @tatsu.rule('Fail')
    def fail(self, ctx: Ctx) -> Any:
        ctx.token('!()')
        ctx.cut()

    @tatsu.rule('Cut')
    def cut(self, ctx: Ctx) -> Any:
        ctx.token('~')
        ctx.cut()

    @tatsu.rule('Cut')
    def cut_deprecated(self, ctx: Ctx) -> Any:
        ctx.token('>>')
        ctx.cut()

    @tatsu.rule
    def known_name(self, ctx: Ctx) -> Any:
        self.name(ctx)
        ctx.cut()

    @tatsu.rule
    def name(self, ctx: Ctx) -> Any:
        self.word(ctx)

    @tatsu.rule('Constant')
    def constant(self, ctx: Ctx) -> Any:
        with ctx.if_():
            ctx.token('`')
        with ctx.group():
            with ctx.choice() as α:
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    ctx.pattern(r'(?ms)```((?:.|\n)*?)```')
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    ctx.token('`')
                    with ctx.nameset('@'):
                        self.literal(ctx)
                    ctx.token('`')
                @α.option
                def 〇(ctx: Ctx) -> Any:
                    ctx.pattern(r'`(.*?)`')

    @tatsu.rule('Alert')
    def alert(self, ctx: Ctx) -> Any:
        ctx.define(['level', 'message'], [])
        with ctx.nameset('level'):
            ctx.pattern(r'\^+')
        with ctx.nameset('message'):
            self.constant(ctx)

    @tatsu.rule('Token')
    def token(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.string(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.raw_string(ctx)

    @tatsu.rule
    def literal(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.string(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.raw_string(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.boolean(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.word(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.hex(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.float(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.int(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.null(ctx)

    @tatsu.rule
    def string(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.multiline_string(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.singlequoted(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.doublequoted(ctx)

    @tatsu.rule
    def singlequoted(self, ctx: Ctx) -> Any:
        self.SINGLEQUOTED(ctx)

    @tatsu.rule
    def doublequoted(self, ctx: Ctx) -> Any:
        self.DOUBLEQUOTED(ctx)

    @tatsu.rule
    def raw_string(self, ctx: Ctx) -> Any:
        ctx.pattern(r'r')
        with ctx.nameset('@'):
            self.STRING(ctx)

    @tatsu.rule
    def STRING(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.SINGLEQUOTED(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.DOUBLEQUOTED(ctx)

    @tatsu.rule
    def SINGLEQUOTED(self, ctx: Ctx) -> Any:
        ctx.pattern(r"'((?:[^'\n]|\\'|\\\\)*?)'")
        ctx.cut()

    @tatsu.rule
    def DOUBLEQUOTED(self, ctx: Ctx) -> Any:
        ctx.pattern(r'"((?:[^"\n]|\\"|\\\\)*?)"')
        ctx.cut()

    @tatsu.rule
    def multiline_string(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.pattern(r"(?ms)'''((?:\\\\|\\.|(?!''').)*?)'''")
                ctx.cut()
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.pattern(r'(?ms)"""((?:\\\\|\\.|(?!""").)*?)"""')
                ctx.cut()

    @tatsu.rule
    def hex(self, ctx: Ctx) -> Any:
        ctx.pattern(r'0[xX](?:\d|[a-fA-F])+')

    @tatsu.rule
    def float(self, ctx: Ctx) -> Any:
        ctx.pattern(r'[-+]?(?:\d+\.\d*|\d*\.\d+)(?:[Ee][-+]?\d+)?')

    @tatsu.rule
    def int(self, ctx: Ctx) -> Any:
        ctx.pattern(r'[-+]?\d+')

    @tatsu.rule
    def path(self, ctx: Ctx) -> Any:
        ctx.pattern(r'(?!\d)\w+(?:::(?!\d)\w+)+')

    @tatsu.rule
    def word(self, ctx: Ctx) -> Any:
        ctx.pattern(r'(?!\d)\w+')

    @tatsu.rule('Dot')
    def dot(self, ctx: Ctx) -> Any:
        ctx.token('/./')

    @tatsu.rule('Pattern')
    def pattern(self, ctx: Ctx) -> Any:
        self.regex(ctx)

    @tatsu.rule
    def regex(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.REGEX(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.token('?')
                with ctx.nameset('@'):
                    self.STRING(ctx)
            @α.option
            def 〇(ctx: Ctx) -> Any:
                self.deprecated_regex(ctx)

    @tatsu.rule
    def REGEX(self, ctx: Ctx) -> Any:
        ctx.pattern(r'(?ms)/((?:[^/\\]|\\/|\\.)*)/')
        ctx.cut()

    @tatsu.rule
    def deprecated_regex(self, ctx: Ctx) -> Any:
        ctx.pattern(r'(?ms)\?/((?:[^/\\]|\\/|\\.)*)/\?')
        ctx.cut()
        ctx.alert('deprecated regex syntax', 2)

    @tatsu.rule('bool')
    def boolean(self, ctx: Ctx) -> Any:
        with ctx.choice() as α:
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.token('True')
            @α.option
            def 〇(ctx: Ctx) -> Any:
                ctx.token('False')

    @tatsu.rule
    def null(self, ctx: Ctx) -> Any:
        ctx.token('None')

    @tatsu.rule('EOF')
    def eof(self, ctx: Ctx) -> Any:
        ctx.token('$')
        ctx.cut()


def main(filename, **kwargs):
    if not filename or filename == '-':
        import sys

        text = sys.stdin.read()
    else:
        import pathlib

        text = pathlib.Path(filename).read_text()

    parser = TatSuBootstrapParser()
    return parser.parse(text, filename=filename, **kwargs)


if __name__ == '__main__':
    import json
    from tatsu.util import asjson

    ast = generic_main(main, TatSuBootstrapParser, name='TatSuBootstrap')
    data = asjson(ast)
    print(json.dumps(data, indent=2))
