Commit d4f4671d authored by Eckhart Arnold's avatar Eckhart Arnold
Browse files

parse.py: Added method as_ebnf() to Grammar class

parent 192d8b22
......@@ -326,6 +326,11 @@ def get_ebnf_transformer() -> TransformationFunc:
return transformer
def serialize_EBNF_AST(ast: Node) -> str:
"""Converts the AST generated from and EBNF-text back to EBNF."""
pass
########################################################################
#
# EBNF abstract syntax tree to Python parser compilation
......
......@@ -1045,6 +1045,8 @@ class Grammar:
except (NameError, AttributeError):
pass # don't fail the initialization of PLACEHOLDER
def __str__(self):
return self.__class__.__name__
def __getitem__(self, key):
try:
......@@ -1059,7 +1061,6 @@ class Grammar:
return self[key]
raise UnknownParserError('Unknown parser "%s" !' % key)
def __contains__(self, key):
return key in self.__dict__ or hasattr(self, key)
......@@ -1316,9 +1317,23 @@ class Grammar:
return line_col(self.document_lbreaks__, self.document_length__ - len(text))
def as_ebnf(self) -> str:
"""
EXPERIMENTAL. Does not yet support serialization of DHParser- directives.
Serializes the Grammar object as a grammar-description in the
Extended Backus-Naur-Form.
"""
ebnf = []
for entry, parser in self.__dict__.items():
if isinstance(parser, Parser) and sane_parser_name(entry):
ebnf.append(str(parser))
return '\n'.join(ebnf)
def static_analysis(self) -> List[GrammarErrorType]:
"""
EXPERIMENTAL
EXPERIMENTAL!!!
Checks the parser tree statically for possible errors. At the moment,
no checks are implemented
......@@ -1459,7 +1474,8 @@ class Token(Parser):
return None, text
def __repr__(self):
return ("'%s'" if self.text.find("'") <= 0 else '"%s"') % abbreviate_middle(self.text, 80)
return '`%s`' % abbreviate_middle(self.text, 80)
# return ("'%s'" if self.text.find("'") <= 0 else '"%s"') % abbreviate_middle(self.text, 80)
class RegExp(Parser):
......@@ -1509,7 +1525,17 @@ class RegExp(Parser):
return None, text
def __repr__(self):
return escape_control_characters('/%s/' % abbreviate_middle(self.regexp.pattern, 120))
pattern = self.regexp.pattern
try:
if pattern == self._grammar.WSP_RE__:
return '~'
elif pattern == self._grammar.COMMENT__:
return 'comment__'
elif pattern == self._grammar.WHITESPACE__:
return 'whitespace__'
except (AttributeError, NameError):
pass
return escape_control_characters('/%s/' % abbreviate_middle(pattern, 120))
def DropToken(text: str) -> Token:
......@@ -2097,6 +2123,8 @@ class Alternative(NaryParser):
return None, text
def __repr__(self):
if self.pname:
return ' | '.join(parser.repr for parser in self.parsers)
return '(' + ' | '.join(parser.repr for parser in self.parsers) + ')'
def reset(self):
......
......@@ -472,6 +472,11 @@ class TestSeries:
# print(parser.python_src__)
# print(parser_class.python_src__)
def test_ebnf_serialization(self):
ebnf_grammar = get_ebnf_grammar()
print(ebnf_grammar.as_ebnf())
class TestAllOfSomeOf:
def test_allOf_order(self):
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment