1135 lines
34 KiB
Python
1135 lines
34 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# WARNING: 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: C405, COM812, I001, F401, PLR1702, PLC2801, SIM117
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from tatsu.buffering import Buffer
|
|
from tatsu.parsing import Parser
|
|
from tatsu.parsing import tatsumasu
|
|
from tatsu.parsing import leftrec, nomemo, isname
|
|
from tatsu.infos import ParserConfig
|
|
from tatsu.util import re, generic_main
|
|
|
|
|
|
KEYWORDS: set[str] = set()
|
|
|
|
|
|
class EBNFBootstrapBuffer(Buffer):
|
|
def __init__(self, text, /, config: ParserConfig | None = None, **settings):
|
|
config = ParserConfig.new(
|
|
config,
|
|
owner=self,
|
|
whitespace='(?m)\\s+',
|
|
nameguard=None,
|
|
ignorecase=False,
|
|
namechars='',
|
|
parseinfo=True,
|
|
comments='(?sm)[(][*](?:.|\\n)*?[*][)]',
|
|
eol_comments='(?sm)*#[^\\n]*$',
|
|
keywords=KEYWORDS,
|
|
start='start',
|
|
)
|
|
config = config.replace(**settings)
|
|
|
|
super().__init__(text, config=config)
|
|
|
|
|
|
class EBNFBootstrapParser(Parser):
|
|
def __init__(self, /, config: ParserConfig | None = None, **settings):
|
|
config = ParserConfig.new(
|
|
config,
|
|
owner=self,
|
|
whitespace='\\s+',
|
|
nameguard=None,
|
|
ignorecase=False,
|
|
namechars='',
|
|
parseinfo=True,
|
|
comments='(?sm)[(][*](?:.|\\n)*?[*][)]',
|
|
eol_comments='(?m)#[^\\n]*$',
|
|
keywords=KEYWORDS,
|
|
start='start',
|
|
)
|
|
config = config.replace(**settings)
|
|
|
|
super().__init__(config=config)
|
|
|
|
@tatsumasu()
|
|
def _start_(self):
|
|
self._grammar_()
|
|
|
|
@tatsumasu('Grammar')
|
|
def _grammar_(self):
|
|
self._constant('TATSU')
|
|
self.name_last_node('title')
|
|
|
|
def block0():
|
|
with self._choice():
|
|
with self._option():
|
|
self._directive_()
|
|
self.add_last_node_to_name('directives')
|
|
with self._option():
|
|
self._keyword_()
|
|
self.add_last_node_to_name('keywords')
|
|
self._error(
|
|
'expecting one of: '
|
|
'<directive> <keyword>'
|
|
)
|
|
self._closure(block0)
|
|
self._rule_()
|
|
self.add_last_node_to_name('rules')
|
|
|
|
def block1():
|
|
with self._choice():
|
|
with self._option():
|
|
self._rule_()
|
|
self.add_last_node_to_name('rules')
|
|
with self._option():
|
|
self._keyword_()
|
|
self.add_last_node_to_name('keywords')
|
|
self._error(
|
|
'expecting one of: '
|
|
'<keyword> <rule>'
|
|
)
|
|
self._closure(block1)
|
|
self._check_eof()
|
|
self._define(
|
|
['title'],
|
|
['directives', 'keywords', 'rules'],
|
|
)
|
|
|
|
@tatsumasu()
|
|
def _directive_(self):
|
|
self._token('@@')
|
|
with self._ifnot():
|
|
self._token('keyword')
|
|
self._cut()
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._token('comments')
|
|
with self._option():
|
|
self._token('eol_comments')
|
|
self._error(
|
|
'expecting one of: '
|
|
"'comments' 'eol_comments'"
|
|
)
|
|
self.name_last_node('name')
|
|
self._cut()
|
|
self._cut()
|
|
self._token('::')
|
|
self._cut()
|
|
self._regex_()
|
|
self.name_last_node('value')
|
|
self._define(['name', 'value'], [])
|
|
with self._option():
|
|
with self._group():
|
|
self._token('whitespace')
|
|
self.name_last_node('name')
|
|
self._cut()
|
|
self._cut()
|
|
self._token('::')
|
|
self._cut()
|
|
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')
|
|
self._error(
|
|
'expecting one of: '
|
|
"'False' 'None' <regex> <string>"
|
|
)
|
|
self.name_last_node('value')
|
|
self._define(['name', 'value'], [])
|
|
with self._option():
|
|
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')
|
|
self._error(
|
|
'expecting one of: '
|
|
"'ignorecase' 'left_recursion'"
|
|
"'nameguard' 'parseinfo'"
|
|
)
|
|
self.name_last_node('name')
|
|
self._cut()
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._token('::')
|
|
self._cut()
|
|
self._boolean_()
|
|
self.name_last_node('value')
|
|
self._define(['value'], [])
|
|
with self._option():
|
|
self._constant(True)
|
|
self.name_last_node('value')
|
|
self._error(
|
|
'expecting one of: '
|
|
"'::'"
|
|
)
|
|
self._define(['name', 'value'], [])
|
|
with self._option():
|
|
with self._group():
|
|
self._token('grammar')
|
|
self.name_last_node('name')
|
|
self._cut()
|
|
self._token('::')
|
|
self._cut()
|
|
self._word_()
|
|
self.name_last_node('value')
|
|
self._define(['name', 'value'], [])
|
|
with self._option():
|
|
with self._group():
|
|
self._token('namechars')
|
|
self.name_last_node('name')
|
|
self._cut()
|
|
self._token('::')
|
|
self._cut()
|
|
self._string_()
|
|
self.name_last_node('value')
|
|
self._define(['name', 'value'], [])
|
|
self._error(
|
|
'expecting one of: '
|
|
"'comments' 'eol_comments' 'grammar'"
|
|
"'ignorecase' 'left_recursion'"
|
|
"'namechars' 'nameguard' 'parseinfo'"
|
|
"'whitespace'"
|
|
)
|
|
self._cut()
|
|
self._define(['name', 'value'], [])
|
|
|
|
@tatsumasu()
|
|
def _keywords_(self):
|
|
|
|
def block0():
|
|
self._keywords_()
|
|
self._positive_closure(block0)
|
|
|
|
@tatsumasu()
|
|
def _keyword_(self):
|
|
self._token('@@keyword')
|
|
self._cut()
|
|
self._token('::')
|
|
self._cut()
|
|
|
|
def block0():
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._word_()
|
|
with self._option():
|
|
self._string_()
|
|
self._error(
|
|
'expecting one of: '
|
|
'<string> <word>'
|
|
)
|
|
self.add_last_node_to_name('@')
|
|
with self._ifnot():
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._token(':')
|
|
with self._option():
|
|
self._token('=')
|
|
self._error(
|
|
'expecting one of: '
|
|
"':' '='"
|
|
)
|
|
self._closure(block0)
|
|
|
|
@tatsumasu()
|
|
def _paramdef_(self):
|
|
with self._choice():
|
|
with self._option():
|
|
self._token('::')
|
|
self._cut()
|
|
self._params_()
|
|
self.name_last_node('params')
|
|
self._define(['params'], [])
|
|
with self._option():
|
|
self._token('(')
|
|
self._cut()
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._kwparams_()
|
|
self.name_last_node('kwparams')
|
|
with self._option():
|
|
self._params_()
|
|
self.name_last_node('params')
|
|
self._token(',')
|
|
self._cut()
|
|
self._kwparams_()
|
|
self.name_last_node('kwparams')
|
|
self._define(['kwparams', 'params'], [])
|
|
with self._option():
|
|
self._params_()
|
|
self.name_last_node('params')
|
|
self._error(
|
|
'expecting one of: '
|
|
'<kwparams> <params>'
|
|
)
|
|
self._token(')')
|
|
self._define(['kwparams', 'params'], [])
|
|
self._error(
|
|
'expecting one of: '
|
|
"'(' '::'"
|
|
)
|
|
|
|
@tatsumasu('Rule')
|
|
def _rule_(self):
|
|
|
|
def block0():
|
|
self._decorator_()
|
|
self._closure(block0)
|
|
self.name_last_node('decorators')
|
|
self._name_()
|
|
self.name_last_node('name')
|
|
self._cut()
|
|
with self._optional():
|
|
with self._choice():
|
|
with self._option():
|
|
self._token('::')
|
|
self._cut()
|
|
self._params_()
|
|
self.name_last_node('params')
|
|
self._define(['params'], [])
|
|
with self._option():
|
|
self._token('(')
|
|
self._cut()
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._kwparams_()
|
|
self.name_last_node('kwparams')
|
|
with self._option():
|
|
self._params_()
|
|
self.name_last_node('params')
|
|
self._token(',')
|
|
self._cut()
|
|
self._kwparams_()
|
|
self.name_last_node('kwparams')
|
|
self._define(['kwparams', 'params'], [])
|
|
with self._option():
|
|
self._params_()
|
|
self.name_last_node('params')
|
|
self._error(
|
|
'expecting one of: '
|
|
'<kwparams> <params>'
|
|
)
|
|
self._token(')')
|
|
self._define(['kwparams', 'params'], [])
|
|
self._error(
|
|
'expecting one of: '
|
|
"'(' '::'"
|
|
)
|
|
with self._optional():
|
|
self._token('<')
|
|
self._cut()
|
|
self._known_name_()
|
|
self.name_last_node('base')
|
|
self._define(['base'], [])
|
|
self._token('=')
|
|
self._cut()
|
|
self._expre_()
|
|
self.name_last_node('exp')
|
|
self._token(';')
|
|
self._cut()
|
|
self._define(['base', 'decorators', 'exp', 'kwparams', 'name', 'params'], [])
|
|
|
|
@tatsumasu()
|
|
def _decorator_(self):
|
|
self._token('@')
|
|
with self._ifnot():
|
|
self._token('@')
|
|
self._cut()
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._token('override')
|
|
with self._option():
|
|
self._token('name')
|
|
with self._option():
|
|
self._token('nomemo')
|
|
self._error(
|
|
'expecting one of: '
|
|
"'name' 'nomemo' 'override'"
|
|
)
|
|
self.name_last_node('@')
|
|
|
|
@tatsumasu()
|
|
def _params_(self):
|
|
self._first_param_()
|
|
self.add_last_node_to_name('@')
|
|
|
|
def block0():
|
|
self._token(',')
|
|
self._literal_()
|
|
self.add_last_node_to_name('@')
|
|
with self._ifnot():
|
|
self._token('=')
|
|
self._cut()
|
|
self._closure(block0)
|
|
|
|
@tatsumasu()
|
|
def _first_param_(self):
|
|
with self._choice():
|
|
with self._option():
|
|
self._path_()
|
|
with self._option():
|
|
self._literal_()
|
|
self._error(
|
|
'expecting one of: '
|
|
'(?!\\d)\\w+(?:::(?!\\d)\\w+)+ <boolean>'
|
|
'<float> <hex> <int> <literal> <null>'
|
|
'<path> <raw_string> <string> <word>'
|
|
)
|
|
|
|
@tatsumasu()
|
|
def _kwparams_(self):
|
|
|
|
def sep0():
|
|
self._token(',')
|
|
|
|
def block1():
|
|
self._pair_()
|
|
self._positive_gather(block1, sep0)
|
|
|
|
@tatsumasu()
|
|
def _pair_(self):
|
|
self._word_()
|
|
self.add_last_node_to_name('@')
|
|
self._token('=')
|
|
self._cut()
|
|
self._literal_()
|
|
self.add_last_node_to_name('@')
|
|
|
|
@tatsumasu()
|
|
def _expre_(self):
|
|
with self._choice():
|
|
with self._option():
|
|
self._choice_()
|
|
with self._option():
|
|
self._sequence_()
|
|
self._error(
|
|
'expecting one of: '
|
|
"'|' <choice> <element> <option>"
|
|
'<sequence>'
|
|
)
|
|
|
|
@tatsumasu('Choice')
|
|
def _choice_(self):
|
|
with self._optional():
|
|
self._token('|')
|
|
self._cut()
|
|
self._option_()
|
|
self.add_last_node_to_name('@')
|
|
|
|
def block0():
|
|
self._token('|')
|
|
self._cut()
|
|
self._option_()
|
|
self.add_last_node_to_name('@')
|
|
self._positive_closure(block0)
|
|
|
|
@tatsumasu('Option')
|
|
def _option_(self):
|
|
self._sequence_()
|
|
self.name_last_node('@')
|
|
|
|
@tatsumasu('Sequence')
|
|
def _sequence_(self):
|
|
|
|
def block0():
|
|
self._element_()
|
|
self._positive_closure(block0)
|
|
self.name_last_node('sequence')
|
|
|
|
@tatsumasu()
|
|
def _element_(self):
|
|
with self._choice():
|
|
with self._option():
|
|
self._rule_include_()
|
|
with self._option():
|
|
self._named_()
|
|
with self._option():
|
|
self._override_()
|
|
with self._option():
|
|
self._term_()
|
|
self._error(
|
|
'expecting one of: '
|
|
"'>' <atom> <closure> <empty_closure>"
|
|
'<gather> <group> <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> <special>'
|
|
'<term> <void>'
|
|
)
|
|
|
|
@tatsumasu('RuleInclude')
|
|
def _rule_include_(self):
|
|
self._token('>')
|
|
self._cut()
|
|
self._known_name_()
|
|
self.name_last_node('@')
|
|
|
|
@tatsumasu()
|
|
def _named_(self):
|
|
with self._choice():
|
|
with self._option():
|
|
self._named_list_()
|
|
with self._option():
|
|
self._named_single_()
|
|
self._error(
|
|
'expecting one of: '
|
|
'<name> <named_list> <named_single>'
|
|
)
|
|
|
|
@tatsumasu('NamedList')
|
|
def _named_list_(self):
|
|
self._name_()
|
|
self.name_last_node('name')
|
|
self._token('+:')
|
|
self._cut()
|
|
self._term_()
|
|
self.name_last_node('exp')
|
|
self._define(['exp', 'name'], [])
|
|
|
|
@tatsumasu('Named')
|
|
def _named_single_(self):
|
|
self._name_()
|
|
self.name_last_node('name')
|
|
self._token(':')
|
|
self._cut()
|
|
self._term_()
|
|
self.name_last_node('exp')
|
|
self._define(['exp', 'name'], [])
|
|
|
|
@tatsumasu()
|
|
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_()
|
|
self._error(
|
|
'expecting one of: '
|
|
"'@' '@+:' '@:' <override_list>"
|
|
'<override_single>'
|
|
'<override_single_deprecated>'
|
|
)
|
|
|
|
@tatsumasu('OverrideList')
|
|
def _override_list_(self):
|
|
self._token('@+:')
|
|
self._cut()
|
|
self._term_()
|
|
self.name_last_node('@')
|
|
|
|
@tatsumasu('Override')
|
|
def _override_single_(self):
|
|
self._token('@:')
|
|
self._cut()
|
|
self._term_()
|
|
self.name_last_node('@')
|
|
|
|
@tatsumasu('Override')
|
|
def _override_single_deprecated_(self):
|
|
self._token('@')
|
|
self._cut()
|
|
self._term_()
|
|
self.name_last_node('@')
|
|
|
|
@tatsumasu()
|
|
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._group_()
|
|
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._special_()
|
|
with self._option():
|
|
self._skip_to_()
|
|
with self._option():
|
|
self._lookahead_()
|
|
with self._option():
|
|
self._negative_lookahead_()
|
|
with self._option():
|
|
self._atom_()
|
|
self._error(
|
|
'expecting one of: '
|
|
"'!' '&' '(' '()' '->' '?(' '[' '{'"
|
|
'<alert> <atom> <call> <closure>'
|
|
'<constant> <cut> <cut_deprecated>'
|
|
'<empty_closure> <eof> <gather> <group>'
|
|
'<join> <left_join> <lookahead>'
|
|
'<negative_lookahead> <optional>'
|
|
'<pattern> <positive_closure>'
|
|
'<right_join> <separator> <skip_to>'
|
|
'<special> <token> <void>'
|
|
)
|
|
|
|
@tatsumasu('Group')
|
|
def _group_(self):
|
|
self._token('(')
|
|
self._cut()
|
|
self._expre_()
|
|
self.name_last_node('exp')
|
|
self._token(')')
|
|
self._cut()
|
|
self._define(['exp'], [])
|
|
|
|
@tatsumasu()
|
|
def _gather_(self):
|
|
with self._if():
|
|
with self._group():
|
|
self._separator_()
|
|
self._token('.{')
|
|
self._cut()
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._positive_gather_()
|
|
with self._option():
|
|
self._normal_gather_()
|
|
self._error(
|
|
'expecting one of: '
|
|
'<normal_gather> <positive_gather>'
|
|
)
|
|
|
|
@tatsumasu('PositiveGather')
|
|
def _positive_gather_(self):
|
|
self._separator_()
|
|
self.name_last_node('sep')
|
|
self._token('.{')
|
|
self._expre_()
|
|
self.name_last_node('exp')
|
|
self._token('}')
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._token('+')
|
|
with self._option():
|
|
self._token('-')
|
|
self._error(
|
|
'expecting one of: '
|
|
"'+' '-'"
|
|
)
|
|
self._cut()
|
|
self._define(['exp', 'sep'], [])
|
|
|
|
@tatsumasu('Gather')
|
|
def _normal_gather_(self):
|
|
self._separator_()
|
|
self.name_last_node('sep')
|
|
self._token('.{')
|
|
self._cut()
|
|
self._expre_()
|
|
self.name_last_node('exp')
|
|
self._token('}')
|
|
with self._optional():
|
|
self._token('*')
|
|
self._cut()
|
|
self._cut()
|
|
self._define(['exp', 'sep'], [])
|
|
|
|
@tatsumasu()
|
|
def _join_(self):
|
|
with self._if():
|
|
with self._group():
|
|
self._separator_()
|
|
self._token('%{')
|
|
self._cut()
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._positive_join_()
|
|
with self._option():
|
|
self._normal_join_()
|
|
self._error(
|
|
'expecting one of: '
|
|
'<normal_join> <positive_join>'
|
|
)
|
|
|
|
@tatsumasu('PositiveJoin')
|
|
def _positive_join_(self):
|
|
self._separator_()
|
|
self.name_last_node('sep')
|
|
self._token('%{')
|
|
self._expre_()
|
|
self.name_last_node('exp')
|
|
self._token('}')
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._token('+')
|
|
with self._option():
|
|
self._token('-')
|
|
self._error(
|
|
'expecting one of: '
|
|
"'+' '-'"
|
|
)
|
|
self._cut()
|
|
self._define(['exp', 'sep'], [])
|
|
|
|
@tatsumasu('Join')
|
|
def _normal_join_(self):
|
|
self._separator_()
|
|
self.name_last_node('sep')
|
|
self._token('%{')
|
|
self._cut()
|
|
self._expre_()
|
|
self.name_last_node('exp')
|
|
self._token('}')
|
|
with self._optional():
|
|
self._token('*')
|
|
self._cut()
|
|
self._cut()
|
|
self._define(['exp', 'sep'], [])
|
|
|
|
@tatsumasu('LeftJoin')
|
|
def _left_join_(self):
|
|
self._separator_()
|
|
self.name_last_node('sep')
|
|
self._token('<{')
|
|
self._cut()
|
|
self._expre_()
|
|
self.name_last_node('exp')
|
|
self._token('}')
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._token('+')
|
|
with self._option():
|
|
self._token('-')
|
|
self._error(
|
|
'expecting one of: '
|
|
"'+' '-'"
|
|
)
|
|
self._cut()
|
|
self._define(['exp', 'sep'], [])
|
|
|
|
@tatsumasu('RightJoin')
|
|
def _right_join_(self):
|
|
self._separator_()
|
|
self.name_last_node('sep')
|
|
self._token('>{')
|
|
self._cut()
|
|
self._expre_()
|
|
self.name_last_node('exp')
|
|
self._token('}')
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._token('+')
|
|
with self._option():
|
|
self._token('-')
|
|
self._error(
|
|
'expecting one of: '
|
|
"'+' '-'"
|
|
)
|
|
self._cut()
|
|
self._define(['exp', 'sep'], [])
|
|
|
|
@tatsumasu()
|
|
def _separator_(self):
|
|
with self._choice():
|
|
with self._option():
|
|
self._group_()
|
|
with self._option():
|
|
self._token_()
|
|
with self._option():
|
|
self._constant_()
|
|
with self._option():
|
|
self._any_()
|
|
with self._option():
|
|
self._pattern_()
|
|
self._error(
|
|
'expecting one of: '
|
|
"'(' '/./' '`' <any> <constant> <group>"
|
|
'<pattern> <raw_string> <regexes>'
|
|
'<string> <token>'
|
|
)
|
|
|
|
@tatsumasu('PositiveClosure')
|
|
def _positive_closure_(self):
|
|
self._token('{')
|
|
self._expre_()
|
|
self.name_last_node('@')
|
|
self._token('}')
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._token('-')
|
|
with self._option():
|
|
self._token('+')
|
|
self._error(
|
|
'expecting one of: '
|
|
"'+' '-'"
|
|
)
|
|
self._cut()
|
|
|
|
@tatsumasu('Closure')
|
|
def _closure_(self):
|
|
self._token('{')
|
|
self._expre_()
|
|
self.name_last_node('@')
|
|
self._token('}')
|
|
with self._optional():
|
|
self._token('*')
|
|
self._cut()
|
|
|
|
@tatsumasu('EmptyClosure')
|
|
def _empty_closure_(self):
|
|
self._token('{')
|
|
self._void()
|
|
self.name_last_node('@')
|
|
self._token('}')
|
|
|
|
@tatsumasu('Optional')
|
|
def _optional_(self):
|
|
self._token('[')
|
|
self._cut()
|
|
self._expre_()
|
|
self.name_last_node('@')
|
|
self._token(']')
|
|
self._cut()
|
|
|
|
@tatsumasu('Special')
|
|
def _special_(self):
|
|
self._token('?(')
|
|
self._cut()
|
|
self._pattern('.*?(?!\\)\\?)')
|
|
self.name_last_node('@')
|
|
self._token(')?')
|
|
self._cut()
|
|
|
|
@tatsumasu('Lookahead')
|
|
def _lookahead_(self):
|
|
self._token('&')
|
|
self._cut()
|
|
self._term_()
|
|
self.name_last_node('@')
|
|
|
|
@tatsumasu('NegativeLookahead')
|
|
def _negative_lookahead_(self):
|
|
self._token('!')
|
|
self._cut()
|
|
self._term_()
|
|
self.name_last_node('@')
|
|
|
|
@tatsumasu('SkipTo')
|
|
def _skip_to_(self):
|
|
self._token('->')
|
|
self._cut()
|
|
self._term_()
|
|
self.name_last_node('@')
|
|
|
|
@tatsumasu()
|
|
def _atom_(self):
|
|
with self._choice():
|
|
with self._option():
|
|
self._cut_()
|
|
with self._option():
|
|
self._cut_deprecated_()
|
|
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._eof_()
|
|
self._error(
|
|
'expecting one of: '
|
|
"'$' '>>' '`' '~' <alert> <call>"
|
|
'<constant> <cut> <cut_deprecated> <eof>'
|
|
'<pattern> <raw_string> <regexes>'
|
|
'<string> <token> <word> \\^+'
|
|
)
|
|
|
|
@tatsumasu('RuleRef')
|
|
def _call_(self):
|
|
self._word_()
|
|
|
|
@tatsumasu('Void')
|
|
def _void_(self):
|
|
self._token('()')
|
|
self._cut()
|
|
|
|
@tatsumasu('Cut')
|
|
def _cut_(self):
|
|
self._token('~')
|
|
self._cut()
|
|
|
|
@tatsumasu('Cut')
|
|
def _cut_deprecated_(self):
|
|
self._token('>>')
|
|
self._cut()
|
|
|
|
@tatsumasu()
|
|
def _known_name_(self):
|
|
self._name_()
|
|
self._cut()
|
|
|
|
@tatsumasu()
|
|
def _name_(self):
|
|
self._word_()
|
|
|
|
@tatsumasu('Constant')
|
|
def _constant_(self):
|
|
with self._if():
|
|
self._token('`')
|
|
with self._group():
|
|
with self._choice():
|
|
with self._option():
|
|
self._pattern('(?ms)```((?:.|\\n)*?)```')
|
|
with self._option():
|
|
self._token('`')
|
|
self._literal_()
|
|
self.name_last_node('@')
|
|
self._token('`')
|
|
with self._option():
|
|
self._pattern('`(.*?)`')
|
|
self._error(
|
|
'expecting one of: '
|
|
"'`' (?ms)```((?:.|\\n)*?)``` `(.*?)`"
|
|
)
|
|
|
|
@tatsumasu('Alert')
|
|
def _alert_(self):
|
|
self._pattern('\\^+')
|
|
self.name_last_node('level')
|
|
self._constant_()
|
|
self.name_last_node('message')
|
|
self._define(['level', 'message'], [])
|
|
|
|
@tatsumasu('Token')
|
|
def _token_(self):
|
|
with self._choice():
|
|
with self._option():
|
|
self._string_()
|
|
with self._option():
|
|
self._raw_string_()
|
|
self._error(
|
|
'expecting one of: '
|
|
'<STRING> <raw_string> <string> r'
|
|
)
|
|
|
|
@tatsumasu()
|
|
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_()
|
|
self._error(
|
|
'expecting one of: '
|
|
"'False' 'None' 'True' (?!\\d)\\w+"
|
|
'0[xX](?:\\d|[a-fA-F])+ <STRING> <boolean>'
|
|
'<float> <hex> <int> <null> <raw_string>'
|
|
'<string> <word> [-'
|
|
'+]?(?:\\d+\\.\\d*|\\d*\\.\\d+)(?:[Ee][-'
|
|
'+]?\\d+)? [-+]?\\d+ r'
|
|
)
|
|
|
|
@tatsumasu()
|
|
def _string_(self):
|
|
self._STRING_()
|
|
|
|
@tatsumasu()
|
|
def _raw_string_(self):
|
|
self._pattern('r')
|
|
self._STRING_()
|
|
self.name_last_node('@')
|
|
|
|
@tatsumasu()
|
|
def _STRING_(self):
|
|
with self._choice():
|
|
with self._option():
|
|
self._pattern('"((?:[^"\\n]|\\\\"|\\\\\\\\)*?)"')
|
|
self.name_last_node('@')
|
|
self._cut()
|
|
with self._option():
|
|
self._pattern("'((?:[^'\\n]|\\\\'|\\\\\\\\)*?)'")
|
|
self.name_last_node('@')
|
|
self._cut()
|
|
self._error(
|
|
'expecting one of: '
|
|
'"((?:[^"\\n]|\\"|\\\\)*?)"'
|
|
"'((?:[^'\\n]|\\'|\\\\)*?)'"
|
|
)
|
|
|
|
@tatsumasu()
|
|
def _hex_(self):
|
|
self._pattern('0[xX](?:\\d|[a-fA-F])+')
|
|
|
|
@tatsumasu()
|
|
def _float_(self):
|
|
self._pattern('[-+]?(?:\\d+\\.\\d*|\\d*\\.\\d+)(?:[Ee][-+]?\\d+)?')
|
|
|
|
@tatsumasu()
|
|
def _int_(self):
|
|
self._pattern('[-+]?\\d+')
|
|
|
|
@tatsumasu()
|
|
def _path_(self):
|
|
self._pattern('(?!\\d)\\w+(?:::(?!\\d)\\w+)+')
|
|
|
|
@tatsumasu()
|
|
def _word_(self):
|
|
self._pattern('(?!\\d)\\w+')
|
|
|
|
@tatsumasu('Any')
|
|
def _any_(self):
|
|
self._token('/./')
|
|
|
|
@tatsumasu('Pattern')
|
|
def _pattern_(self):
|
|
self._regexes_()
|
|
|
|
@tatsumasu()
|
|
def _regexes_(self):
|
|
|
|
def sep0():
|
|
self._token('+')
|
|
|
|
def block1():
|
|
self._regex_()
|
|
self._positive_gather(block1, sep0)
|
|
|
|
@tatsumasu()
|
|
def _regex_(self):
|
|
with self._choice():
|
|
with self._option():
|
|
self._token('/')
|
|
self._cut()
|
|
self._pattern('(?:[^/\\\\]|\\\\/|\\\\.)*')
|
|
self.name_last_node('@')
|
|
self._token('/')
|
|
self._cut()
|
|
with self._option():
|
|
self._token('?/')
|
|
self._cut()
|
|
self._pattern('(?:.|\\n)*?(?=/\\?)')
|
|
self.name_last_node('@')
|
|
self._pattern('/\\?+')
|
|
self._cut()
|
|
with self._option():
|
|
self._token('?')
|
|
self._STRING_()
|
|
self.name_last_node('@')
|
|
self._error(
|
|
'expecting one of: '
|
|
"'/' '?' '?/'"
|
|
)
|
|
|
|
@tatsumasu()
|
|
def _boolean_(self):
|
|
with self._choice():
|
|
with self._option():
|
|
self._token('True')
|
|
with self._option():
|
|
self._token('False')
|
|
self._error(
|
|
'expecting one of: '
|
|
"'False' 'True'"
|
|
)
|
|
|
|
@tatsumasu()
|
|
def _null_(self):
|
|
self._token('None')
|
|
|
|
@tatsumasu('EOF')
|
|
def _eof_(self):
|
|
self._token('$')
|
|
self._cut()
|
|
|
|
|
|
def main(filename, **kwargs):
|
|
if not filename or filename == '-':
|
|
text = sys.stdin.read()
|
|
else:
|
|
text = Path(filename).read_text()
|
|
parser = EBNFBootstrapParser()
|
|
return parser.parse(
|
|
text,
|
|
filename=filename,
|
|
**kwargs,
|
|
)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
import json
|
|
from tatsu.util import asjson
|
|
|
|
ast = generic_main(main, EBNFBootstrapParser, name='EBNFBootstrap')
|
|
data = asjson(ast)
|
|
print(json.dumps(data, indent=2))
|