#!/usr/bin/env python3

# CAVEAT UTILITOR
#
#  This file was automatically generated by 竜TatSu.
#
#     https://pypi.python.org/pypi/tatsu/
#
#  Any changes you make to it will be overwritten the next time
#  the file is generated.

# ruff: noqa: RUF100, C405, COM812, I001, F401, PLR1702, PLC2801, SIM117
# ruff: noqa: PL2401, PLC2402, PLC2403

from __future__ import annotations

from tatsu.buffering import Buffer
from tatsu.infos import ParserConfig
from tatsu.parsing import Parser, leftrec, nomemo, isname, generic_main, rule

__all__ = ['TatSuBootstrapBuffer', 'TatSuBootstrapParser', 'main']


KEYWORDS: set[str] = set()


class TatSuBootstrapBuffer(Buffer):
    def __init__(self, text, /, config: ParserConfig | None = None, **settings):
        config = ParserConfig.new(
            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',
        )
        config = config.override(**settings)

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


class TatSuBootstrapParser(Parser):
    def __init__(self, /, config: ParserConfig | None = None, **settings):
        config = ParserConfig.new(
            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',
        )
        config = config.override(**settings)

        super().__init__(config=config)

    @rule()
    def _start_(self):
        self._grammar_()

    @rule('Grammar')
    def _grammar_(self):
        with self._setname('title'):
            self._constant('TATSU')

        def block0():
            with self._choice():
                with self._option():
                    with self._addname('directives'):
                        self._directive_()
                with self._option():
                    with self._addname('keywords'):
                        self._keyword_()
                if self._no_more_options:
                    raise self.newexcept(
                        'expecting one of:  <directive> <keyword>'
                    ) from None

        self._closure(block0)
        with self._addname('rules'):
            self._rule_()

        def block1():
            with self._choice():
                with self._option():
                    with self._addname('rules'):
                        self._rule_()
                with self._option():
                    with self._addname('keywords'):
                        self._keyword_()
                if self._no_more_options:
                    raise self.newexcept(
                        'expecting one of:  <keyword> <rule>'
                    ) from None

        self._closure(block1)
        self._check_eof()
        self._define(['title'], ['directives', 'keywords', 'rules'])

    @rule()
    def _directive_(self):
        self._token('@@')
        with self._ifnot():
            self._token('keyword')
        self._cut()
        with self._group():
            with self._choice():
                with self._option():
                    with self._setname('name'):
                        with self._group():
                            with self._choice():
                                with self._option():
                                    self._token('comments')
                                with self._option():
                                    self._token('eol_comments')
                                if self._no_more_options:
                                    raise self.newexcept(
                                        "expecting one of:  'comments' 'eol_comments'"
                                    ) from None
                    self._cut()
                    self._cut()
                    self._token('::')
                    self._cut()
                    with self._setname('value'):
                        self._regex_()
                    self._define(['name', 'value'], [])
                with self._option():
                    with self._setname('name'):
                        with self._group():
                            self._token('whitespace')
                    self._cut()
                    self._token('::')
                    self._cut()
                    with self._setname('value'):
                        with self._group():
                            with self._choice():
                                with self._option():
                                    self._regex_()
                                with self._option():
                                    self._string_()
                                with self._option():
                                    self._token('None')
                                with self._option():
                                    self._token('False')
                                with self._option():
                                    self._constant('None')
                                if self._no_more_options:
                                    raise self.newexcept(
                                        'expecting one of: '
                                        "'False' 'None' <regex> <string>"
                                    ) from None
                    self._define(['name', 'value'], [])
                with self._option():
                    with self._setname('name'):
                        with self._group():
                            with self._choice():
                                with self._option():
                                    self._token('nameguard')
                                with self._option():
                                    self._token('ignorecase')
                                with self._option():
                                    self._token('left_recursion')
                                with self._option():
                                    self._token('parseinfo')
                                with self._option():
                                    self._token('memoization')
                                if self._no_more_options:
                                    raise self.newexcept(
                                        'expecting one of: '
                                        "'ignorecase' 'left_recursion'"
                                        "'memoization' 'nameguard' 'parseinfo'"
                                    ) from None
                    self._cut()
                    with self._group():
                        with self._choice():
                            with self._option():
                                self._token('::')
                                self._cut()
                                with self._setname('value'):
                                    self._boolean_()
                                self._define(['value'], [])
                            with self._option():
                                with self._setname('value'):
                                    self._constant(True)
                            if self._no_more_options:
                                raise self.newexcept(
                                    "expecting one of:  '::'"
                                ) from None
                    self._define(['name', 'value'], [])
                with self._option():
                    with self._setname('name'):
                        with self._group():
                            self._token('grammar')
                    self._cut()
                    self._token('::')
                    self._cut()
                    with self._setname('value'):
                        self._word_()
                    self._define(['name', 'value'], [])
                with self._option():
                    with self._setname('name'):
                        with self._group():
                            self._token('namechars')
                    self._cut()
                    self._token('::')
                    self._cut()
                    with self._setname('value'):
                        self._string_()
                    self._define(['name', 'value'], [])
                if self._no_more_options:
                    raise self.newexcept(
                        'expecting one of: '
                        "'comments' 'eol_comments' 'grammar'"
                        "'ignorecase' 'left_recursion'"
                        "'memoization' 'namechars' 'nameguard'"
                        "'parseinfo' 'whitespace'"
                    ) from None
        self._cut()
        self._define(['name', 'value'], [])

    @rule()
    def _keywords_(self):

        def block0():
            self._keywords_()

        self._positive_closure(block0)

    @rule()
    def _keyword_(self):
        self._token('@@keyword')
        self._cut()
        self._token('::')
        self._cut()

        def block0():
            with self._addname('@'):
                with self._group():
                    with self._choice():
                        with self._option():
                            self._word_()
                        with self._option():
                            self._string_()
                        if self._no_more_options:
                            raise self.newexcept(
                                'expecting one of:  <string> <word>'
                            ) from None
            with self._ifnot():
                with self._group():
                    with self._choice():
                        with self._option():
                            self._token(':')
                        with self._option():
                            self._token('=')
                        if self._no_more_options:
                            raise self.newexcept("expecting one of:  ':' '='") from None

        self._closure(block0)

    @rule()
    def _paramdef_(self):
        with self._choice():
            with self._option():
                self._token('::')
                self._cut()
                with self._setname('params'):
                    self._params_()
                self._define(['params'], [])
            with self._option():
                self._token('(')
                self._cut()
                with self._group():
                    with self._choice():
                        with self._option():
                            with self._setname('kwparams'):
                                self._kwparams_()
                        with self._option():
                            with self._setname('params'):
                                self._params_()
                            self._token(',')
                            self._cut()
                            with self._setname('kwparams'):
                                self._kwparams_()
                            self._define(['kwparams', 'params'], [])
                        with self._option():
                            with self._setname('params'):
                                self._params_()
                        if self._no_more_options:
                            raise self.newexcept(
                                'expecting one of:  <kwparams> <params>'
                            ) from None
                self._token(')')
                self._define(['kwparams', 'params'], [])
            if self._no_more_options:
                raise self.newexcept("expecting one of:  '(' '::'") from None

    @rule('Rule')
    def _rule_(self):
        with self._setname('decorators'):

            def block0():
                self._decorator_()

            self._closure(block0)
        with self._setname('name'):
            self._name_()
        self._cut()
        with self._optional():
            with self._choice():
                with self._option():
                    self._token('::')
                    self._cut()
                    with self._setname('params'):
                        self._params_()
                    self._define(['params'], [])
                with self._option():
                    self._token('(')
                    self._cut()
                    with self._group():
                        with self._choice():
                            with self._option():
                                with self._setname('kwparams'):
                                    self._kwparams_()
                            with self._option():
                                with self._setname('params'):
                                    self._params_()
                                self._token(',')
                                self._cut()
                                with self._setname('kwparams'):
                                    self._kwparams_()
                                self._define(['kwparams', 'params'], [])
                            with self._option():
                                with self._setname('params'):
                                    self._params_()
                            if self._no_more_options:
                                raise self.newexcept(
                                    'expecting one of:  <kwparams> <params>'
                                ) from None
                    self._token(')')
                    self._define(['kwparams', 'params'], [])
                if self._no_more_options:
                    raise self.newexcept("expecting one of:  '(' '::'") from None
        with self._optional():
            self._token('<')
            self._cut()
            with self._setname('base'):
                self._known_name_()
            self._define(['base'], [])
        with self._group():
            with self._choice():
                with self._option():
                    self._token('=')
                with self._option():
                    self._token(':=')
                with self._option():
                    self._token(':')
                if self._no_more_options:
                    raise self.newexcept("expecting one of:  ':' ':=' '='") from None
        self._cut()
        with self._setname('exp'):
            self._expre_()
        self._RULE_END_()
        self._cut()
        self._define(['base', 'decorators', 'exp', 'kwparams', 'name', 'params'], [])

    @rule()
    def _RULE_END_(self):
        with self._group():
            with self._choice():
                with self._option():
                    self._EMPTYLINE_()
                    with self._optional():
                        self._token(';')
                with self._option():
                    self._check_eof()
                with self._option():
                    self._token(';')
                if self._no_more_options:
                    raise self.newexcept(
                        'expecting one of: '
                        "'(?:\\\\s*(?:\\\\r?\\\\n|\\\\r)){2,}' ';'"
                        '<EMPTYLINE>'
                    ) from None

    @rule()
    def _EMPTYLINE_(self):
        self._pattern(r'(?:\s*(?:\r?\n|\r)){2,}')

    @rule()
    def _decorator_(self):
        self._token('@')
        with self._ifnot():
            self._token('@')
        self._cut()
        with self._setname('@'):
            with self._group():
                with self._choice():
                    with self._option():
                        self._token('override')
                    with self._option():
                        self._token('name')
                    with self._option():
                        self._token('nomemo')
                    if self._no_more_options:
                        raise self.newexcept(
                            "expecting one of:  'name' 'nomemo' 'override'"
                        ) from None

    @rule()
    def _params_(self):
        with self._addname('@'):
            self._first_param_()

        def block0():
            self._token(',')
            with self._addname('@'):
                self._literal_()
            with self._ifnot():
                self._token('=')
            self._cut()

        self._closure(block0)

    @rule()
    def _first_param_(self):
        with self._choice():
            with self._option():
                self._path_()
            with self._option():
                self._literal_()
            if self._no_more_options:
                raise self.newexcept(
                    'expecting one of: '
                    "'(?!\\\\d)\\\\w+(?:::(?!\\\\d)\\\\w+)+'"
                    '<boolean> <float> <hex> <int> <literal>'
                    '<null> <path> <raw_string> <string>'
                    '<word>'
                ) from None

    @rule()
    def _kwparams_(self):

        def sep0():
            self._token(',')

        def block1():
            self._pair_()

        self._positive_gather(block1, sep0)

    @rule()
    def _pair_(self):
        with self._addname('@'):
            self._word_()
        self._token('=')
        self._cut()
        with self._addname('@'):
            self._literal_()

    @rule()
    def _expre_(self):
        with self._choice():
            with self._option():
                self._choice_()
            with self._option():
                self._sequence_()
            if self._no_more_options:
                raise self.newexcept(
                    'expecting one of: '
                    "'(?:\\\\s*(?:\\\\r?\\\\n|\\\\r)){2,}' '|'"
                    '<EMPTYLINE> <choice> <element> <option>'
                    '<sequence>'
                ) from None

    @rule('Choice')
    def _choice_(self):
        with self._optional():
            self._token('|')
            self._cut()
        with self._addname('@'):
            self._option_()

        def block0():
            self._token('|')
            self._cut()
            with self._addname('@'):
                self._option_()

        self._positive_closure(block0)

    @rule('Option')
    def _option_(self):
        with self._setname('@'):
            self._sequence_()

    @rule('Sequence')
    def _sequence_(self):
        with self._group():
            with self._choice():
                with self._option():
                    with self._if():
                        with self._group():
                            self._element_()
                            self._token(',')

                    def sep0():
                        self._token(',')

                    def block1():
                        self._element_()

                    self._positive_gather(block1, sep0)
                with self._option():

                    def block2():
                        with self._ifnot():
                            self._EMPTYLINE_()
                        self._element_()

                    self._positive_closure(block2)
                if self._no_more_options:
                    raise self.newexcept(
                        'expecting one of: '
                        "'(?:\\\\s*(?:\\\\r?\\\\n|\\\\r)){2,}'"
                        '<EMPTYLINE> <element> <named> <override>'
                        '<rule_include> <term>'
                    ) from None

    @rule()
    def _element_(self):
        with self._group():
            with self._choice():
                with self._option():
                    self._rule_include_()
                with self._option():
                    self._named_()
                with self._option():
                    self._override_()
                with self._option():
                    self._term_()
                if self._no_more_options:
                    raise self.newexcept(
                        'expecting one of: '
                        "'>' <atom> <closure> <cut>"
                        '<cut_deprecated> <empty_closure>'
                        '<gather> <join> <left_join> <lookahead>'
                        '<named> <named_list> <named_single>'
                        '<negative_lookahead> <optional>'
                        '<override> <override_list>'
                        '<override_single>'
                        '<override_single_deprecated>'
                        '<positive_closure> <right_join>'
                        '<rule_include> <skip_to> <term> <void>'
                    ) from None

    @rule('RuleInclude')
    def _rule_include_(self):
        self._token('>')
        self._cut()
        with self._setname('@'):
            self._known_name_()

    @rule()
    def _named_(self):
        with self._choice():
            with self._option():
                self._named_list_()
            with self._option():
                self._named_single_()
            if self._no_more_options:
                raise self.newexcept(
                    'expecting one of:  <name> <named_list> <named_single>'
                ) from None

    @rule('NamedList')
    def _named_list_(self):
        with self._setname('name'):
            self._name_()
        self._token('+:')
        self._cut()
        with self._setname('exp'):
            self._term_()
        self._define(['exp', 'name'], [])

    @rule('Named')
    def _named_single_(self):
        with self._setname('name'):
            self._name_()
        self._token(':')
        self._cut()
        with self._setname('exp'):
            self._term_()
        self._define(['exp', 'name'], [])

    @rule()
    def _override_(self):
        with self._choice():
            with self._option():
                self._override_list_()
            with self._option():
                self._override_single_()
            with self._option():
                self._override_single_deprecated_()
            if self._no_more_options:
                raise self.newexcept(
                    'expecting one of: '
                    "'@' '@+:' '@:' <override_list>"
                    '<override_single>'
                    '<override_single_deprecated>'
                ) from None

    @rule('OverrideList')
    def _override_list_(self):
        self._token('@+:')
        self._cut()
        with self._setname('@'):
            self._term_()

    @rule('Override')
    def _override_single_(self):
        self._token('@:')
        self._cut()
        with self._setname('@'):
            self._term_()

    @rule('Override')
    def _override_single_deprecated_(self):
        self._token('@')
        self._cut()
        with self._setname('@'):
            self._term_()

    @rule()
    def _term_(self):
        with self._choice():
            with self._option():
                self._void_()
            with self._option():
                self._gather_()
            with self._option():
                self._join_()
            with self._option():
                self._left_join_()
            with self._option():
                self._right_join_()
            with self._option():
                self._empty_closure_()
            with self._option():
                self._positive_closure_()
            with self._option():
                self._closure_()
            with self._option():
                self._optional_()
            with self._option():
                self._skip_to_()
            with self._option():
                self._lookahead_()
            with self._option():
                self._negative_lookahead_()
            with self._option():
                self._cut_()
            with self._option():
                self._cut_deprecated_()
            with self._option():
                self._atom_()
            if self._no_more_options:
                raise self.newexcept(
                    'expecting one of: '
                    "'!' '&' '(' '()' '->' '>>' '[' '{' '{}'"
                    "'~' <alert> <atom> <call> <closure>"
                    '<constant> <cut> <cut_deprecated> <dot>'
                    '<empty_closure> <eof> <gather> <group>'
                    '<join> <left_join> <lookahead>'
                    '<negative_lookahead> <optional>'
                    '<pattern> <positive_closure>'
                    '<right_join> <skip_to> <token> <void>'
                ) from None

    @rule('Group')
    def _group_(self):
        self._token('(')
        self._cut()
        with self._setname('@'):
            self._expre_()
        self._token(')')
        self._cut()

    @rule()
    def _gather_(self):
        with self._if():
            with self._group():
                self._atom_()
                self._token('.{')
        self._cut()
        with self._group():
            with self._choice():
                with self._option():
                    self._positive_gather_()
                with self._option():
                    self._normal_gather_()
                if self._no_more_options:
                    raise self.newexcept(
                        'expecting one of:  <normal_gather> <positive_gather>'
                    ) from None

    @rule('PositiveGather')
    def _positive_gather_(self):
        with self._setname('sep'):
            self._atom_()
        self._token('.{')
        with self._setname('exp'):
            self._expre_()
        self._token('}')
        with self._group():
            with self._choice():
                with self._option():
                    self._token('+')
                with self._option():
                    self._token('-')
                if self._no_more_options:
                    raise self.newexcept("expecting one of:  '+' '-'") from None
        self._cut()
        self._define(['exp', 'sep'], [])

    @rule('Gather')
    def _normal_gather_(self):
        with self._setname('sep'):
            self._atom_()
        self._token('.{')
        self._cut()
        with self._setname('exp'):
            self._expre_()
        self._token('}')
        with self._optional():
            self._token('*')
            self._cut()
        self._cut()
        self._define(['exp', 'sep'], [])

    @rule()
    def _join_(self):
        with self._if():
            with self._group():
                self._atom_()
                self._token('%{')
        self._cut()
        with self._group():
            with self._choice():
                with self._option():
                    self._positive_join_()
                with self._option():
                    self._normal_join_()
                if self._no_more_options:
                    raise self.newexcept(
                        'expecting one of:  <normal_join> <positive_join>'
                    ) from None

    @rule('PositiveJoin')
    def _positive_join_(self):
        with self._setname('sep'):
            self._atom_()
        self._token('%{')
        with self._setname('exp'):
            self._expre_()
        self._token('}')
        with self._group():
            with self._choice():
                with self._option():
                    self._token('+')
                with self._option():
                    self._token('-')
                if self._no_more_options:
                    raise self.newexcept("expecting one of:  '+' '-'") from None
        self._cut()
        self._define(['exp', 'sep'], [])

    @rule('Join')
    def _normal_join_(self):
        with self._setname('sep'):
            self._atom_()
        self._token('%{')
        self._cut()
        with self._setname('exp'):
            self._expre_()
        self._token('}')
        with self._optional():
            self._token('*')
            self._cut()
        self._cut()
        self._define(['exp', 'sep'], [])

    @rule('LeftJoin')
    def _left_join_(self):
        with self._setname('sep'):
            self._atom_()
        self._token('<{')
        self._cut()
        with self._setname('exp'):
            self._expre_()
        self._token('}')
        with self._group():
            with self._choice():
                with self._option():
                    self._token('+')
                with self._option():
                    self._token('-')
                if self._no_more_options:
                    raise self.newexcept("expecting one of:  '+' '-'") from None
        self._cut()
        self._define(['exp', 'sep'], [])

    @rule('RightJoin')
    def _right_join_(self):
        with self._setname('sep'):
            self._atom_()
        self._token('>{')
        self._cut()
        with self._setname('exp'):
            self._expre_()
        self._token('}')
        with self._group():
            with self._choice():
                with self._option():
                    self._token('+')
                with self._option():
                    self._token('-')
                if self._no_more_options:
                    raise self.newexcept("expecting one of:  '+' '-'") from None
        self._cut()
        self._define(['exp', 'sep'], [])

    @rule('PositiveClosure')
    def _positive_closure_(self):
        with self._choice():
            with self._option():
                self._token('{')
                with self._setname('@'):
                    self._expre_()
                self._token('}')
                with self._group():
                    with self._choice():
                        with self._option():
                            self._token('-')
                        with self._option():
                            self._token('+')
                        if self._no_more_options:
                            raise self.newexcept("expecting one of:  '+' '-'") from None
                self._cut()
            with self._option():
                with self._setname('@'):
                    self._atom_()
                self._token('+')
                self._cut()
            if self._no_more_options:
                raise self.newexcept(
                    'expecting one of: '
                    "'(' '{' <alert> <atom> <call> <constant>"
                    '<dot> <eof> <group> <pattern> <token>'
                ) from None

    @rule('Closure')
    def _closure_(self):
        with self._choice():
            with self._option():
                self._token('{')
                with self._setname('@'):
                    self._expre_()
                self._token('}')
                with self._optional():
                    self._token('*')
                self._cut()
            with self._option():
                with self._setname('@'):
                    self._atom_()
                self._token('*')
                self._cut()
            if self._no_more_options:
                raise self.newexcept(
                    'expecting one of: '
                    "'(' '{' <alert> <atom> <call> <constant>"
                    '<dot> <eof> <group> <pattern> <token>'
                ) from None

    @rule('EmptyClosure')
    def _empty_closure_(self):
        self._token('{}')
        self._cut()
        with self._setname('@'):
            self._void()

    @rule('Optional')
    def _optional_(self):
        with self._choice():
            with self._option():
                self._token('[')
                self._cut()
                with self._setname('@'):
                    self._expre_()
                self._token(']')
                self._cut()
            with self._option():
                with self._setname('@'):
                    self._atom_()
                with self._ifnot():
                    with self._group():
                        with self._choice():
                            with self._option():
                                self._token('?"')
                            with self._option():
                                self._token("?'")
                            with self._option():
                                self._token('?/')
                            if self._no_more_options:
                                raise self.newexcept(
                                    'expecting one of:  "?\'" \'?"\' \'?/\''
                                ) from None
                self._token('?')
                self._cut()
            if self._no_more_options:
                raise self.newexcept(
                    'expecting one of: '
                    "'(' '[' <alert> <atom> <call> <constant>"
                    '<dot> <eof> <group> <pattern> <token>'
                ) from None

    @rule('Lookahead')
    def _lookahead_(self):
        self._token('&')
        self._cut()
        with self._setname('@'):
            self._term_()

    @rule('NegativeLookahead')
    def _negative_lookahead_(self):
        self._token('!')
        self._cut()
        with self._setname('@'):
            self._term_()

    @rule('SkipTo')
    def _skip_to_(self):
        self._token('->')
        self._cut()
        with self._setname('@'):
            self._term_()

    @rule()
    def _atom_(self):
        with self._choice():
            with self._option():
                self._group_()
            with self._option():
                self._token_()
            with self._option():
                self._alert_()
            with self._option():
                self._constant_()
            with self._option():
                self._call_()
            with self._option():
                self._pattern_()
            with self._option():
                self._dot_()
            with self._option():
                self._eof_()
            if self._no_more_options:
                raise self.newexcept(
                    'expecting one of: '
                    "'$' '(' '/./' '\\\\^+' '`' <alert> <call>"
                    '<constant> <dot> <eof> <group> <pattern>'
                    '<raw_string> <regexes> <string> <token>'
                    '<word>'
                ) from None

    @rule('Call')
    def _call_(self):
        self._word_()

    @rule('Void')
    def _void_(self):
        self._token('()')
        self._cut()

    @rule('Fail')
    def _fail_(self):
        self._token('!()')
        self._cut()

    @rule('Cut')
    def _cut_(self):
        self._token('~')
        self._cut()

    @rule('Cut')
    def _cut_deprecated_(self):
        self._token('>>')
        self._cut()

    @rule()
    def _known_name_(self):
        self._name_()
        self._cut()

    @rule()
    def _name_(self):
        self._word_()

    @rule('Constant')
    def _constant_(self):
        with self._if():
            self._token('`')
        with self._group():
            with self._choice():
                with self._option():
                    self._pattern(r'(?ms)```((?:.|\n)*?)```')
                with self._option():
                    self._token('`')
                    with self._setname('@'):
                        self._literal_()
                    self._token('`')
                with self._option():
                    self._pattern(r'`(.*?)`')
                if self._no_more_options:
                    raise self.newexcept(
                        "expecting one of:  '(?ms)```((?:.|\\\\n)*?)```' '`' '`(.*?)`'"
                    ) from None

    @rule('Alert')
    def _alert_(self):
        with self._setname('level'):
            self._pattern(r'\^+')
        with self._setname('message'):
            self._constant_()
        self._define(['level', 'message'], [])

    @rule('Token')
    def _token_(self):
        with self._choice():
            with self._option():
                self._string_()
            with self._option():
                self._raw_string_()
            if self._no_more_options:
                raise self.newexcept(
                    "expecting one of:  'r' <STRING> <raw_string> <string>"
                ) from None

    @rule()
    def _literal_(self):
        with self._choice():
            with self._option():
                self._string_()
            with self._option():
                self._raw_string_()
            with self._option():
                self._boolean_()
            with self._option():
                self._word_()
            with self._option():
                self._hex_()
            with self._option():
                self._float_()
            with self._option():
                self._int_()
            with self._option():
                self._null_()
            if self._no_more_options:
                raise self.newexcept(
                    'expecting one of: '
                    "'(?!\\\\d)\\\\w+' '0[xX](?:\\\\d|[a-fA-F])+'"
                    "'False' 'None' 'True' '[-"
                    '+]?(?:\\\\d+\\\\.\\\\d*|\\\\d*\\\\.\\\\d+)(?:[Ee][-'
                    "+]?\\\\d+)?' '[-+]?\\\\d+' 'r' <STRING>"
                    '<boolean> <float> <hex> <int> <null>'
                    '<raw_string> <string> <word>'
                ) from None

    @rule()
    def _string_(self):
        self._STRING_()

    @rule()
    def _raw_string_(self):
        self._pattern(r'r')
        with self._setname('@'):
            self._STRING_()

    @rule()
    def _STRING_(self):
        with self._choice():
            with self._option():
                with self._setname('@'):
                    self._pattern(r'"((?:[^"\n]|\\"|\\\\)*?)"')
                self._cut()
            with self._option():
                with self._setname('@'):
                    self._pattern(r"'((?:[^'\n]|\\'|\\\\)*?)'")
                self._cut()
            if self._no_more_options:
                raise self.newexcept(
                    'expecting one of: '
                    '"\'((?:[^\'\\\\n]|\\\\\\\\\'|\\\\\\\\\\\\\\\\)*?)\'"'
                    '\'"((?:[^"\\\\n]|\\\\\\\\"|\\\\\\\\\\\\\\\\)*?)"\''
                ) from None

    @rule()
    def _hex_(self):
        self._pattern(r'0[xX](?:\d|[a-fA-F])+')

    @rule()
    def _float_(self):
        self._pattern(r'[-+]?(?:\d+\.\d*|\d*\.\d+)(?:[Ee][-+]?\d+)?')

    @rule()
    def _int_(self):
        self._pattern(r'[-+]?\d+')

    @rule()
    def _path_(self):
        self._pattern(r'(?!\d)\w+(?:::(?!\d)\w+)+')

    @rule()
    def _word_(self):
        self._pattern(r'(?!\d)\w+')

    @rule('Dot')
    def _dot_(self):
        self._token('/./')

    @rule('Pattern')
    def _pattern_(self):
        self._regexes_()

    @rule()
    def _regexes_(self):

        def sep0():
            self._token('+')

        def block1():
            self._regex_()

        self._positive_gather(block1, sep0)

    @rule()
    def _regex_(self):
        with self._choice():
            with self._option():
                self._token('/')
                self._cut()
                with self._setname('@'):
                    self._pattern(r'(?:[^/\\]|\\/|\\.)*')
                self._token('/')
                self._cut()
            with self._option():
                self._token('?')
                with self._setname('@'):
                    self._STRING_()
            with self._option():
                self._deprecated_regex_()
            if self._no_more_options:
                raise self.newexcept(
                    "expecting one of:  '/' '?' '?/' <deprecated_regex>"
                ) from None

    @rule()
    def _deprecated_regex_(self):
        self._token('?/')
        self._cut()
        with self._setname('@'):
            self._pattern(r'(?:.|\n)*?(?=/\?)')
        self._pattern(r'/\?+')
        self._cut()

    @rule()
    def _boolean_(self):
        with self._choice():
            with self._option():
                self._token('True')
            with self._option():
                self._token('False')
            if self._no_more_options:
                raise self.newexcept("expecting one of:  'False' 'True'") from None

    @rule()
    def _null_(self):
        self._token('None')

    @rule('EOF')
    def _eof_(self):
        self._token('$')
        self._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))
