diff options
Diffstat (limited to 'Demo')
-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 53b57b3..72691b5 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]) |