From 872abf78f626ea5c4cecd65751c06fa40991e7f1 Mon Sep 17 00:00:00 2001 From: Eckhart Arnold Date: Mon, 3 Jul 2017 20:48:38 +0200 Subject: [PATCH] - parsers.py: __repr__ and __str__ methods of Parsers adjusted --- DHParser/parsers.py | 38 +++++++++++++++++++------------------- DHParser/syntaxtree.py | 15 +++++++++------ dhparser.py | 5 +++++ 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/DHParser/parsers.py b/DHParser/parsers.py index e9233d8..85dc6a6 100644 --- a/DHParser/parsers.py +++ b/DHParser/parsers.py @@ -805,7 +805,7 @@ class Synonym(UnaryOperator): return None, text def __repr__(self): - return self.name + '=' + self.parser.name + return self.name or self.parser.repr class Optional(UnaryOperator): @@ -826,7 +826,8 @@ class Optional(UnaryOperator): return Node(self, ()), text def __repr__(self): - return '[' + repr(self.parser) + ']' + return '[' + (self.parser.repr[1:-1] if isinstance(self.parser, Alternative) + and not self.parser.name else self.parser.repr) + ']' class ZeroOrMore(Optional): def __call__(self, text: str) -> Tuple[Node, str]: @@ -843,7 +844,8 @@ class ZeroOrMore(Optional): return Node(self, results), text def __repr__(self): - return '{' + repr(self.parser) + '}' + return '{' + (self.parser.repr[1:-1] if isinstance(self.parser, Alternative) + and not self.parser.name else self.parser.repr) + '}' class OneOrMore(UnaryOperator): @@ -870,7 +872,8 @@ class OneOrMore(UnaryOperator): return Node(self, results), text_ def __repr__(self): - return '{' + repr(self.parser) + '}+' + return '{' + (self.parser.repr[1:-1] if isinstance(self.parser, Alternative) + and not self.parser.name else self.parser.repr) + '}+' class Series(NaryOperator): @@ -891,6 +894,9 @@ class Series(NaryOperator): assert len(results) <= len(self.parsers) return Node(self, results), text_ + def __repr__(self): + return " ".join(parser.repr for parser in self.parsers) + def __add__(self, other: Parser) -> 'Series': other_parsers = cast('Series', other).parsers if isinstance(other, Series) else (other,) return Series(*(self.parsers + other_parsers)) @@ -904,9 +910,6 @@ class Series(NaryOperator): self.parsers += other_parsers return self - def __repr__(self): - return '(' + " ".join(repr(parser) for parser in self.parsers) + ')' - class Alternative(NaryOperator): """Matches if at least one of several alternatives matches. Returns @@ -940,7 +943,7 @@ class Alternative(NaryOperator): return None, text def __repr__(self): - return " | ".join(repr(parser) for parser in self.parsers) + return '(' + ' | '.join(parser.repr for parser in self.parsers) + ')' def __or__(self, other: Parser) -> 'Alternative': other_parsers = cast('Alternative', other).parsers \ @@ -986,7 +989,7 @@ class Required(FlowOperator): return node, text_ def __repr__(self): - return '§' + repr(self.parser) + return '§' + self.parser.repr class Lookahead(FlowOperator): @@ -1001,7 +1004,7 @@ class Lookahead(FlowOperator): return None, text def __repr__(self): - return '&' + repr(self.parser) + return '&' + self.parser.repr def sign(self, bool_value) -> bool: return bool_value @@ -1009,7 +1012,7 @@ class Lookahead(FlowOperator): class NegativeLookahead(Lookahead): def __repr__(self): - return '!' + repr(self.parser) + return '!' + self.parser.repr def sign(self, bool_value) -> bool: return not bool_value @@ -1043,7 +1046,7 @@ class Lookbehind(FlowOperator): return None, text def __repr__(self): - return '-&' + repr(self.parser) + return '-&' + self.parser.repr def sign(self, bool_value) -> bool: return bool_value @@ -1061,7 +1064,7 @@ class Lookbehind(FlowOperator): class NegativeLookbehind(Lookbehind): def __repr__(self): - return '-!' + repr(self.parser) + return '-!' + self.parser.repr def sign(self, bool_value) -> bool: return not bool_value @@ -1091,7 +1094,7 @@ class Capture(UnaryOperator): return None, text def __repr__(self): - return repr(self.parser) + return self.parser.repr RetrieveFilter = Callable[[List[str]], str] @@ -1124,7 +1127,7 @@ class Retrieve(Parser): return self.call(text) # allow call method to be called from subclass circumventing the parser guard def __repr__(self): - return ':' + repr(self.symbol) + return ':' + self.symbol.repr def call(self, text: str) -> Tuple[Node, str]: try: @@ -1151,7 +1154,7 @@ class Pop(Retrieve): return nd, txt def __repr__(self): - return '::' + repr(self.symbol) + return '::' + self.symbol.repr ######################################################################## @@ -1186,9 +1189,6 @@ class Forward(Parser): self.cycle_reached = False return s - def __str__(self): - return "Forward->" + str(self.parser) - def set(self, parser: Parser): # assert isinstance(parser, Parser) # self.name = parser.name # redundant, see Grammar-constructor diff --git a/DHParser/syntaxtree.py b/DHParser/syntaxtree.py index 0fa6f5d..ba13bfd 100644 --- a/DHParser/syntaxtree.py +++ b/DHParser/syntaxtree.py @@ -83,13 +83,19 @@ class ParserBase: self.name = name # type: str self._ptype = ':' + self.__class__.__name__ # type: str + def __repr__(self): + self.name + self.ptype + def __str__(self): - return self.name or self.ptype + return self.name or repr(self) @property def ptype(self) -> str: return self._ptype + @property + def repr(self) -> str: + return self.name if self.name else repr(self) class MockParser(ParserBase): """ @@ -107,8 +113,8 @@ class MockParser(ParserBase): self.name = name self._ptype = ptype or ':' + self.__class__.__name__ - def __repr__(self): - return repr_call(self.__init__, (self.name, self.ptype)) + # def __repr__(self): + # return repr_call(self.__init__, (self.name, self.ptype)) class ZombieParser(MockParser): @@ -129,9 +135,6 @@ class ZombieParser(MockParser): assert self.__class__ == ZombieParser, "No derivatives, please!" self.__class__.alive = True - def __repr__(self): - return "ZOMBIE_PARSER" - def __copy__(self): return self diff --git a/dhparser.py b/dhparser.py index 9edbfe5..b94c5d8 100755 --- a/dhparser.py +++ b/dhparser.py @@ -36,6 +36,11 @@ def selftest(file_name): grammar = f.read() compiler_name = os.path.basename(os.path.splitext(file_name)[0]) parser = get_ebnf_grammar() + print("\nAlphabetical List of Parsers:\n") + parser_list = sorted([p for p in parser.all_parsers__ if p.name], key=lambda p: p.name) + for p in parser_list: + print("%s = %s" % (p.name, repr(p))) + print('\n\n') transformer = get_ebnf_transformer() compiler = get_ebnf_compiler(compiler_name, grammar) result, errors, syntax_tree = compile_source(grammar, None, parser, -- GitLab