"""
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')