#!/usr/bin/python
import sys
import re
import string
import copy
def isint(s):
try:
int(s)
return True
except ValueError:
return False
if len(sys.argv) != 2:
print 'Usage: ', sys.argv[0], ' bison_output_file'
sys.exit(1)
bfile = file(sys.argv[1],'r')
sfile = file("spec.txt",'w')
while True:
line = bfile.readline()
if not line or line.strip() == 'Grammar': break
prevnt = ''
stringrules = []
while True:
line = bfile.readline()
if not line or line.strip().startswith('Terminals'): break
if len(line.strip()) == 0: continue
[grnum,nt,rhs] = re.split('(?:\\s|:|/\*.*\*/)+',line.strip(),2)
if nt == '|': nt = prevnt
prevnt = nt
stringrules.append((grnum,[nt] + rhs.split()))
syms = dict()
nonterms = set()
while True:
line = bfile.readline()
if not line or line.strip().startswith('Nonterminals'): break
if len(line.strip()) == 0: continue
[trname,trnum,junk] = re.split('[ ()]+',line.strip(),2)
if trname == 'error': continue
syms[trname] = trnum
nonterms.add(trname)
sfile.write(trnum + ' ' + trname + '\n')
sfile.write('\n')
sfile.flush()
while True:
line = bfile.readline()
if not line or line.strip().startswith('state'): break
if len(line.strip()) == 0 or line.startswith(' ') or line.startswith('\t'):
continue
[ntname,ntnum,junk] = re.split('[ ()]+',line.strip(),2)
syms[ntname] = ntnum
sfile.write(ntnum + ' ' + ntname + '\n')
sfile.write('\n')
sfile.flush()
for (grnum,rule) in stringrules:
sfile.write(grnum)
for sym in rule:
sfile.write(' ' + syms[sym])
sfile.write('\n')
sfile.write('\n')
sfile.flush()
while True:
if not line: break
sfile.write(line.split()[1] + '\n')
fordef = copy.copy(nonterms)
while True:
line = bfile.readline()
if (not line) or line.startswith('state'): break
if len(line.strip()) == 0: continue
if isint(line.split()[0]): continue
sad = re.split('(?:\\s|shift, and|to state|using rule|\(.*\))+',line.strip())
if sad[1] == 'accept':
sfile.write('a\n')
continue
[sym,action,dest] = sad[:3]
if sym == '$default':
for defsym in fordef:
sfile.write(syms[defsym] + ' ')
if action == 'go':
sfile.write('s ')
sfile.write(dest)
elif action == 'reduce':
sfile.write('r ')
sfile.write(dest)
elif action == 'accept':
sfile.write('a')
sfile.write('\n')
else:
fordef.discard(sym)
sfile.write(syms[sym] + ' ')
if action == 'go':
sfile.write('s ')
sfile.write(dest)
elif action == 'reduce':
sfile.write('r ')
sfile.write(dest)
elif action == 'accept':
sfile.write('a')
sfile.write('\n')
sfile.write('\n')
sfile.flush()
bfile.close()
sfile.close()