diff options
Diffstat (limited to 'Demo/parser/unparse.py')
-rw-r--r-- | Demo/parser/unparse.py | 316 |
1 files changed, 158 insertions, 158 deletions
diff --git a/Demo/parser/unparse.py b/Demo/parser/unparse.py index 2455885..53b57b3 100644 --- a/Demo/parser/unparse.py +++ b/Demo/parser/unparse.py @@ -1,158 +1,158 @@ -"Usage: unparse.py <path to source file>" -import sys - -class Unparser: - """Methods in this class recursively traverse an AST and - output source code for the abstract syntax; original formatting - is disregarged. """ - - def __init__(self, tree, file = sys.stdout): - """Unparser(tree, file=sys.stdout) -> None. - Print the source for tree to file.""" - self.f = file - self._indent = 0 - self.dispatch(tree) - self.f.flush() - - def fill(self, text = ""): - "Indent a piece of text, according to the current indentation level" - self.f.write("\n"+" "*self._indent + 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__) - meth(tree) - - - ############### Unparsing methods ###################### - # There should be one method per concrete grammar type # - # Constructors should be grouped by sum type. Ideally, # - # this would follow the order in the grammar, but # - # currently doesn't. # - ######################################################## - - def _Module(self, tree): - for stmt in tree.body: - self.dispatch(stmt) - - # 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 _Assign(self, t): - self.fill() - for target in t.targets: - self.dispatch(target) - self.write(" = ") - self.dispatch(t.value) - - 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") - self.fill("def "+t.name + "(") - self.dispatch(t.args) - self.enter() - self.dispatch(t.body) - self.leave() - - def _If(self, t): - self.fill("if ") - self.dispatch(t.test) - self.enter() - # XXX elif? - 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 _Name(self, t): - self.write(t.id) - - def _List(self, t): - self.write("[") - for e in t.elts: - self.dispatch(e) - self.write(", ") - self.write("]") - - 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(")") - - # others - def _arguments(self, t): - first = True - # XXX t.defaults - for a in t.args: - if first:first = False - else: self.write(", ") - self.dispatch(a) - 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("**"+self.kwarg) - self.write(")") - -def roundtrip(filename): - source = open(filename).read() - tree = compile(source, filename, "exec", 0x400) - Unparser(tree) - -if __name__=='__main__': - roundtrip(sys.argv[1]) +"Usage: unparse.py <path to source file>"
+import sys
+
+class Unparser:
+ """Methods in this class recursively traverse an AST and
+ output source code for the abstract syntax; original formatting
+ is disregarged. """
+
+ def __init__(self, tree, file = sys.stdout):
+ """Unparser(tree, file=sys.stdout) -> None.
+ Print the source for tree to file."""
+ self.f = file
+ self._indent = 0
+ self.dispatch(tree)
+ self.f.flush()
+
+ def fill(self, text = ""):
+ "Indent a piece of text, according to the current indentation level"
+ self.f.write("\n"+" "*self._indent + 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__)
+ meth(tree)
+
+
+ ############### Unparsing methods ######################
+ # There should be one method per concrete grammar type #
+ # Constructors should be grouped by sum type. Ideally, #
+ # this would follow the order in the grammar, but #
+ # currently doesn't. #
+ ########################################################
+
+ def _Module(self, tree):
+ for stmt in tree.body:
+ self.dispatch(stmt)
+
+ # 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 _Assign(self, t):
+ self.fill()
+ for target in t.targets:
+ self.dispatch(target)
+ self.write(" = ")
+ self.dispatch(t.value)
+
+ 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")
+ self.fill("def "+t.name + "(")
+ self.dispatch(t.args)
+ self.enter()
+ self.dispatch(t.body)
+ self.leave()
+
+ def _If(self, t):
+ self.fill("if ")
+ self.dispatch(t.test)
+ self.enter()
+ # XXX elif?
+ 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 _Name(self, t):
+ self.write(t.id)
+
+ def _List(self, t):
+ self.write("[")
+ for e in t.elts:
+ self.dispatch(e)
+ self.write(", ")
+ self.write("]")
+
+ 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(")")
+
+ # others
+ def _arguments(self, t):
+ first = True
+ # XXX t.defaults
+ for a in t.args:
+ if first:first = False
+ else: self.write(", ")
+ self.dispatch(a)
+ 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("**"+self.kwarg)
+ self.write(")")
+
+def roundtrip(filename):
+ source = open(filename).read()
+ tree = compile(source, filename, "exec", 0x400)
+ Unparser(tree)
+
+if __name__=='__main__':
+ roundtrip(sys.argv[1])
|