(root)/
Python-3.12.0/
Tools/
peg_generator/
scripts/
joinstats.py
       1  #!/usr/bin/env python3.8
       2  
       3  """Produce a report about the most-memoable types.
       4  
       5  Reads a list of statistics from stdin.  Each line must be two numbers,
       6  being a type and a count.  We then read some other files and produce a
       7  list sorted by most frequent type.
       8  
       9  There should also be something to recognize left-recursive rules.
      10  """
      11  
      12  import os
      13  import re
      14  import sys
      15  
      16  from typing import Dict
      17  
      18  reporoot = os.path.dirname(os.path.dirname(__file__))
      19  parse_c = os.path.join(reporoot, "peg_extension", "parse.c")
      20  
      21  
      22  class ESC[4;38;5;81mTypeMapper:
      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  
      40  def 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  
      65  if __name__ == "__main__":
      66      main()