| 13 | |
| 14 | |
| 15 | class ASTGrammarPrinter: |
| 16 | def children(self, node: Rule) -> Iterator[Any]: |
| 17 | for value in node: |
| 18 | if isinstance(value, list): |
| 19 | yield from value |
| 20 | else: |
| 21 | yield value |
| 22 | |
| 23 | def name(self, node: Rule) -> str: |
| 24 | if not list(self.children(node)): |
| 25 | return repr(node) |
| 26 | return node.__class__.__name__ |
| 27 | |
| 28 | def print_grammar_ast(self, grammar: Grammar, printer: Callable[..., None] = print) -> None: |
| 29 | for rule in grammar.rules.values(): |
| 30 | printer(self.print_nodes_recursively(rule)) |
| 31 | |
| 32 | def print_nodes_recursively(self, node: Rule, prefix: str = "", istail: bool = True) -> str: |
| 33 | children = list(self.children(node)) |
| 34 | value = self.name(node) |
| 35 | |
| 36 | line = prefix + ("└──" if istail else "├──") + value + "\n" |
| 37 | sufix = " " if istail else "│ " |
| 38 | |
| 39 | if not children: |
| 40 | return line |
| 41 | |
| 42 | *children, last = children |
| 43 | for child in children: |
| 44 | line += self.print_nodes_recursively(child, prefix + sufix, False) |
| 45 | line += self.print_nodes_recursively(last, prefix + sufix, True) |
| 46 | |
| 47 | return line |
| 48 | |
| 49 | |
| 50 | def main() -> None: |
no outgoing calls
searching dependent graphs…