pgen2min.py
1.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
"""Lists unreachable non-terminals in a pgen grammar
Usage: python pgen2min.py INFILE
"""
import sys, string, os.path
import snakes.lang.pgen as pgen
import collections
if len(sys.argv) < 2 :
print("Usage: python pgen2dot.py INFILE")
sys.exit(1)
root = None
nodes = set()
edges = collections.defaultdict(set)
def walk (st, lex, rule=None) :
global root
tok, children = st
if tok == pgen.PgenParser.RULE :
rule = children[0][0]
if root is None :
root = rule
nodes.add(rule)
for child in children[1:] :
walk(child, lex, rule)
elif isinstance(tok, str) and tok.strip() and tok[0] in string.ascii_lowercase :
nodes.add(tok)
if rule is not None :
edges[rule].add(tok)
else :
for child in children :
walk(child, lex, rule)
st, lex = pgen.PgenParser.parse(sys.argv[1])
walk(st, lex)
reached = set()
next = set([root])
while not next.issubset(reached) :
reached.update(next)
prev = next
next = set()
for n in prev :
next.update(edges[n])
for node in sorted(nodes - reached) :
print(node)