import triplayacc as yacc import triplalex as lex import syntax from pathlib import Path from graphviz import Source import matplotlib.pyplot as plt import matplotlib.image as mpimg import lib.console as cnsl import os import matplotlib matplotlib.use("TkAgg") # Renders a diagram of the AST def render_diagram(dot_string: str): # Set DPI for PNG os.environ["GV_FILE_DPI"] = "300" src = Source(dot_string, format="png", engine="dot") png_path = src.render(cleanup=True) img = mpimg.imread(png_path) fig = plt.figure(figsize=(12, 12)) fig.canvas.manager.window.wm_title("TRIPLA AST Viewer") plt.imshow(img) plt.axis("off") plt.show() # Pretty prints the AST def pretty_print(node, indent=0): prefix = " " * indent print(f"{prefix}{type(node).__name__}:") for key, value in node.__dict__.items(): if isinstance(value, syntax.EXPRESSION): pretty_print(value, indent + 4) elif isinstance(value, list): print(f"{prefix} {key}: [") for element in value: if isinstance(element, syntax.EXPRESSION): pretty_print(element, indent + 4) else: print(" " * (indent + 4) + str(element)) print(f"{prefix} ]") else: print(f"{prefix} {key}: {value}") # Exports the AST as a DOT file def export_dot_file(dot_string: str, filename: str): try: Path(filename).write_text(dot_string, encoding="utf-8") print(f"Saved DOT file as: {filename}") except Exception as e: print(f"Could not save DOT file: {e}") if __name__ == "__main__": print("\nTRIPLA Parser Tool") while True: choice = cnsl.prompt_choice("\nSelect action:", ["Parse .tripla", "Exit"]) if choice == 1: print("\nBye Bye.") break programs = cnsl.search_programs() if not programs: print("\nNo .tripla files found.") continue idx = cnsl.prompt_choice("\nSelect program to parse:", [p.name for p in programs]) path = programs[idx] source = path.read_text() ast = yacc.parser.parse(source) # Pretty print if cnsl.prompt_confirmation("\nPretty-print AST?"): print("") pretty_print(ast) # Export DOT dot_str = ast.to_dot() if cnsl.prompt_confirmation("Export AST as .dot file?"): default = f"{path.stem}.dot" cnsl = input(f"Filename [{default}]: ").strip() if not cnsl: cnsl = default export_dot_file(dot_str, cnsl) # Display AST diagram if cnsl.prompt_confirmation("Display AST diagram?"): render_diagram(dot_str) print("Rendered AST diagram.")