#!/usr/bin/env python3.8 """Produce a report about the most-memoable types. Reads a list of statistics from stdin. Each line must be two numbers, being a type and a count. We then read some other files and produce a list sorted by most frequent type. There should also be something to recognize left-recursive rules. """ import os import re import sys from typing import Dict reporoot = os.path.dirname(os.path.dirname(__file__)) parse_c = os.path.join(reporoot, "peg_extension", "parse.c") class TypeMapper: """State used to map types to names.""" def __init__(self, filename: str) -> None: self.table: Dict[int, str] = {} with open(filename) as f: for line in f: match = re.match(r"#define (\w+)_type (\d+)", line) if match: name, type = match.groups() if "left" in line.lower(): name += " // Left-recursive" self.table[int(type)] = name def lookup(self, type: int) -> str: return self.table.get(type, str(type)) def main() -> None: mapper = TypeMapper(parse_c) table = [] filename = sys.argv[1] with open(filename) as f: for lineno, line in enumerate(f, 1): line = line.strip() if not line or line.startswith("#"): continue parts = line.split() # Extra fields ignored if len(parts) < 2: print(f"{lineno}: bad input ({line!r})") continue try: type, count = map(int, parts[:2]) except ValueError as err: print(f"{lineno}: non-integer input ({line!r})") continue table.append((type, count)) table.sort(key=lambda values: -values[1]) for type, count in table: print(f"{type:4d} {count:9d} {mapper.lookup(type)}") if __name__ == "__main__": main()