Viewing file: grammar_visualizer.py (1.82 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
import argparse import sys
from typing import Any, Iterator, Callable
from pegen.build import build_parser from pegen.grammar import Grammar, Rule
argparser = argparse.ArgumentParser( prog="pegen", description="Pretty print the AST for a given PEG grammar" ) argparser.add_argument("filename", help="Grammar description")
class ASTGrammarPrinter: def children(self, node: Rule) -> Iterator[Any]: for value in node: if isinstance(value, list): yield from value else: yield value
def name(self, node: Rule) -> str: if not list(self.children(node)): return repr(node) return node.__class__.__name__
def print_grammar_ast(self, grammar: Grammar, printer: Callable[..., None] = print) -> None: for rule in grammar.rules.values(): printer(self.print_nodes_recursively(rule))
def print_nodes_recursively(self, node: Rule, prefix: str = "", istail: bool = True) -> str:
children = list(self.children(node)) value = self.name(node)
line = prefix + ("└──" if istail else "├──") + value + "\n" sufix = " " if istail else "│ "
if not children: return line
*children, last = children for child in children: line += self.print_nodes_recursively(child, prefix + sufix, False) line += self.print_nodes_recursively(last, prefix + sufix, True)
return line
def main() -> None: args = argparser.parse_args()
try: grammar, parser, tokenizer = build_parser(args.filename) except Exception as err: print("ERROR: Failed to parse grammar file", file=sys.stderr) sys.exit(1)
visitor = ASTGrammarPrinter() visitor.print_grammar_ast(grammar)
if __name__ == "__main__": main()
|