You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
883 lines
24 KiB
883 lines
24 KiB
2 years ago
|
""" Turn compiler.ast structures back into executable python code.
|
||
|
|
||
|
The unparse method takes a compiler.ast tree and transforms it back into
|
||
|
valid python code. It is incomplete and currently only works for
|
||
|
import statements, function calls, function definitions, assignments, and
|
||
|
basic expressions.
|
||
|
|
||
|
Inspired by python-2.5-svn/Demo/parser/unparse.py
|
||
|
|
||
|
fixme: We may want to move to using _ast trees because the compiler for
|
||
|
them is about 6 times faster than compiler.compile.
|
||
|
"""
|
||
|
from __future__ import division, absolute_import, print_function
|
||
|
|
||
|
import sys
|
||
|
from compiler.ast import Const, Name, Tuple, Div, Mul, Sub, Add
|
||
|
|
||
|
if sys.version_info[0] >= 3:
|
||
|
from io import StringIO
|
||
|
else:
|
||
|
from StringIO import StringIO
|
||
|
|
||
|
|
||
|
def unparse(ast, single_line_functions=False):
|
||
|
s = StringIO()
|
||
|
UnparseCompilerAst(ast, s, single_line_functions)
|
||
|
return s.getvalue().lstrip()
|
||
|
|
||
|
|
||
|
op_precedence = {
|
||
|
"compiler.ast.Power": 3,
|
||
|
"compiler.ast.Mul": 2,
|
||
|
"compiler.ast.Div": 2,
|
||
|
"compiler.ast.Add": 1,
|
||
|
"compiler.ast.Sub": 1,
|
||
|
}
|
||
|
|
||
|
|
||
|
class UnparseCompilerAst:
|
||
|
""" Methods in this class recursively traverse an AST and
|
||
|
output source code for the abstract syntax; original formatting
|
||
|
is disregarged.
|
||
|
"""
|
||
|
|
||
|
#########################################################################
|
||
|
# object interface.
|
||
|
#########################################################################
|
||
|
|
||
|
def __init__(self, tree, file=sys.stdout, single_line_functions=False):
|
||
|
""" Unparser(tree, file=sys.stdout) -> None.
|
||
|
|
||
|
Print the source for tree to file.
|
||
|
"""
|
||
|
self.f = file
|
||
|
self._single_func = single_line_functions
|
||
|
self._do_indent = True
|
||
|
self._indent = 0
|
||
|
self._dispatch(tree)
|
||
|
self._write("\n")
|
||
|
self.f.flush()
|
||
|
|
||
|
#########################################################################
|
||
|
# Unparser private interface.
|
||
|
#########################################################################
|
||
|
|
||
|
### format, output, and dispatch methods ################################
|
||
|
|
||
|
def _fill(self, text=""):
|
||
|
"Indent a piece of text, according to the current indentation level"
|
||
|
if self._do_indent:
|
||
|
self._write("\n" + " " * self._indent + text)
|
||
|
else:
|
||
|
self._write(text)
|
||
|
|
||
|
def _write(self, text):
|
||
|
"Append a piece of text to the current line."
|
||
|
self.f.write(text)
|
||
|
|
||
|
def _enter(self):
|
||
|
"Print ':', and increase the indentation."
|
||
|
self._write(": ")
|
||
|
self._indent += 1
|
||
|
|
||
|
def _leave(self):
|
||
|
"Decrease the indentation level."
|
||
|
self._indent -= 1
|
||
|
|
||
|
def _dispatch(self, tree):
|
||
|
"_dispatcher function, _dispatching tree type T to method _T."
|
||
|
if isinstance(tree, list):
|
||
|
for t in tree:
|
||
|
self._dispatch(t)
|
||
|
return
|
||
|
meth = getattr(self, "_" + tree.__class__.__name__)
|
||
|
if tree.__class__.__name__ == "NoneType" and not self._do_indent:
|
||
|
return
|
||
|
meth(tree)
|
||
|
|
||
|
#########################################################################
|
||
|
# compiler.ast unparsing methods.
|
||
|
#
|
||
|
# There should be one method per concrete grammar type. They are
|
||
|
# organized in alphabetical order.
|
||
|
#########################################################################
|
||
|
|
||
|
def _Add(self, t):
|
||
|
self.__binary_op(t, "+")
|
||
|
|
||
|
def _And(self, t):
|
||
|
self._write(" (")
|
||
|
for i, node in enumerate(t.nodes):
|
||
|
self._dispatch(node)
|
||
|
if i != len(t.nodes) - 1:
|
||
|
self._write(") and (")
|
||
|
self._write(")")
|
||
|
|
||
|
def _AssAttr(self, t):
|
||
|
""" Handle assigning an attribute of an object
|
||
|
"""
|
||
|
self._dispatch(t.expr)
|
||
|
self._write("." + t.attrname)
|
||
|
|
||
|
def _Assign(self, t):
|
||
|
""" Expression Assignment such as "a = 1".
|
||
|
|
||
|
This only handles assignment in expressions. Keyword assignment
|
||
|
is handled separately.
|
||
|
"""
|
||
|
self._fill()
|
||
|
for target in t.nodes:
|
||
|
self._dispatch(target)
|
||
|
self._write(" = ")
|
||
|
self._dispatch(t.expr)
|
||
|
if not self._do_indent:
|
||
|
self._write("; ")
|
||
|
|
||
|
def _AssName(self, t):
|
||
|
""" Name on left hand side of expression.
|
||
|
|
||
|
Treat just like a name on the right side of an expression.
|
||
|
"""
|
||
|
self._Name(t)
|
||
|
|
||
|
def _AssTuple(self, t):
|
||
|
""" Tuple on left hand side of an expression.
|
||
|
"""
|
||
|
|
||
|
# _write each elements, separated by a comma.
|
||
|
for element in t.nodes[:-1]:
|
||
|
self._dispatch(element)
|
||
|
self._write(", ")
|
||
|
|
||
|
# Handle the last one without writing comma
|
||
|
last_element = t.nodes[-1]
|
||
|
self._dispatch(last_element)
|
||
|
|
||
|
def _AugAssign(self, t):
|
||
|
""" +=,-=,*=,/=,**=, etc. operations
|
||
|
"""
|
||
|
|
||
|
self._fill()
|
||
|
self._dispatch(t.node)
|
||
|
self._write(" " + t.op + " ")
|
||
|
self._dispatch(t.expr)
|
||
|
if not self._do_indent:
|
||
|
self._write(";")
|
||
|
|
||
|
def _Bitand(self, t):
|
||
|
""" Bit and operation.
|
||
|
"""
|
||
|
|
||
|
for i, node in enumerate(t.nodes):
|
||
|
self._write("(")
|
||
|
self._dispatch(node)
|
||
|
self._write(")")
|
||
|
if i != len(t.nodes) - 1:
|
||
|
self._write(" & ")
|
||
|
|
||
|
def _Bitor(self, t):
|
||
|
""" Bit or operation
|
||
|
"""
|
||
|
|
||
|
for i, node in enumerate(t.nodes):
|
||
|
self._write("(")
|
||
|
self._dispatch(node)
|
||
|
self._write(")")
|
||
|
if i != len(t.nodes) - 1:
|
||
|
self._write(" | ")
|
||
|
|
||
|
def _CallFunc(self, t):
|
||
|
""" Function call.
|
||
|
"""
|
||
|
self._dispatch(t.node)
|
||
|
self._write("(")
|
||
|
comma = False
|
||
|
for e in t.args:
|
||
|
if comma:
|
||
|
self._write(", ")
|
||
|
else:
|
||
|
comma = True
|
||
|
self._dispatch(e)
|
||
|
if t.star_args:
|
||
|
if comma:
|
||
|
self._write(", ")
|
||
|
else:
|
||
|
comma = True
|
||
|
self._write("*")
|
||
|
self._dispatch(t.star_args)
|
||
|
if t.dstar_args:
|
||
|
if comma:
|
||
|
self._write(", ")
|
||
|
else:
|
||
|
comma = True
|
||
|
self._write("**")
|
||
|
self._dispatch(t.dstar_args)
|
||
|
self._write(")")
|
||
|
|
||
|
def _Compare(self, t):
|
||
|
self._dispatch(t.expr)
|
||
|
for op, expr in t.ops:
|
||
|
self._write(" " + op + " ")
|
||
|
self._dispatch(expr)
|
||
|
|
||
|
def _Const(self, t):
|
||
|
""" A constant value such as an integer value, 3, or a string, "hello".
|
||
|
"""
|
||
|
self._dispatch(t.value)
|
||
|
|
||
|
def _Decorators(self, t):
|
||
|
""" Handle function decorators (eg. @has_units)
|
||
|
"""
|
||
|
for node in t.nodes:
|
||
|
self._dispatch(node)
|
||
|
|
||
|
def _Dict(self, t):
|
||
|
self._write("{")
|
||
|
for i, (k, v) in enumerate(t.items):
|
||
|
self._dispatch(k)
|
||
|
self._write(": ")
|
||
|
self._dispatch(v)
|
||
|
if i < len(t.items) - 1:
|
||
|
self._write(", ")
|
||
|
self._write("}")
|
||
|
|
||
|
def _Discard(self, t):
|
||
|
""" Node for when return value is ignored such as in "foo(a)".
|
||
|
"""
|
||
|
self._fill()
|
||
|
self._dispatch(t.expr)
|
||
|
|
||
|
def _Div(self, t):
|
||
|
self.__binary_op(t, "/")
|
||
|
|
||
|
def _Ellipsis(self, t):
|
||
|
self._write("...")
|
||
|
|
||
|
def _From(self, t):
|
||
|
""" Handle "from xyz import foo, bar as baz".
|
||
|
"""
|
||
|
# fixme: Are From and ImportFrom handled differently?
|
||
|
self._fill("from ")
|
||
|
self._write(t.modname)
|
||
|
self._write(" import ")
|
||
|
for i, (name, asname) in enumerate(t.names):
|
||
|
if i != 0:
|
||
|
self._write(", ")
|
||
|
self._write(name)
|
||
|
if asname is not None:
|
||
|
self._write(" as " + asname)
|
||
|
|
||
|
def _Function(self, t):
|
||
|
""" Handle function definitions
|
||
|
"""
|
||
|
if t.decorators is not None:
|
||
|
self._fill("@")
|
||
|
self._dispatch(t.decorators)
|
||
|
self._fill("def " + t.name + "(")
|
||
|
defaults = [None] * (len(t.argnames) - len(t.defaults)) + list(t.defaults)
|
||
|
for i, arg in enumerate(zip(t.argnames, defaults)):
|
||
|
self._write(arg[0])
|
||
|
if arg[1] is not None:
|
||
|
self._write("=")
|
||
|
self._dispatch(arg[1])
|
||
|
if i < len(t.argnames) - 1:
|
||
|
self._write(", ")
|
||
|
self._write(")")
|
||
|
if self._single_func:
|
||
|
self._do_indent = False
|
||
|
self._enter()
|
||
|
self._dispatch(t.code)
|
||
|
self._leave()
|
||
|
self._do_indent = True
|
||
|
|
||
|
def _Getattr(self, t):
|
||
|
""" Handle getting an attribute of an object
|
||
|
"""
|
||
|
if isinstance(t.expr, (Div, Mul, Sub, Add)):
|
||
|
self._write("(")
|
||
|
self._dispatch(t.expr)
|
||
|
self._write(")")
|
||
|
else:
|
||
|
self._dispatch(t.expr)
|
||
|
|
||
|
self._write("." + t.attrname)
|
||
|
|
||
|
def _If(self, t):
|
||
|
self._fill()
|
||
|
|
||
|
for i, (compare, code) in enumerate(t.tests):
|
||
|
if i == 0:
|
||
|
self._write("if ")
|
||
|
else:
|
||
|
self._write("elif ")
|
||
|
self._dispatch(compare)
|
||
|
self._enter()
|
||
|
self._fill()
|
||
|
self._dispatch(code)
|
||
|
self._leave()
|
||
|
self._write("\n")
|
||
|
|
||
|
if t.else_ is not None:
|
||
|
self._write("else")
|
||
|
self._enter()
|
||
|
self._fill()
|
||
|
self._dispatch(t.else_)
|
||
|
self._leave()
|
||
|
self._write("\n")
|
||
|
|
||
|
def _IfExp(self, t):
|
||
|
self._dispatch(t.then)
|
||
|
self._write(" if ")
|
||
|
self._dispatch(t.test)
|
||
|
|
||
|
if t.else_ is not None:
|
||
|
self._write(" else (")
|
||
|
self._dispatch(t.else_)
|
||
|
self._write(")")
|
||
|
|
||
|
def _Import(self, t):
|
||
|
""" Handle "import xyz.foo".
|
||
|
"""
|
||
|
self._fill("import ")
|
||
|
|
||
|
for i, (name, asname) in enumerate(t.names):
|
||
|
if i != 0:
|
||
|
self._write(", ")
|
||
|
self._write(name)
|
||
|
if asname is not None:
|
||
|
self._write(" as " + asname)
|
||
|
|
||
|
def _Keyword(self, t):
|
||
|
""" Keyword value assignment within function calls and definitions.
|
||
|
"""
|
||
|
self._write(t.name)
|
||
|
self._write("=")
|
||
|
self._dispatch(t.expr)
|
||
|
|
||
|
def _List(self, t):
|
||
|
self._write("[")
|
||
|
for i, node in enumerate(t.nodes):
|
||
|
self._dispatch(node)
|
||
|
if i < len(t.nodes) - 1:
|
||
|
self._write(", ")
|
||
|
self._write("]")
|
||
|
|
||
|
def _Module(self, t):
|
||
|
if t.doc is not None:
|
||
|
self._dispatch(t.doc)
|
||
|
self._dispatch(t.node)
|
||
|
|
||
|
def _Mul(self, t):
|
||
|
self.__binary_op(t, "*")
|
||
|
|
||
|
def _Name(self, t):
|
||
|
self._write(t.name)
|
||
|
|
||
|
def _NoneType(self, t):
|
||
|
self._write("None")
|
||
|
|
||
|
def _Not(self, t):
|
||
|
self._write("not (")
|
||
|
self._dispatch(t.expr)
|
||
|
self._write(")")
|
||
|
|
||
|
def _Or(self, t):
|
||
|
self._write(" (")
|
||
|
for i, node in enumerate(t.nodes):
|
||
|
self._dispatch(node)
|
||
|
if i != len(t.nodes) - 1:
|
||
|
self._write(") or (")
|
||
|
self._write(")")
|
||
|
|
||
|
def _Pass(self, t):
|
||
|
self._write("pass\n")
|
||
|
|
||
|
def _Printnl(self, t):
|
||
|
self._fill("print ")
|
||
|
if t.dest:
|
||
|
self._write(">> ")
|
||
|
self._dispatch(t.dest)
|
||
|
self._write(", ")
|
||
|
comma = False
|
||
|
for node in t.nodes:
|
||
|
if comma:
|
||
|
self._write(", ")
|
||
|
else:
|
||
|
comma = True
|
||
|
self._dispatch(node)
|
||
|
|
||
|
def _Power(self, t):
|
||
|
self.__binary_op(t, "**")
|
||
|
|
||
|
def _Return(self, t):
|
||
|
self._fill("return ")
|
||
|
if t.value:
|
||
|
if isinstance(t.value, Tuple):
|
||
|
text = ", ".join([name.name for name in t.value.asList()])
|
||
|
self._write(text)
|
||
|
else:
|
||
|
self._dispatch(t.value)
|
||
|
if not self._do_indent:
|
||
|
self._write("; ")
|
||
|
|
||
|
def _Slice(self, t):
|
||
|
self._dispatch(t.expr)
|
||
|
self._write("[")
|
||
|
if t.lower:
|
||
|
self._dispatch(t.lower)
|
||
|
self._write(":")
|
||
|
if t.upper:
|
||
|
self._dispatch(t.upper)
|
||
|
# if t.step:
|
||
|
# self._write(":")
|
||
|
# self._dispatch(t.step)
|
||
|
self._write("]")
|
||
|
|
||
|
def _Sliceobj(self, t):
|
||
|
for i, node in enumerate(t.nodes):
|
||
|
if i != 0:
|
||
|
self._write(":")
|
||
|
if not (isinstance(node, Const) and node.value is None):
|
||
|
self._dispatch(node)
|
||
|
|
||
|
def _Stmt(self, tree):
|
||
|
for node in tree.nodes:
|
||
|
self._dispatch(node)
|
||
|
|
||
|
def _Sub(self, t):
|
||
|
self.__binary_op(t, "-")
|
||
|
|
||
|
def _Subscript(self, t):
|
||
|
self._dispatch(t.expr)
|
||
|
self._write("[")
|
||
|
for i, value in enumerate(t.subs):
|
||
|
if i != 0:
|
||
|
self._write(",")
|
||
|
self._dispatch(value)
|
||
|
self._write("]")
|
||
|
|
||
|
def _TryExcept(self, t):
|
||
|
self._fill("try")
|
||
|
self._enter()
|
||
|
self._dispatch(t.body)
|
||
|
self._leave()
|
||
|
|
||
|
for handler in t.handlers:
|
||
|
self._fill("except ")
|
||
|
self._dispatch(handler[0])
|
||
|
if handler[1] is not None:
|
||
|
self._write(", ")
|
||
|
self._dispatch(handler[1])
|
||
|
self._enter()
|
||
|
self._dispatch(handler[2])
|
||
|
self._leave()
|
||
|
|
||
|
if t.else_:
|
||
|
self._fill("else")
|
||
|
self._enter()
|
||
|
self._dispatch(t.else_)
|
||
|
self._leave()
|
||
|
|
||
|
def _Tuple(self, t):
|
||
|
|
||
|
if not t.nodes:
|
||
|
# Empty tuple.
|
||
|
self._write("()")
|
||
|
else:
|
||
|
self._write("(")
|
||
|
|
||
|
# _write each elements, separated by a comma.
|
||
|
for element in t.nodes[:-1]:
|
||
|
self._dispatch(element)
|
||
|
self._write(", ")
|
||
|
|
||
|
# Handle the last one without writing comma
|
||
|
last_element = t.nodes[-1]
|
||
|
self._dispatch(last_element)
|
||
|
|
||
|
self._write(")")
|
||
|
|
||
|
def _UnaryAdd(self, t):
|
||
|
self._write("+")
|
||
|
self._dispatch(t.expr)
|
||
|
|
||
|
def _UnarySub(self, t):
|
||
|
self._write("-")
|
||
|
self._dispatch(t.expr)
|
||
|
|
||
|
def _With(self, t):
|
||
|
self._fill("with ")
|
||
|
self._dispatch(t.expr)
|
||
|
if t.vars:
|
||
|
self._write(" as ")
|
||
|
self._dispatch(t.vars.name)
|
||
|
self._enter()
|
||
|
self._dispatch(t.body)
|
||
|
self._leave()
|
||
|
self._write("\n")
|
||
|
|
||
|
def _int(self, t):
|
||
|
self._write(repr(t))
|
||
|
|
||
|
def __binary_op(self, t, symbol):
|
||
|
# Check if parenthesis are needed on left side and then dispatch
|
||
|
has_paren = False
|
||
|
left_class = str(t.left.__class__)
|
||
|
if (
|
||
|
left_class in op_precedence.keys()
|
||
|
and op_precedence[left_class] < op_precedence[str(t.__class__)]
|
||
|
):
|
||
|
has_paren = True
|
||
|
if has_paren:
|
||
|
self._write("(")
|
||
|
self._dispatch(t.left)
|
||
|
if has_paren:
|
||
|
self._write(")")
|
||
|
# Write the appropriate symbol for operator
|
||
|
self._write(symbol)
|
||
|
# Check if parenthesis are needed on the right side and then dispatch
|
||
|
has_paren = False
|
||
|
right_class = str(t.right.__class__)
|
||
|
if (
|
||
|
right_class in op_precedence.keys()
|
||
|
and op_precedence[right_class] < op_precedence[str(t.__class__)]
|
||
|
):
|
||
|
has_paren = True
|
||
|
if has_paren:
|
||
|
self._write("(")
|
||
|
self._dispatch(t.right)
|
||
|
if has_paren:
|
||
|
self._write(")")
|
||
|
|
||
|
def _float(self, t):
|
||
|
# if t is 0.1, str(t)->'0.1' while repr(t)->'0.1000000000001'
|
||
|
# We prefer str here.
|
||
|
self._write(str(t))
|
||
|
|
||
|
def _str(self, t):
|
||
|
self._write(repr(t))
|
||
|
|
||
|
def _tuple(self, t):
|
||
|
self._write(str(t))
|
||
|
|
||
|
#########################################################################
|
||
|
# These are the methods from the _ast modules unparse.
|
||
|
#
|
||
|
# As our needs to handle more advanced code increase, we may want to
|
||
|
# modify some of the methods below so that they work for compiler.ast.
|
||
|
#########################################################################
|
||
|
|
||
|
|
||
|
# # stmt
|
||
|
# def _Expr(self, tree):
|
||
|
# self._fill()
|
||
|
# self._dispatch(tree.value)
|
||
|
#
|
||
|
# def _Import(self, t):
|
||
|
# self._fill("import ")
|
||
|
# first = True
|
||
|
# for a in t.names:
|
||
|
# if first:
|
||
|
# first = False
|
||
|
# else:
|
||
|
# self._write(", ")
|
||
|
# self._write(a.name)
|
||
|
# if a.asname:
|
||
|
# self._write(" as "+a.asname)
|
||
|
#
|
||
|
## def _ImportFrom(self, t):
|
||
|
## self._fill("from ")
|
||
|
## self._write(t.module)
|
||
|
## self._write(" import ")
|
||
|
## for i, a in enumerate(t.names):
|
||
|
## if i == 0:
|
||
|
## self._write(", ")
|
||
|
## self._write(a.name)
|
||
|
## if a.asname:
|
||
|
## self._write(" as "+a.asname)
|
||
|
## # XXX(jpe) what is level for?
|
||
|
##
|
||
|
#
|
||
|
# def _Break(self, t):
|
||
|
# self._fill("break")
|
||
|
#
|
||
|
# def _Continue(self, t):
|
||
|
# self._fill("continue")
|
||
|
#
|
||
|
# def _Delete(self, t):
|
||
|
# self._fill("del ")
|
||
|
# self._dispatch(t.targets)
|
||
|
#
|
||
|
# def _Assert(self, t):
|
||
|
# self._fill("assert ")
|
||
|
# self._dispatch(t.test)
|
||
|
# if t.msg:
|
||
|
# self._write(", ")
|
||
|
# self._dispatch(t.msg)
|
||
|
#
|
||
|
# def _Exec(self, t):
|
||
|
# self._fill("exec ")
|
||
|
# self._dispatch(t.body)
|
||
|
# if t.globals:
|
||
|
# self._write(" in ")
|
||
|
# self._dispatch(t.globals)
|
||
|
# if t.locals:
|
||
|
# self._write(", ")
|
||
|
# self._dispatch(t.locals)
|
||
|
#
|
||
|
# def _Print(self, t):
|
||
|
# self._fill("print ")
|
||
|
# do_comma = False
|
||
|
# if t.dest:
|
||
|
# self._write(">>")
|
||
|
# self._dispatch(t.dest)
|
||
|
# do_comma = True
|
||
|
# for e in t.values:
|
||
|
# if do_comma:self._write(", ")
|
||
|
# else:do_comma=True
|
||
|
# self._dispatch(e)
|
||
|
# if not t.nl:
|
||
|
# self._write(",")
|
||
|
#
|
||
|
# def _Global(self, t):
|
||
|
# self._fill("global")
|
||
|
# for i, n in enumerate(t.names):
|
||
|
# if i != 0:
|
||
|
# self._write(",")
|
||
|
# self._write(" " + n)
|
||
|
#
|
||
|
# def _Yield(self, t):
|
||
|
# self._fill("yield")
|
||
|
# if t.value:
|
||
|
# self._write(" (")
|
||
|
# self._dispatch(t.value)
|
||
|
# self._write(")")
|
||
|
#
|
||
|
# def _Raise(self, t):
|
||
|
# self._fill('raise ')
|
||
|
# if t.type:
|
||
|
# self._dispatch(t.type)
|
||
|
# if t.inst:
|
||
|
# self._write(", ")
|
||
|
# self._dispatch(t.inst)
|
||
|
# if t.tback:
|
||
|
# self._write(", ")
|
||
|
# self._dispatch(t.tback)
|
||
|
#
|
||
|
#
|
||
|
# def _TryFinally(self, t):
|
||
|
# self._fill("try")
|
||
|
# self._enter()
|
||
|
# self._dispatch(t.body)
|
||
|
# self._leave()
|
||
|
#
|
||
|
# self._fill("finally")
|
||
|
# self._enter()
|
||
|
# self._dispatch(t.finalbody)
|
||
|
# self._leave()
|
||
|
#
|
||
|
# def _excepthandler(self, t):
|
||
|
# self._fill("except ")
|
||
|
# if t.type:
|
||
|
# self._dispatch(t.type)
|
||
|
# if t.name:
|
||
|
# self._write(", ")
|
||
|
# self._dispatch(t.name)
|
||
|
# self._enter()
|
||
|
# self._dispatch(t.body)
|
||
|
# self._leave()
|
||
|
#
|
||
|
# def _ClassDef(self, t):
|
||
|
# self._write("\n")
|
||
|
# self._fill("class "+t.name)
|
||
|
# if t.bases:
|
||
|
# self._write("(")
|
||
|
# for a in t.bases:
|
||
|
# self._dispatch(a)
|
||
|
# self._write(", ")
|
||
|
# self._write(")")
|
||
|
# self._enter()
|
||
|
# self._dispatch(t.body)
|
||
|
# self._leave()
|
||
|
#
|
||
|
# def _FunctionDef(self, t):
|
||
|
# self._write("\n")
|
||
|
# for deco in t.decorators:
|
||
|
# self._fill("@")
|
||
|
# self._dispatch(deco)
|
||
|
# self._fill("def "+t.name + "(")
|
||
|
# self._dispatch(t.args)
|
||
|
# self._write(")")
|
||
|
# self._enter()
|
||
|
# self._dispatch(t.body)
|
||
|
# self._leave()
|
||
|
#
|
||
|
# def _For(self, t):
|
||
|
# self._fill("for ")
|
||
|
# self._dispatch(t.target)
|
||
|
# self._write(" in ")
|
||
|
# self._dispatch(t.iter)
|
||
|
# self._enter()
|
||
|
# self._dispatch(t.body)
|
||
|
# self._leave()
|
||
|
# if t.orelse:
|
||
|
# self._fill("else")
|
||
|
# self._enter()
|
||
|
# self._dispatch(t.orelse)
|
||
|
# self._leave
|
||
|
#
|
||
|
# def _While(self, t):
|
||
|
# self._fill("while ")
|
||
|
# self._dispatch(t.test)
|
||
|
# self._enter()
|
||
|
# self._dispatch(t.body)
|
||
|
# self._leave()
|
||
|
# if t.orelse:
|
||
|
# self._fill("else")
|
||
|
# self._enter()
|
||
|
# self._dispatch(t.orelse)
|
||
|
# self._leave
|
||
|
#
|
||
|
# # expr
|
||
|
# def _Str(self, tree):
|
||
|
# self._write(repr(tree.s))
|
||
|
##
|
||
|
# def _Repr(self, t):
|
||
|
# self._write("`")
|
||
|
# self._dispatch(t.value)
|
||
|
# self._write("`")
|
||
|
#
|
||
|
# def _Num(self, t):
|
||
|
# self._write(repr(t.n))
|
||
|
#
|
||
|
# def _ListComp(self, t):
|
||
|
# self._write("[")
|
||
|
# self._dispatch(t.elt)
|
||
|
# for gen in t.generators:
|
||
|
# self._dispatch(gen)
|
||
|
# self._write("]")
|
||
|
#
|
||
|
# def _GeneratorExp(self, t):
|
||
|
# self._write("(")
|
||
|
# self._dispatch(t.elt)
|
||
|
# for gen in t.generators:
|
||
|
# self._dispatch(gen)
|
||
|
# self._write(")")
|
||
|
#
|
||
|
# def _comprehension(self, t):
|
||
|
# self._write(" for ")
|
||
|
# self._dispatch(t.target)
|
||
|
# self._write(" in ")
|
||
|
# self._dispatch(t.iter)
|
||
|
# for if_clause in t.ifs:
|
||
|
# self._write(" if ")
|
||
|
# self._dispatch(if_clause)
|
||
|
#
|
||
|
# def _IfExp(self, t):
|
||
|
# self._dispatch(t.body)
|
||
|
# self._write(" if ")
|
||
|
# self._dispatch(t.test)
|
||
|
# if t.orelse:
|
||
|
# self._write(" else ")
|
||
|
# self._dispatch(t.orelse)
|
||
|
#
|
||
|
# unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"}
|
||
|
# def _UnaryOp(self, t):
|
||
|
# self._write(self.unop[t.op.__class__.__name__])
|
||
|
# self._write("(")
|
||
|
# self._dispatch(t.operand)
|
||
|
# self._write(")")
|
||
|
#
|
||
|
# binop = { "Add":"+", "Sub":"-", "Mult":"*", "Div":"/", "Mod":"%",
|
||
|
# "LShift":">>", "RShift":"<<", "BitOr":"|", "BitXor":"^", "BitAnd":"&",
|
||
|
# "FloorDiv":"//", "Pow": "**"}
|
||
|
# def _BinOp(self, t):
|
||
|
# self._write("(")
|
||
|
# self._dispatch(t.left)
|
||
|
# self._write(")" + self.binop[t.op.__class__.__name__] + "(")
|
||
|
# self._dispatch(t.right)
|
||
|
# self._write(")")
|
||
|
#
|
||
|
# boolops = {_ast.And: 'and', _ast.Or: 'or'}
|
||
|
# def _BoolOp(self, t):
|
||
|
# self._write("(")
|
||
|
# self._dispatch(t.values[0])
|
||
|
# for v in t.values[1:]:
|
||
|
# self._write(" %s " % self.boolops[t.op.__class__])
|
||
|
# self._dispatch(v)
|
||
|
# self._write(")")
|
||
|
#
|
||
|
# def _Attribute(self,t):
|
||
|
# self._dispatch(t.value)
|
||
|
# self._write(".")
|
||
|
# self._write(t.attr)
|
||
|
#
|
||
|
## def _Call(self, t):
|
||
|
## self._dispatch(t.func)
|
||
|
## self._write("(")
|
||
|
## comma = False
|
||
|
## for e in t.args:
|
||
|
## if comma: self._write(", ")
|
||
|
## else: comma = True
|
||
|
## self._dispatch(e)
|
||
|
## for e in t.keywords:
|
||
|
## if comma: self._write(", ")
|
||
|
## else: comma = True
|
||
|
## self._dispatch(e)
|
||
|
## if t.starargs:
|
||
|
## if comma: self._write(", ")
|
||
|
## else: comma = True
|
||
|
## self._write("*")
|
||
|
## self._dispatch(t.starargs)
|
||
|
## if t.kwargs:
|
||
|
## if comma: self._write(", ")
|
||
|
## else: comma = True
|
||
|
## self._write("**")
|
||
|
## self._dispatch(t.kwargs)
|
||
|
## self._write(")")
|
||
|
#
|
||
|
# # slice
|
||
|
# def _Index(self, t):
|
||
|
# self._dispatch(t.value)
|
||
|
#
|
||
|
# def _ExtSlice(self, t):
|
||
|
# for i, d in enumerate(t.dims):
|
||
|
# if i != 0:
|
||
|
# self._write(': ')
|
||
|
# self._dispatch(d)
|
||
|
#
|
||
|
# # others
|
||
|
# def _arguments(self, t):
|
||
|
# first = True
|
||
|
# nonDef = len(t.args)-len(t.defaults)
|
||
|
# for a in t.args[0:nonDef]:
|
||
|
# if first:first = False
|
||
|
# else: self._write(", ")
|
||
|
# self._dispatch(a)
|
||
|
# for a,d in zip(t.args[nonDef:], t.defaults):
|
||
|
# if first:first = False
|
||
|
# else: self._write(", ")
|
||
|
# self._dispatch(a),
|
||
|
# self._write("=")
|
||
|
# self._dispatch(d)
|
||
|
# if t.vararg:
|
||
|
# if first:first = False
|
||
|
# else: self._write(", ")
|
||
|
# self._write("*"+t.vararg)
|
||
|
# if t.kwarg:
|
||
|
# if first:first = False
|
||
|
# else: self._write(", ")
|
||
|
# self._write("**"+t.kwarg)
|
||
|
#
|
||
|
## def _keyword(self, t):
|
||
|
## self._write(t.arg)
|
||
|
## self._write("=")
|
||
|
## self._dispatch(t.value)
|
||
|
#
|
||
|
# def _Lambda(self, t):
|
||
|
# self._write("lambda ")
|
||
|
# self._dispatch(t.args)
|
||
|
# self._write(": ")
|
||
|
# self._dispatch(t.body)
|