is_a = isinstance from t2 import * from pdb import set_trace as trace from pprint import pprint as pp def make_map (l): m = {} for i in range (len (l)): m[l[i]] = i return m def build_tables (s): tokens = s._tokens.keys() nonterms = s._nonterms.keys() goto = s._goto action = s._action token_map = make_map (tokens) nt_map = make_map (nonterms) action2 = [] for i in range (len (action)): d = {} for k,v in action[i].iteritems(): # v is always a one-element list? GLR-related? if is_a (v[0], Parsing.ShiftAction): v = -1, v[0].nextState elif is_a (v[0], Parsing.ReduceAction): p = v[0].production v = -2, (len(p.rhs), p.lhs.name) else: raise ValueError d[token_map[k.name]] = v action2.append (d) goto2 = [] for i in range (len (goto)): d = {} for k,v in goto[i].iteritems(): d[k.name] = v goto2.append (d) return goto2, action2, token_map, nt_map def get_state (stack): if stack: return stack[-1][1] else: return 0 def machine (goto, action, tmap, ntmap, stream): stack = [] while len(stream): kind, val = stream[0] state = get_state (stack) print '----- stack=', stack print '***** kind,val=',kind,val print '********* state=',state shift_reduce, n = action[state][tmap[kind]] if shift_reduce is -1: # shift stream.pop (0) stack.append ((val, n)) elif shift_reduce is -2: # reduce plen, nt = n print '------- plen,nt=', plen, nt if plen == 0: args = [] else: stack, args = stack[:-plen], stack[-plen:] next_state = goto[get_state(stack)][nt] stack.append (((nt,[x[0] for x in args]), next_state)) if stack[-1][0] == '<$>': return stack[0][0] else: raise SyntaxError import sys stream = [ ('NAME','x'), ('plus','+'), ('NAME','y'), ('slash','/'), ('NAME','z'), ('splatsplat','**'), ('NUMBER','3'), ('<$>','<$>') ] stream = [ ('NAME','x'), ('or','or'), ('NAME','y'), ('or','or'), ('NAME','z'), ('<$>','<$>') ] stream = [ ('def','def'), ('NAME','thing'), ('lparen','('), ('NAME','x'), ('rparen',')'), ('colon', ':'), ('NEWLINE', ''), ('INDENT', ''), ('pass', 'pass'), ('NEWLINE', ''), ('DEDENT', ''), ('<$>','<$>') ] class Parser (Parsing.Lr): def scan (self, input): for ttype, tdata in input: tok = eval ('t_%s' % (ttype,)) (self) self.token (tok) self.eoi() spec = Parsing.Spec (sys.modules[__name__], skinny=False, logFile="t0.log", verbose=True) #p = Parser (spec) #p._verbose = True #p.scan (stream) goto, action, tmap, ntmap = build_tables (spec) pp (machine (goto, action, tmap, ntmap, stream))