import sys from ast_token import tokenmap from ast_grammar import symbolmap debug = 0 def st2ast(st): """Transform a concrete syntax tree into an abstract one.""" if not isinstance(st, tuple): st = st.totuple() return sttuple2ast(st) stmap = {} stmap.update(tokenmap) stmap.update(symbolmap) ##def sttuple2ast(sttuple): ## if isinstance(sttuple, tuple): ## fn = stmap[sttuple[0]] ## nodes = [sttuple2ast(t) for t in sttuple[1:]] ## if debug: ## print >> sys.stderr, '%s(%s)' % ( ## fn.func_name, ', '.join([repr(n) for n in nodes])), ## result = fn(*nodes) ## if debug: ## print >> sys.stderr, '->', repr(result) ## return result ## else: ## return sttuple def sttuple2ast(sttuple): # non-recursive version stack = [0, sttuple] stackpos = 1 while stackpos: sttuple = stack[stackpos] n = len(stack) - stackpos if n < len(sttuple): result = sttuple[n] if isinstance(result, tuple): stack.append(stackpos) stackpos = len(stack) else: fn = stmap[sttuple[0]] nodes = stack[stackpos+1:] del stack[stackpos:] if debug: print >> sys.stderr, '%s(%s)' % ( fn.func_name, ', '.join([repr(n) for n in nodes])), result = fn(*nodes) if debug: print >> sys.stderr, '->', repr(result) stackpos = stack.pop() stack.append(result) assert len(stack) == 1 return stack.pop() def DISABLED_sttuple2ast(sttuple): # another non-recursive version previous = None it = iter(sttuple) nodes = [stmap[it.next()]] while True: for arg in it: if isinstance(arg, tuple): previous = previous, it, nodes it = iter(arg) nodes = [stmap[it.next()]] break nodes.append(arg) else: fn = nodes[0] if debug: print >> sys.stderr, '%s(%s)' % ( fn.func_name, ', '.join([repr(n) for n in nodes[1:]])), result = fn(*nodes[1:]) if debug: print >> sys.stderr, '->', repr(result) if previous is None: return result previous, it, nodes = previous nodes.append(result)