• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3.8
2
3"""Produce a report about the most-memoable types.
4
5Reads a list of statistics from stdin.  Each line must be two numbers,
6being a type and a count.  We then read some other files and produce a
7list sorted by most frequent type.
8
9There should also be something to recognize left-recursive rules.
10"""
11
12import os
13import re
14import sys
15
16from typing import Dict
17
18reporoot = os.path.dirname(os.path.dirname(__file__))
19parse_c = os.path.join(reporoot, "peg_extension", "parse.c")
20
21
22class TypeMapper:
23    """State used to map types to names."""
24
25    def __init__(self, filename: str) -> None:
26        self.table: Dict[int, str] = {}
27        with open(filename) as f:
28            for line in f:
29                match = re.match(r"#define (\w+)_type (\d+)", line)
30                if match:
31                    name, type = match.groups()
32                    if "left" in line.lower():
33                        name += " // Left-recursive"
34                    self.table[int(type)] = name
35
36    def lookup(self, type: int) -> str:
37        return self.table.get(type, str(type))
38
39
40def main() -> None:
41    mapper = TypeMapper(parse_c)
42    table = []
43    filename = sys.argv[1]
44    with open(filename) as f:
45        for lineno, line in enumerate(f, 1):
46            line = line.strip()
47            if not line or line.startswith("#"):
48                continue
49            parts = line.split()
50            # Extra fields ignored
51            if len(parts) < 2:
52                print(f"{lineno}: bad input ({line!r})")
53                continue
54            try:
55                type, count = map(int, parts[:2])
56            except ValueError as err:
57                print(f"{lineno}: non-integer input ({line!r})")
58                continue
59            table.append((type, count))
60    table.sort(key=lambda values: -values[1])
61    for type, count in table:
62        print(f"{type:4d} {count:9d} {mapper.lookup(type)}")
63
64
65if __name__ == "__main__":
66    main()
67