""" This is a simple print visitor. It just outputs the tree back into python code. """ __rev__ = "$?" import compiler import compiler.visitor class NotImplementedException(Exception): pass class Writer(object): def __init__(self): self.__lvl = 0 self.__stack = [''] self.__in_line = False def writeline(self, string): self.__in_line = False self.write(string) self.newline() def write(self, string): if not self.__in_line: self.__stack[-1] += '%s' % (self.__lvl * '\t') self.__in_line = True self.__stack[-1] += '%s' % (string) def newline(self): self.__stack.append('') self.__in_line = False def inclvl(self): self.__lvl += 1 def declvl(self): self.__lvl -= 1 def __str__(self): return '\n'.join(self.__stack) class PrintVisitor(compiler.visitor.ASTVisitor): def __init__(self, *args, **kwargs): compiler.visitor.ASTVisitor.__init__(self) self._results = Writer() def visitAdd(self, node): # Add attributes # left left operand # right right operand # raise NotImplementedException('visitAdd') const_left = isinstance(node.left, compiler.ast.Const) const_right = isinstance(node.right, compiler.ast.Const) if not const_left: self._results.write('(') self.visit(node.left) if not const_left: self._results.write(')') self._results.write('+') if not const_right: self._results.write('(') self.visit(node.right) if not const_right: self._results.write(')') def visitAnd(self, node): # And attributes # nodes list of operands raise NotImplementedException('visitAnd') def visitAssAttr(self, node): # AssAttr attributes # expr expression on the left-hand side of the dot # attrname the attribute name, a string # flags XXX raise NotImplementedException('visitAssAttr') def visitAssList(self, node): # AssList attributes # nodes list of list elements being assigned to raise NotImplementedException('visitAssList') def visitAssName(self, node): # AssName attributes # name name being assigned to # flags XXX # raise NotImplementedException('visitAssName') self._results.write(node.name) def visitAssTuple(self, node): # AssTuple attributes # nodes list of tuple elements being assigned to raise NotImplementedException('visitAssTuple') def visitAssert(self, node): # Assert attributes # test the expression to be tested # fail the value of the AssertionError raise NotImplementedException('visitAssert') def visitAssign(self, node): # Assign attributes # nodes a list of assignment targets, one per equal sign # expr the value being assigned # raise NotImplementedException('visitAssign') for assname in node.nodes: self.visit(assname) self._results.write(' = ') self.visit(node.expr) self._results.newline() def visitAugAssign(self, node): # AugAssign attributes # node # op # expr raise NotImplementedException('visitAugAssign') def visitBackquote(self, node): # Backquote attributes # expr raise NotImplementedException('visitBackquote') def visitBitand(self, node): # Bitand attributes # nodes # raise NotImplementedException('visitBitand') first = True for subnode in node.nodes: if first: first = False else: self._results.write('&') const_subnode = isinstance(subnode, compiler.ast.Const) if not const_subnode: self._results.write('(') self.visit(subnode) if not const_subnode: self._results.write(')') def visitBitor(self, node): # Bitor attributes # nodes # raise NotImplementedException('visitBitor') first = True for subnode in node.nodes: if first: first = False else: self._results.write('|') const_subnode = isinstance(subnode, compiler.ast.Const) if not const_subnode: self._results.write('(') self.visit(subnode) if not const_subnode: self._results.write(')') def visitBitxor(self, node): # Bitxor attributes # nodes # raise NotImplementedException('visitBitxor') first = True for subnode in node.nodes: if first: first = False else: self._results.write('^') const_subnode = isinstance(subnode, compiler.ast.Const) if not const_subnode: self._results.write('(') self.visit(subnode) if not const_subnode: self._results.write(')') def visitBreak(self, node): # Break attributes raise NotImplementedException('visitBreak') def visitCallFunc(self, node): # CallFunc attributes # node expression for the callee # args a list of arguments # star_args the extended *-arg value # dstar_args the extended **-arg value # raise NotImplementedException('visitCallFunc') self.visit(node.node) self._results.write('(') if node.args: for arg in node.args: self.visit(arg) self._results.write(', ') if node.star_args: self._results.write('*') self.visit(node.dstar_args) if node.dstar_args: self._results.write(', ') if node.dstar_args: self._results.write('**') self.visit(node.dstar_args) self._results.write(')') def visitClass(self, node): # Class attributes # name the name of the class, a string # bases a list of base classes # doc doc string, a string or None # code the body of the class statement raise NotImplementedException('visitClass') def visitComment(self, node): # Compare attributes # comment the comment string # raise NotImplementedException('visitComment') self._results.write('# %s' % (node.comment,)) def visitCompare(self, node): # Compare attributes # expr # ops raise NotImplementedException('visitCompare') def visitConst(self, node): # Const attributes # value # raise NotImplementedException('visitConst') if type(node.value) == str: self._results.write("\"%s\"" % node.value.replace('\"','\\\"')) else: self._results.write("%s" % node.value) def visitContinue(self, node): # Continue attributes raise NotImplementedException('visitContinue') def visitDecorators(self, node): # Decorators attributes # nodes List of function decorator expressions raise NotImplementedException('visitDecorators') def visitDict(self, node): # Dict attributes # items # raise NotImplementedException('visitDict') self._results.write('{') self._results.newline() self._results.inclvl() for item in node.items: if isinstance(item, tuple): self.visit(item[0]) self._results.write(': ') self.visit(item[1]) self._results.write(',') else: # for comments self.visit(item) self._results.newline() self._results.declvl() self._results.write('}') def visitDiscard(self, node): # Discard attributes # expr # raise NotImplementedException('visitDiscard') self.visit(node.expr) def visitDiv(self, node): # Div attributes # left # right # raise NotImplementedException('visitDiv') const_left = isinstance(node.left, compiler.ast.Const) const_right = isinstance(node.right, compiler.ast.Const) if not const_left: self._results.write('(') self.visit(node.left) if not const_left: self._results.write(')') self._results.write('/') if not const_right: self._results.write('(') self.visit(node.right) if not const_right: self._results.write(')') def visitEllipsis(self, node): # Ellipsis attributes raise NotImplementedException('visitEllipsis') def visitExpression(self, node): # Expression attributes # node raise NotImplementedException('visitExpression') def visitExec(self, node): # Exec attributes # expr # locals # globals raise NotImplementedException('visitExec') def visitFloorDiv(self, node): # FloorDiv attributes # left # right raise NotImplementedException('visitFloorDiv') def visitFor(self, node): # For attributes # assign # list # body # else_ raise NotImplementedException('visitFor') def visitFrom(self, node): # From attributes # modname # names raise NotImplementedException('visitFrom') def visitFunction(self, node): # Function attributes # decorators Decorators or None # name name used in def, a string # argnames list of argument names, as strings # defaults list of default values # flags xxx # doc doc string, a string or None # code the body of the function raise NotImplementedException('visitFunction') def visitGenExpr(self, node): # GenExpr attributes # code raise NotImplementedException('visitGenExpr') def visitGenExprFor(self, node): # GenExprFor attributes # assign # iter # ifs raise NotImplementedException('visitGenExprFor') def visitGenExprIf(self, node): # GenExprIf attributes # test raise NotImplementedException('visitGenExprIf') def visitGenExprInner(self, node): # GenExprInner attributes # expr # quals raise NotImplementedException('visitGenExprInner') def visitGetattr(self, node): # Getattr attributes # expr # attrname raise NotImplementedException('visitGetattr') def visitGlobal(self, node): # Global attributes # names raise NotImplementedException('visitGlobal') def visitIf(self, node): # If attributes # tests # else_ raise NotImplementedException('visitIf') def visitImport(self, node): # Import attributes # names raise NotImplementedException('visitImport') def visitInvert(self, node): # Invert attributes # expr raise NotImplementedException('visitInvert') def visitKeyword(self, node): # Keyword attributes # name # expr # raise NotImplementedException('visitKeyword') self._results.write('%s=' % node.name) self.visit(node.expr) def visitLambda(self, node): # Lambda attributes # argnames # defaults # flags # code raise NotImplementedException('visitLambda') def visitLeftShift(self, node): # LeftShift attributes # left # right raise NotImplementedException('visitLeftShift') def visitList(self, node): # List attributes # nodes # raise NotImplementedException('visitList') self._results.write('[') self._results.inclvl() for subnode in node.nodes: self.visit(subnode) self._results.write(',') self._results.newline() self._results.declvl() self._results.write(']') def visitListComp(self, node): # ListComp attributes # expr # quals raise NotImplementedException('visitListComp') def visitListCompFor(self, node): # ListCompFor attributes # assign # list # ifs raise NotImplementedException('visitListCompFor') def visitListCompIf(self, node): # ListCompIf attributes # test raise NotImplementedException('visitListCompIf') def visitMod(self, node): # Mod attributes # left # right raise NotImplementedException('visitMod') def visitModule(self, node): # Module attributes # doc doc string, a string or None # node body of the module, a Stmt # raise NotImplementedException('visitModule') self._results.write('\"\"\"%s\"\"\"' % node.doc) self._results.newline() self.visit(node.node) def visitMul(self, node): # Mul attributes # left # right # raise NotImplementedException('visitMul') const_left = isinstance(node.left, compiler.ast.Const) const_right = isinstance(node.right, compiler.ast.Const) if not const_left: self._results.write('(') self.visit(node.left) if not const_left: self._results.write(')') self._results.write('*') if not const_right: self._results.write('(') self.visit(node.right) if not const_right: self._results.write(')') # self._results.write('(') # self.visit(node.left) # self._results.write(')*(') # self.visit(node.right) # self._results.write(')') def visitName(self, node): # Name attributes # name # raise NotImplementedException('visitName') self._results.write('%s' % node.name) def visitNot(self, node): # Not attributes # expr raise NotImplementedException('visitNot') def visitOr(self, node): # Or attributes # nodes raise NotImplementedException('visitOr') def visitPass(self, node): # Pass attributes raise NotImplementedException('visitPass') def visitPower(self, node): # Power attributes # left # right raise NotImplementedException('visitPower') def visitPrint(self, node): # Print attributes # nodes # dest raise NotImplementedException('visitPrint') def visitPrintnl(self, node): # Printnl attributes # nodes # dest raise NotImplementedException('visitPrintnl') def visitRaise(self, node): # Raise attributes # expr1 # expr2 # expr3 raise NotImplementedException('visitRaise') def visitReturn(self, node): # Return attributes # value raise NotImplementedException('visitReturn') def visitRightShift(self, node): # RightShift attributes # left # right raise NotImplementedException('visitRightShift') def visitSlice(self, node): # Slice attributes # expr # flags # lower # upper raise NotImplementedException('visitSlice') def visitSliceobj(self, node): # Sliceobj attributes # nodes list of statements raise NotImplementedException('visitSliceobj') def visitStmt(self, node): # Stmt attributes # nodes # raise NotImplementedException('visitStmt') for stmtnode in node.nodes: self.visit(stmtnode) self._results.newline() def visitSub(self, node): # Sub attributes # left # right # raise NotImplementedException('visitSub') const_left = isinstance(node.left, compiler.ast.Const) const_right = isinstance(node.right, compiler.ast.Const) if not const_left: self._results.write('(') self.visit(node.left) if not const_left: self._results.write(')') self._results.write('-') if not const_right: self._results.write('(') self.visit(node.right) if not const_right: self._results.write(')') def visitSubscript(self, node): # Subscript attributes # expr # flags # subs raise NotImplementedException('visitSubscript') def visitTryExcept(self, node): # TryExcept attributes # body # handlers # else_ raise NotImplementedException('visitTryExcept') def visitTryFinally(self, node): # TryFinally attributes # body # final raise NotImplementedException('visitTryFinally') def visitTuple(self, node): # Tuple attributes # nodes raise NotImplementedException('visitTuple') def visitUnaryAdd(self, node): # UnaryAdd attributes # expr raise NotImplementedException('visitUnaryAdd') def visitUnarySub(self, node): # UnarySub attributes # expr # raise NotImplementedException('visitUnarySub') self._results.write('-') self.visit(node.expr) def visitWhile(self, node): # While attributes # test # body # else_ raise NotImplementedException('visitWhile') def visitWith(self, node): # With attributes # expr # vars # body raise NotImplementedException('visitWith') def visitYield(self, node): # Yield attributes # value raise NotImplementedException('visitYield')