#!/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()