mirror of
https://github.com/python/cpython.git
synced 2025-08-30 21:48:47 +00:00
bpo-40334: PEP 617 implementation: New PEG parser for CPython (GH-19503)
Co-authored-by: Guido van Rossum <guido@python.org> Co-authored-by: Lysandros Nikolaou <lisandrosnik@gmail.com>
This commit is contained in:
parent
a81849b031
commit
c5fc156852
91 changed files with 27057 additions and 146 deletions
65
Tools/peg_generator/pegen/grammar_visualizer.py
Normal file
65
Tools/peg_generator/pegen/grammar_visualizer.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
import argparse
|
||||
import sys
|
||||
|
||||
from typing import Any, Iterator, Iterable, 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()
|
Loading…
Add table
Add a link
Reference in a new issue