From c9ab4ddda6a54932d69560d400357c3dd0e523d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E5=A4=B4=E8=89=BA=E6=9C=AF=E5=AE=B6=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=AE=A4?= <5647384+labsite@user.noreply.gitee.com> Date: Wed, 25 Aug 2021 04:26:16 +0000 Subject: [PATCH 01/12] =?UTF-8?q?add=20=E6=9C=A8=E5=85=B0/=E8=BD=AC.py.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\346\234\250\345\205\260/\350\275\254.py" | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 "\346\234\250\345\205\260/\350\275\254.py" diff --git "a/\346\234\250\345\205\260/\350\275\254.py" "b/\346\234\250\345\205\260/\350\275\254.py" new file mode 100644 index 0000000..e69de29 -- Gitee From ef02045cdf39e43f6c628b2d1b2feb2f5b443e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E5=A4=B4=E8=89=BA=E6=9C=AF=E5=AE=B6=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=AE=A4?= <5647384+labsite@user.noreply.gitee.com> Date: Wed, 25 Aug 2021 13:44:06 +0000 Subject: [PATCH 02/12] =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\346\234\250\345\205\260/\350\275\254.py" | 912 +++++++++++++++++++++ 1 file changed, 912 insertions(+) diff --git "a/\346\234\250\345\205\260/\350\275\254.py" "b/\346\234\250\345\205\260/\350\275\254.py" index e69de29..07acc9d 100644 --- "a/\346\234\250\345\205\260/\350\275\254.py" +++ "b/\346\234\250\345\205\260/\350\275\254.py" @@ -0,0 +1,912 @@ +"Usage: unparse.py " +from __future__ import print_function, unicode_literals +import six +from six.moves import cStringIO +import sys +import ast +import os +import tokenize +from six import StringIO + +# Large float and imaginary literals get turned into infinities in the AST. +# We unparse those infinities to INFSTR. +INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1) + +def interleave(inter, f, seq): + """Call f on each item in seq, calling inter() in between. + """ + seq = iter(seq) + try: + f(next(seq)) + except StopIteration: + pass + else: + for x in seq: + inter() + f(x) + +class Unparser: + """Methods in this class recursively traverse an AST and + output source code for the abstract syntax; original formatting + is disregarded. """ + + def __init__(self, tree, file = sys.stdout): + """Unparser(tree, file=sys.stdout) -> None. + Print the source for tree to file.""" + self.f = file + self.future_imports = [] + self._indent = 0 + self.dispatch(tree) + print("", file=self.f) + 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(six.text_type(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) + + def _Interactive(self, tree): + for stmt in tree.body: + self.dispatch(stmt) + + def _Expression(self, tree): + self.dispatch(tree.body) + + # stmt + def _Expr(self, tree): + self.fill() + self.dispatch(tree.value) + + def _NamedExpr(self, tree): + self.write("(") + self.dispatch(tree.target) + self.write(" := ") + self.dispatch(tree.value) + self.write(")") + + def _Import(self, t): + self.fill("import ") + interleave(lambda: self.write(", "), self.dispatch, t.names) + + def _ImportFrom(self, t): + # A from __future__ import may affect unparsing, so record it. + if t.module and t.module == '__future__': + self.future_imports.extend(n.name for n in t.names) + + self.fill("from ") + self.write("." * t.level) + if t.module: + self.write(t.module) + self.write(" import ") + interleave(lambda: self.write(", "), self.dispatch, t.names) + + def _Assign(self, t): + self.fill() + for target in t.targets: + self.dispatch(target) + self.write(" = ") + self.dispatch(t.value) + + def _AugAssign(self, t): + self.fill() + self.dispatch(t.target) + self.write(" "+self.binop[t.op.__class__.__name__]+"= ") + self.dispatch(t.value) + + def _AnnAssign(self, t): + self.fill() + if not t.simple and isinstance(t.target, ast.Name): + self.write('(') + self.dispatch(t.target) + if not t.simple and isinstance(t.target, ast.Name): + self.write(')') + self.write(": ") + self.dispatch(t.annotation) + if t.value: + self.write(" = ") + self.dispatch(t.value) + + def _Return(self, t): + self.fill("return") + if t.value: + self.write(" ") + self.dispatch(t.value) + + def _Pass(self, t): + self.fill("pass") + + def _Break(self, t): + self.fill("break") + + def _Continue(self, t): + self.fill("continue") + + def _Delete(self, t): + self.fill("del ") + interleave(lambda: self.write(", "), 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 ") + interleave(lambda: self.write(", "), self.write, t.names) + + def _Nonlocal(self, t): + self.fill("nonlocal ") + interleave(lambda: self.write(", "), self.write, t.names) + + def _Await(self, t): + self.write("(") + self.write("await") + if t.value: + self.write(" ") + self.dispatch(t.value) + self.write(")") + + def _Yield(self, t): + self.write("(") + self.write("yield") + if t.value: + self.write(" ") + self.dispatch(t.value) + self.write(")") + + def _YieldFrom(self, t): + self.write("(") + self.write("yield from") + if t.value: + self.write(" ") + self.dispatch(t.value) + self.write(")") + + def _Raise(self, t): + self.fill("raise") + if six.PY3: + if not t.exc: + assert not t.cause + return + self.write(" ") + self.dispatch(t.exc) + if t.cause: + self.write(" from ") + self.dispatch(t.cause) + else: + self.write(" ") + 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 _Try(self, t): + self.fill("try") + self.enter() + self.dispatch(t.body) + self.leave() + for ex in t.handlers: + self.dispatch(ex) + if t.orelse: + self.fill("else") + self.enter() + self.dispatch(t.orelse) + self.leave() + if t.finalbody: + self.fill("finally") + self.enter() + self.dispatch(t.finalbody) + self.leave() + + def _TryExcept(self, t): + self.fill("try") + self.enter() + self.dispatch(t.body) + self.leave() + + for ex in t.handlers: + self.dispatch(ex) + if t.orelse: + self.fill("else") + self.enter() + self.dispatch(t.orelse) + self.leave() + + def _TryFinally(self, t): + if len(t.body) == 1 and isinstance(t.body[0], ast.TryExcept): + # try-except-finally + self.dispatch(t.body) + else: + 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.write(" ") + self.dispatch(t.type) + if t.name: + self.write(" as ") + if six.PY3: + self.write(t.name) + else: + self.dispatch(t.name) + self.enter() + self.dispatch(t.body) + self.leave() + + def _ClassDef(self, t): + self.write("\n") + for deco in t.decorator_list: + self.fill("@") + self.dispatch(deco) + self.fill("class "+t.name) + if six.PY3: + self.write("(") + comma = False + for e in t.bases: + 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 sys.version_info[:2] < (3, 5): + 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(")") + elif 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.__FunctionDef_helper(t, "def") + + def _AsyncFunctionDef(self, t): + self.__FunctionDef_helper(t, "async def") + + def __FunctionDef_helper(self, t, fill_suffix): + self.write("\n") + for deco in t.decorator_list: + self.fill("@") + self.dispatch(deco) + def_str = fill_suffix+" "+t.name + "(" + self.fill(def_str) + self.dispatch(t.args) + self.write(")") + if getattr(t, "returns", False): + self.write(" -> ") + self.dispatch(t.returns) + self.enter() + self.dispatch(t.body) + self.leave() + + def _For(self, t): + self.__For_helper("for ", t) + + def _AsyncFor(self, t): + self.__For_helper("async for ", t) + + def __For_helper(self, fill, t): + self.fill(fill) + 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 _If(self, t): + self.fill("if ") + self.dispatch(t.test) + self.enter() + self.dispatch(t.body) + self.leave() + # collapse nested ifs into equivalent elifs. + while (t.orelse and len(t.orelse) == 1 and + isinstance(t.orelse[0], ast.If)): + t = t.orelse[0] + self.fill("elif ") + self.dispatch(t.test) + self.enter() + self.dispatch(t.body) + self.leave() + # final else + 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() + + def _generic_With(self, t, async_=False): + self.fill("async with " if async_ else "with ") + if hasattr(t, 'items'): + interleave(lambda: self.write(", "), self.dispatch, t.items) + else: + self.dispatch(t.context_expr) + if t.optional_vars: + self.write(" as ") + self.dispatch(t.optional_vars) + self.enter() + self.dispatch(t.body) + self.leave() + + def _With(self, t): + self._generic_With(t) + + def _AsyncWith(self, t): + self._generic_With(t, async_=True) + + # expr + def _Bytes(self, t): + self.write(repr(t.s)) + + def _Str(self, tree): + if six.PY3: + self.write(repr(tree.s)) + else: + # if from __future__ import unicode_literals is in effect, + # then we want to output string literals using a 'b' prefix + # and unicode literals with no prefix. + if "unicode_literals" not in self.future_imports: + self.write(repr(tree.s)) + elif isinstance(tree.s, str): + self.write("b" + repr(tree.s)) + elif isinstance(tree.s, unicode): + self.write(repr(tree.s).lstrip("u")) + else: + assert False, "shouldn't get here" + + def _JoinedStr(self, t): + # JoinedStr(expr* values) + self.write("f") + string = StringIO() + self._fstring_JoinedStr(t, string.write) + # Deviation from `unparse.py`: Try to find an unused quote. + # This change is made to handle _very_ complex f-strings. + v = string.getvalue() + if '\n' in v or '\r' in v: + quote_types = ["'''", '"""'] + else: + quote_types = ["'", '"', '"""', "'''"] + for quote_type in quote_types: + if quote_type not in v: + v = "{quote_type}{v}{quote_type}".format(quote_type=quote_type, v=v) + break + else: + v = repr(v) + self.write(v) + + def _FormattedValue(self, t): + # FormattedValue(expr value, int? conversion, expr? format_spec) + self.write("f") + string = StringIO() + self._fstring_JoinedStr(t, string.write) + self.write(repr(string.getvalue())) + + def _fstring_JoinedStr(self, t, write): + for value in t.values: + meth = getattr(self, "_fstring_" + type(value).__name__) + meth(value, write) + + def _fstring_Str(self, t, write): + value = t.s.replace("{", "{{").replace("}", "}}") + write(value) + + def _fstring_Constant(self, t, write): + assert isinstance(t.value, str) + value = t.value.replace("{", "{{").replace("}", "}}") + write(value) + + def _fstring_FormattedValue(self, t, write): + write("{") + expr = StringIO() + Unparser(t.value, expr) + expr = expr.getvalue().rstrip("\n") + if expr.startswith("{"): + write(" ") # Separate pair of opening brackets as "{ {" + write(expr) + if t.conversion != -1: + conversion = chr(t.conversion) + assert conversion in "sra" + write("!{conversion}".format(conversion=conversion)) + if t.format_spec: + write(":") + meth = getattr(self, "_fstring_" + type(t.format_spec).__name__) + meth(t.format_spec, write) + write("}") + + def _Name(self, t): + self.write(t.id) + + def _NameConstant(self, t): + self.write(repr(t.value)) + + def _Repr(self, t): + self.write("`") + self.dispatch(t.value) + self.write("`") + + def _write_constant(self, value): + if isinstance(value, (float, complex)): + # Substitute overflowing decimal literal for AST infinities. + self.write(repr(value).replace("inf", INFSTR)) + else: + self.write(repr(value)) + + def _Constant(self, t): + value = t.value + if isinstance(value, tuple): + self.write("(") + if len(value) == 1: + self._write_constant(value[0]) + self.write(",") + else: + interleave(lambda: self.write(", "), self._write_constant, value) + self.write(")") + elif value is Ellipsis: # instead of `...` for Py2 compatibility + self.write("...") + else: + if t.kind == "u": + self.write("u") + self._write_constant(t.value) + + def _Num(self, t): + repr_n = repr(t.n) + if six.PY3: + self.write(repr_n.replace("inf", INFSTR)) + else: + # Parenthesize negative numbers, to avoid turning (-1)**2 into -1**2. + if repr_n.startswith("-"): + self.write("(") + if "inf" in repr_n and repr_n.endswith("*j"): + repr_n = repr_n.replace("*j", "j") + # Substitute overflowing decimal literal for AST infinities. + self.write(repr_n.replace("inf", INFSTR)) + if repr_n.startswith("-"): + self.write(")") + + def _List(self, t): + self.write("[") + interleave(lambda: self.write(", "), self.dispatch, t.elts) + self.write("]") + + 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 _SetComp(self, t): + self.write("{") + self.dispatch(t.elt) + for gen in t.generators: + self.dispatch(gen) + self.write("}") + + def _DictComp(self, t): + self.write("{") + self.dispatch(t.key) + self.write(": ") + self.dispatch(t.value) + for gen in t.generators: + self.dispatch(gen) + self.write("}") + + def _comprehension(self, t): + if getattr(t, 'is_async', False): + self.write(" async for ") + else: + 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.write("(") + self.dispatch(t.body) + self.write(" if ") + self.dispatch(t.test) + self.write(" else ") + self.dispatch(t.orelse) + self.write(")") + + def _Set(self, t): + assert(t.elts) # should be at least one element + self.write("{") + interleave(lambda: self.write(", "), self.dispatch, t.elts) + self.write("}") + + def _Dict(self, t): + self.write("{") + def write_key_value_pair(k, v): + self.dispatch(k) + self.write(": ") + self.dispatch(v) + + def write_item(item): + k, v = item + if k is None: + # for dictionary unpacking operator in dicts {**{'y': 2}} + # see PEP 448 for details + self.write("**") + self.dispatch(v) + else: + write_key_value_pair(k, v) + interleave(lambda: self.write(", "), write_item, zip(t.keys, t.values)) + self.write("}") + + def _Tuple(self, t): + self.write("(") + if len(t.elts) == 1: + elt = t.elts[0] + self.dispatch(elt) + self.write(",") + else: + interleave(lambda: self.write(", "), self.dispatch, t.elts) + self.write(")") + + unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"} + def _UnaryOp(self, t): + self.write("(") + self.write(self.unop[t.op.__class__.__name__]) + self.write(" ") + if six.PY2 and isinstance(t.op, ast.USub) and isinstance(t.operand, ast.Num): + # If we're applying unary minus to a number, parenthesize the number. + # This is necessary: -2147483648 is different from -(2147483648) on + # a 32-bit machine (the first is an int, the second a long), and + # -7j is different from -(7j). (The first has real part 0.0, the second + # has real part -0.0.) + self.write("(") + self.dispatch(t.operand) + self.write(")") + else: + self.dispatch(t.operand) + self.write(")") + + binop = { "Add":"+", "Sub":"-", "Mult":"*", "MatMult":"@", "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(")") + + cmpops = {"Eq":"==", "NotEq":"!=", "Lt":"<", "LtE":"<=", "Gt":">", "GtE":">=", + "Is":"is", "IsNot":"is not", "In":"in", "NotIn":"not in"} + def _Compare(self, t): + self.write("(") + self.dispatch(t.left) + for o, e in zip(t.ops, t.comparators): + self.write(" " + self.cmpops[o.__class__.__name__] + " ") + self.dispatch(e) + self.write(")") + + boolops = {ast.And: 'and', ast.Or: 'or'} + def _BoolOp(self, t): + self.write("(") + s = " %s " % self.boolops[t.op.__class__] + interleave(lambda: self.write(s), self.dispatch, t.values) + self.write(")") + + def _Attribute(self,t): + self.dispatch(t.value) + # Special case: 3.__abs__() is a syntax error, so if t.value + # is an integer literal then we need to either parenthesize + # it or add an extra space to get 3 .__abs__(). + if isinstance(t.value, getattr(ast, 'Constant', getattr(ast, 'Num', None))) and isinstance(t.value.n, int): + self.write(" ") + 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 sys.version_info[:2] < (3, 5): + 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(")") + + def _Subscript(self, t): + self.dispatch(t.value) + self.write("[") + self.dispatch(t.slice) + self.write("]") + + def _Starred(self, t): + self.write("*") + self.dispatch(t.value) + + # slice + def _Ellipsis(self, t): + self.write("...") + + def _Index(self, t): + self.dispatch(t.value) + + def _Slice(self, t): + 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) + + def _ExtSlice(self, t): + interleave(lambda: self.write(', '), self.dispatch, t.dims) + + # argument + def _arg(self, t): + self.write(t.arg) + if t.annotation: + self.write(": ") + self.dispatch(t.annotation) + + # others + def _arguments(self, t): + first = True + # normal arguments + all_args = getattr(t, 'posonlyargs', []) + t.args + defaults = [None] * (len(all_args) - len(t.defaults)) + t.defaults + for index, elements in enumerate(zip(all_args, defaults), 1): + a, d = elements + if first:first = False + else: self.write(", ") + self.dispatch(a) + if d: + self.write("=") + self.dispatch(d) + if index == len(getattr(t, 'posonlyargs', ())): + self.write(", /") + + # varargs, or bare '*' if no varargs but keyword-only arguments present + if t.vararg or getattr(t, "kwonlyargs", False): + if first:first = False + else: self.write(", ") + self.write("*") + if t.vararg: + if hasattr(t.vararg, 'arg'): + self.write(t.vararg.arg) + if t.vararg.annotation: + self.write(": ") + self.dispatch(t.vararg.annotation) + else: + self.write(t.vararg) + if getattr(t, 'varargannotation', None): + self.write(": ") + self.dispatch(t.varargannotation) + + # keyword-only arguments + if getattr(t, "kwonlyargs", False): + for a, d in zip(t.kwonlyargs, t.kw_defaults): + if first:first = False + else: self.write(", ") + self.dispatch(a), + if d: + self.write("=") + self.dispatch(d) + + # kwargs + if t.kwarg: + if first:first = False + else: self.write(", ") + if hasattr(t.kwarg, 'arg'): + self.write("**"+t.kwarg.arg) + if t.kwarg.annotation: + self.write(": ") + self.dispatch(t.kwarg.annotation) + else: + self.write("**"+t.kwarg) + if getattr(t, 'kwargannotation', None): + self.write(": ") + self.dispatch(t.kwargannotation) + + def _keyword(self, t): + if t.arg is None: + # starting from Python 3.5 this denotes a kwargs part of the invocation + self.write("**") + else: + self.write(t.arg) + self.write("=") + self.dispatch(t.value) + + def _Lambda(self, t): + self.write("(") + self.write("lambda ") + self.dispatch(t.args) + self.write(": ") + self.dispatch(t.body) + self.write(")") + + def _alias(self, t): + self.write(t.name) + if t.asname: + self.write(" as "+t.asname) + + def _withitem(self, t): + self.dispatch(t.context_expr) + if t.optional_vars: + self.write(" as ") + self.dispatch(t.optional_vars) + +def roundtrip(filename, output=sys.stdout): + if six.PY3: + with open(filename, "rb") as pyfile: + encoding = tokenize.detect_encoding(pyfile.readline)[0] + with open(filename, "r", encoding=encoding) as pyfile: + source = pyfile.read() + else: + with open(filename, "r") as pyfile: + source = pyfile.read() + tree = compile(source, filename, "exec", ast.PyCF_ONLY_AST, dont_inherit=True) + Unparser(tree, output) + + + +def testdir(a): + try: + names = [n for n in os.listdir(a) if n.endswith('.py')] + except OSError: + print("Directory not readable: %s" % a, file=sys.stderr) + else: + for n in names: + fullname = os.path.join(a, n) + if os.path.isfile(fullname): + output = StringIO() + print('Testing %s' % fullname) + try: + roundtrip(fullname, output) + except Exception as e: + print(' Failed to compile, exception is %s' % repr(e)) + elif os.path.isdir(fullname): + testdir(fullname) + +def main(args): + if args[0] == '--testdir': + for a in args[1:]: + testdir(a) + else: + for a in args: + roundtrip(a) + +def 转(tree): + v = cStringIO() + Unparser(tree, file=v) + return v.getvalue() + +if __name__=='__main__': + main(sys.argv[1:]) \ No newline at end of file -- Gitee From 683090225c94d683b905b261a742f1596956a793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E5=A4=B4=E8=89=BA=E6=9C=AF=E5=AE=B6=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=AE=A4?= <5647384+labsite@user.noreply.gitee.com> Date: Wed, 25 Aug 2021 13:51:17 +0000 Subject: [PATCH 03/12] =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\346\234\250\345\205\260/\344\270\255.py" | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git "a/\346\234\250\345\205\260/\344\270\255.py" "b/\346\234\250\345\205\260/\344\270\255.py" index 6ef23db..828b372 100755 --- "a/\346\234\250\345\205\260/\344\270\255.py" +++ "b/\346\234\250\345\205\260/\344\270\255.py" @@ -27,11 +27,13 @@ def 中(argv=None): try: 选项, 参数 = getopt.getopt( argv[1:], - '兰版树', + '兰版树转', [ "语法树", "python变木兰", - '版本']) + '版本', + '转python', + ]) except getopt.GetoptError as e: try: sys.stderr.write(str(e) + '\n') @@ -43,6 +45,8 @@ def 中(argv=None): 版本 = False python变木兰 = False 语法树 = False + 转python = False + for 某项, 值 in 选项: if 某项 in ('-版', '--版本'): 版本 = True @@ -50,6 +54,9 @@ def 中(argv=None): python变木兰 = True elif 某项 in ("-树", "--语法树"): 语法树 = True + elif 某项 in ('–转', '--转python'): + 转python = True + if 版本: from 木兰 import __版本__ @@ -93,3 +100,7 @@ def 中(argv=None): del e except SyntaxError as 语法错误: sys.stderr.write(f"语法错误: {语法错误}\n") + + if 转python: + import 转 + 转.unparse(节点) \ No newline at end of file -- Gitee From 71348392f0c867684b3b99c448ef105f73122e1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E5=A4=B4=E8=89=BA=E6=9C=AF=E5=AE=B6=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=AE=A4?= <5647384+labsite@user.noreply.gitee.com> Date: Wed, 25 Aug 2021 13:52:00 +0000 Subject: [PATCH 04/12] =?UTF-8?q?=20=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\346\234\250\345\205\260/\344\270\255.py" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\346\234\250\345\205\260/\344\270\255.py" "b/\346\234\250\345\205\260/\344\270\255.py" index 828b372..7795410 100755 --- "a/\346\234\250\345\205\260/\344\270\255.py" +++ "b/\346\234\250\345\205\260/\344\270\255.py" @@ -103,4 +103,4 @@ def 中(argv=None): if 转python: import 转 - 转.unparse(节点) \ No newline at end of file + print(转.unparse(节点)) \ No newline at end of file -- Gitee From 1ae9a0b715ea66e6442b3b89f80a3858e2d82a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E5=A4=B4=E8=89=BA=E6=9C=AF=E5=AE=B6=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=AE=A4?= <5647384+labsite@user.noreply.gitee.com> Date: Wed, 25 Aug 2021 23:43:24 +0000 Subject: [PATCH 05/12] =?UTF-8?q?update=20=E6=9C=A8=E5=85=B0/=E4=B8=AD.py.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\346\234\250\345\205\260/\344\270\255.py" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/\346\234\250\345\205\260/\344\270\255.py" "b/\346\234\250\345\205\260/\344\270\255.py" index 7795410..6fe314f 100755 --- "a/\346\234\250\345\205\260/\344\270\255.py" +++ "b/\346\234\250\345\205\260/\344\270\255.py" @@ -9,6 +9,7 @@ from 木兰.环境 import 创建全局变量 from 木兰.交互 import 开始交互 from 木兰.功用.反馈信息 import 反馈信息 from 木兰.功用.调试辅助 import 语法树相关 +import 转 def 用途(程序): 介绍 = '''使用方法: %s 源码文件 @@ -102,5 +103,4 @@ def 中(argv=None): sys.stderr.write(f"语法错误: {语法错误}\n") if 转python: - import 转 - print(转.unparse(节点)) \ No newline at end of file + print(转.转(节点)) \ No newline at end of file -- Gitee From 2de28ea8c26b6b67a4bd5b7d1f76368461608948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E5=A4=B4=E8=89=BA=E6=9C=AF=E5=AE=B6=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=AE=A4?= <5647384+labsite@user.noreply.gitee.com> Date: Wed, 25 Aug 2021 23:45:28 +0000 Subject: [PATCH 06/12] =?UTF-8?q?update=20=E6=9C=A8=E5=85=B0/=E8=BD=AC.py.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\346\234\250\345\205\260/\350\275\254.py" | 46 +--------------------- 1 file changed, 1 insertion(+), 45 deletions(-) diff --git "a/\346\234\250\345\205\260/\350\275\254.py" "b/\346\234\250\345\205\260/\350\275\254.py" index 07acc9d..83f8dc8 100644 --- "a/\346\234\250\345\205\260/\350\275\254.py" +++ "b/\346\234\250\345\205\260/\350\275\254.py" @@ -1,4 +1,3 @@ -"Usage: unparse.py " from __future__ import print_function, unicode_literals import six from six.moves import cStringIO @@ -863,50 +862,7 @@ class Unparser: self.write(" as ") self.dispatch(t.optional_vars) -def roundtrip(filename, output=sys.stdout): - if six.PY3: - with open(filename, "rb") as pyfile: - encoding = tokenize.detect_encoding(pyfile.readline)[0] - with open(filename, "r", encoding=encoding) as pyfile: - source = pyfile.read() - else: - with open(filename, "r") as pyfile: - source = pyfile.read() - tree = compile(source, filename, "exec", ast.PyCF_ONLY_AST, dont_inherit=True) - Unparser(tree, output) - - - -def testdir(a): - try: - names = [n for n in os.listdir(a) if n.endswith('.py')] - except OSError: - print("Directory not readable: %s" % a, file=sys.stderr) - else: - for n in names: - fullname = os.path.join(a, n) - if os.path.isfile(fullname): - output = StringIO() - print('Testing %s' % fullname) - try: - roundtrip(fullname, output) - except Exception as e: - print(' Failed to compile, exception is %s' % repr(e)) - elif os.path.isdir(fullname): - testdir(fullname) - -def main(args): - if args[0] == '--testdir': - for a in args[1:]: - testdir(a) - else: - for a in args: - roundtrip(a) - def 转(tree): v = cStringIO() Unparser(tree, file=v) - return v.getvalue() - -if __name__=='__main__': - main(sys.argv[1:]) \ No newline at end of file + return v.getvalue() \ No newline at end of file -- Gitee From 82c98597b859228d63dce3bade37ce7393f9a4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E5=A4=B4=E8=89=BA=E6=9C=AF=E5=AE=B6=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=AE=A4?= <5647384+labsite@user.noreply.gitee.com> Date: Thu, 26 Aug 2021 00:18:29 +0000 Subject: [PATCH 07/12] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20?= =?UTF-8?q?=E6=9C=A8=E5=85=B0/=E8=BD=AC.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\346\234\250\345\205\260/\350\275\254.py" | 868 --------------------- 1 file changed, 868 deletions(-) delete mode 100644 "\346\234\250\345\205\260/\350\275\254.py" diff --git "a/\346\234\250\345\205\260/\350\275\254.py" "b/\346\234\250\345\205\260/\350\275\254.py" deleted file mode 100644 index 83f8dc8..0000000 --- "a/\346\234\250\345\205\260/\350\275\254.py" +++ /dev/null @@ -1,868 +0,0 @@ -from __future__ import print_function, unicode_literals -import six -from six.moves import cStringIO -import sys -import ast -import os -import tokenize -from six import StringIO - -# Large float and imaginary literals get turned into infinities in the AST. -# We unparse those infinities to INFSTR. -INFSTR = "1e" + repr(sys.float_info.max_10_exp + 1) - -def interleave(inter, f, seq): - """Call f on each item in seq, calling inter() in between. - """ - seq = iter(seq) - try: - f(next(seq)) - except StopIteration: - pass - else: - for x in seq: - inter() - f(x) - -class Unparser: - """Methods in this class recursively traverse an AST and - output source code for the abstract syntax; original formatting - is disregarded. """ - - def __init__(self, tree, file = sys.stdout): - """Unparser(tree, file=sys.stdout) -> None. - Print the source for tree to file.""" - self.f = file - self.future_imports = [] - self._indent = 0 - self.dispatch(tree) - print("", file=self.f) - 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(six.text_type(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) - - def _Interactive(self, tree): - for stmt in tree.body: - self.dispatch(stmt) - - def _Expression(self, tree): - self.dispatch(tree.body) - - # stmt - def _Expr(self, tree): - self.fill() - self.dispatch(tree.value) - - def _NamedExpr(self, tree): - self.write("(") - self.dispatch(tree.target) - self.write(" := ") - self.dispatch(tree.value) - self.write(")") - - def _Import(self, t): - self.fill("import ") - interleave(lambda: self.write(", "), self.dispatch, t.names) - - def _ImportFrom(self, t): - # A from __future__ import may affect unparsing, so record it. - if t.module and t.module == '__future__': - self.future_imports.extend(n.name for n in t.names) - - self.fill("from ") - self.write("." * t.level) - if t.module: - self.write(t.module) - self.write(" import ") - interleave(lambda: self.write(", "), self.dispatch, t.names) - - def _Assign(self, t): - self.fill() - for target in t.targets: - self.dispatch(target) - self.write(" = ") - self.dispatch(t.value) - - def _AugAssign(self, t): - self.fill() - self.dispatch(t.target) - self.write(" "+self.binop[t.op.__class__.__name__]+"= ") - self.dispatch(t.value) - - def _AnnAssign(self, t): - self.fill() - if not t.simple and isinstance(t.target, ast.Name): - self.write('(') - self.dispatch(t.target) - if not t.simple and isinstance(t.target, ast.Name): - self.write(')') - self.write(": ") - self.dispatch(t.annotation) - if t.value: - self.write(" = ") - self.dispatch(t.value) - - def _Return(self, t): - self.fill("return") - if t.value: - self.write(" ") - self.dispatch(t.value) - - def _Pass(self, t): - self.fill("pass") - - def _Break(self, t): - self.fill("break") - - def _Continue(self, t): - self.fill("continue") - - def _Delete(self, t): - self.fill("del ") - interleave(lambda: self.write(", "), 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 ") - interleave(lambda: self.write(", "), self.write, t.names) - - def _Nonlocal(self, t): - self.fill("nonlocal ") - interleave(lambda: self.write(", "), self.write, t.names) - - def _Await(self, t): - self.write("(") - self.write("await") - if t.value: - self.write(" ") - self.dispatch(t.value) - self.write(")") - - def _Yield(self, t): - self.write("(") - self.write("yield") - if t.value: - self.write(" ") - self.dispatch(t.value) - self.write(")") - - def _YieldFrom(self, t): - self.write("(") - self.write("yield from") - if t.value: - self.write(" ") - self.dispatch(t.value) - self.write(")") - - def _Raise(self, t): - self.fill("raise") - if six.PY3: - if not t.exc: - assert not t.cause - return - self.write(" ") - self.dispatch(t.exc) - if t.cause: - self.write(" from ") - self.dispatch(t.cause) - else: - self.write(" ") - 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 _Try(self, t): - self.fill("try") - self.enter() - self.dispatch(t.body) - self.leave() - for ex in t.handlers: - self.dispatch(ex) - if t.orelse: - self.fill("else") - self.enter() - self.dispatch(t.orelse) - self.leave() - if t.finalbody: - self.fill("finally") - self.enter() - self.dispatch(t.finalbody) - self.leave() - - def _TryExcept(self, t): - self.fill("try") - self.enter() - self.dispatch(t.body) - self.leave() - - for ex in t.handlers: - self.dispatch(ex) - if t.orelse: - self.fill("else") - self.enter() - self.dispatch(t.orelse) - self.leave() - - def _TryFinally(self, t): - if len(t.body) == 1 and isinstance(t.body[0], ast.TryExcept): - # try-except-finally - self.dispatch(t.body) - else: - 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.write(" ") - self.dispatch(t.type) - if t.name: - self.write(" as ") - if six.PY3: - self.write(t.name) - else: - self.dispatch(t.name) - self.enter() - self.dispatch(t.body) - self.leave() - - def _ClassDef(self, t): - self.write("\n") - for deco in t.decorator_list: - self.fill("@") - self.dispatch(deco) - self.fill("class "+t.name) - if six.PY3: - self.write("(") - comma = False - for e in t.bases: - 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 sys.version_info[:2] < (3, 5): - 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(")") - elif 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.__FunctionDef_helper(t, "def") - - def _AsyncFunctionDef(self, t): - self.__FunctionDef_helper(t, "async def") - - def __FunctionDef_helper(self, t, fill_suffix): - self.write("\n") - for deco in t.decorator_list: - self.fill("@") - self.dispatch(deco) - def_str = fill_suffix+" "+t.name + "(" - self.fill(def_str) - self.dispatch(t.args) - self.write(")") - if getattr(t, "returns", False): - self.write(" -> ") - self.dispatch(t.returns) - self.enter() - self.dispatch(t.body) - self.leave() - - def _For(self, t): - self.__For_helper("for ", t) - - def _AsyncFor(self, t): - self.__For_helper("async for ", t) - - def __For_helper(self, fill, t): - self.fill(fill) - 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 _If(self, t): - self.fill("if ") - self.dispatch(t.test) - self.enter() - self.dispatch(t.body) - self.leave() - # collapse nested ifs into equivalent elifs. - while (t.orelse and len(t.orelse) == 1 and - isinstance(t.orelse[0], ast.If)): - t = t.orelse[0] - self.fill("elif ") - self.dispatch(t.test) - self.enter() - self.dispatch(t.body) - self.leave() - # final else - 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() - - def _generic_With(self, t, async_=False): - self.fill("async with " if async_ else "with ") - if hasattr(t, 'items'): - interleave(lambda: self.write(", "), self.dispatch, t.items) - else: - self.dispatch(t.context_expr) - if t.optional_vars: - self.write(" as ") - self.dispatch(t.optional_vars) - self.enter() - self.dispatch(t.body) - self.leave() - - def _With(self, t): - self._generic_With(t) - - def _AsyncWith(self, t): - self._generic_With(t, async_=True) - - # expr - def _Bytes(self, t): - self.write(repr(t.s)) - - def _Str(self, tree): - if six.PY3: - self.write(repr(tree.s)) - else: - # if from __future__ import unicode_literals is in effect, - # then we want to output string literals using a 'b' prefix - # and unicode literals with no prefix. - if "unicode_literals" not in self.future_imports: - self.write(repr(tree.s)) - elif isinstance(tree.s, str): - self.write("b" + repr(tree.s)) - elif isinstance(tree.s, unicode): - self.write(repr(tree.s).lstrip("u")) - else: - assert False, "shouldn't get here" - - def _JoinedStr(self, t): - # JoinedStr(expr* values) - self.write("f") - string = StringIO() - self._fstring_JoinedStr(t, string.write) - # Deviation from `unparse.py`: Try to find an unused quote. - # This change is made to handle _very_ complex f-strings. - v = string.getvalue() - if '\n' in v or '\r' in v: - quote_types = ["'''", '"""'] - else: - quote_types = ["'", '"', '"""', "'''"] - for quote_type in quote_types: - if quote_type not in v: - v = "{quote_type}{v}{quote_type}".format(quote_type=quote_type, v=v) - break - else: - v = repr(v) - self.write(v) - - def _FormattedValue(self, t): - # FormattedValue(expr value, int? conversion, expr? format_spec) - self.write("f") - string = StringIO() - self._fstring_JoinedStr(t, string.write) - self.write(repr(string.getvalue())) - - def _fstring_JoinedStr(self, t, write): - for value in t.values: - meth = getattr(self, "_fstring_" + type(value).__name__) - meth(value, write) - - def _fstring_Str(self, t, write): - value = t.s.replace("{", "{{").replace("}", "}}") - write(value) - - def _fstring_Constant(self, t, write): - assert isinstance(t.value, str) - value = t.value.replace("{", "{{").replace("}", "}}") - write(value) - - def _fstring_FormattedValue(self, t, write): - write("{") - expr = StringIO() - Unparser(t.value, expr) - expr = expr.getvalue().rstrip("\n") - if expr.startswith("{"): - write(" ") # Separate pair of opening brackets as "{ {" - write(expr) - if t.conversion != -1: - conversion = chr(t.conversion) - assert conversion in "sra" - write("!{conversion}".format(conversion=conversion)) - if t.format_spec: - write(":") - meth = getattr(self, "_fstring_" + type(t.format_spec).__name__) - meth(t.format_spec, write) - write("}") - - def _Name(self, t): - self.write(t.id) - - def _NameConstant(self, t): - self.write(repr(t.value)) - - def _Repr(self, t): - self.write("`") - self.dispatch(t.value) - self.write("`") - - def _write_constant(self, value): - if isinstance(value, (float, complex)): - # Substitute overflowing decimal literal for AST infinities. - self.write(repr(value).replace("inf", INFSTR)) - else: - self.write(repr(value)) - - def _Constant(self, t): - value = t.value - if isinstance(value, tuple): - self.write("(") - if len(value) == 1: - self._write_constant(value[0]) - self.write(",") - else: - interleave(lambda: self.write(", "), self._write_constant, value) - self.write(")") - elif value is Ellipsis: # instead of `...` for Py2 compatibility - self.write("...") - else: - if t.kind == "u": - self.write("u") - self._write_constant(t.value) - - def _Num(self, t): - repr_n = repr(t.n) - if six.PY3: - self.write(repr_n.replace("inf", INFSTR)) - else: - # Parenthesize negative numbers, to avoid turning (-1)**2 into -1**2. - if repr_n.startswith("-"): - self.write("(") - if "inf" in repr_n and repr_n.endswith("*j"): - repr_n = repr_n.replace("*j", "j") - # Substitute overflowing decimal literal for AST infinities. - self.write(repr_n.replace("inf", INFSTR)) - if repr_n.startswith("-"): - self.write(")") - - def _List(self, t): - self.write("[") - interleave(lambda: self.write(", "), self.dispatch, t.elts) - self.write("]") - - 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 _SetComp(self, t): - self.write("{") - self.dispatch(t.elt) - for gen in t.generators: - self.dispatch(gen) - self.write("}") - - def _DictComp(self, t): - self.write("{") - self.dispatch(t.key) - self.write(": ") - self.dispatch(t.value) - for gen in t.generators: - self.dispatch(gen) - self.write("}") - - def _comprehension(self, t): - if getattr(t, 'is_async', False): - self.write(" async for ") - else: - 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.write("(") - self.dispatch(t.body) - self.write(" if ") - self.dispatch(t.test) - self.write(" else ") - self.dispatch(t.orelse) - self.write(")") - - def _Set(self, t): - assert(t.elts) # should be at least one element - self.write("{") - interleave(lambda: self.write(", "), self.dispatch, t.elts) - self.write("}") - - def _Dict(self, t): - self.write("{") - def write_key_value_pair(k, v): - self.dispatch(k) - self.write(": ") - self.dispatch(v) - - def write_item(item): - k, v = item - if k is None: - # for dictionary unpacking operator in dicts {**{'y': 2}} - # see PEP 448 for details - self.write("**") - self.dispatch(v) - else: - write_key_value_pair(k, v) - interleave(lambda: self.write(", "), write_item, zip(t.keys, t.values)) - self.write("}") - - def _Tuple(self, t): - self.write("(") - if len(t.elts) == 1: - elt = t.elts[0] - self.dispatch(elt) - self.write(",") - else: - interleave(lambda: self.write(", "), self.dispatch, t.elts) - self.write(")") - - unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"} - def _UnaryOp(self, t): - self.write("(") - self.write(self.unop[t.op.__class__.__name__]) - self.write(" ") - if six.PY2 and isinstance(t.op, ast.USub) and isinstance(t.operand, ast.Num): - # If we're applying unary minus to a number, parenthesize the number. - # This is necessary: -2147483648 is different from -(2147483648) on - # a 32-bit machine (the first is an int, the second a long), and - # -7j is different from -(7j). (The first has real part 0.0, the second - # has real part -0.0.) - self.write("(") - self.dispatch(t.operand) - self.write(")") - else: - self.dispatch(t.operand) - self.write(")") - - binop = { "Add":"+", "Sub":"-", "Mult":"*", "MatMult":"@", "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(")") - - cmpops = {"Eq":"==", "NotEq":"!=", "Lt":"<", "LtE":"<=", "Gt":">", "GtE":">=", - "Is":"is", "IsNot":"is not", "In":"in", "NotIn":"not in"} - def _Compare(self, t): - self.write("(") - self.dispatch(t.left) - for o, e in zip(t.ops, t.comparators): - self.write(" " + self.cmpops[o.__class__.__name__] + " ") - self.dispatch(e) - self.write(")") - - boolops = {ast.And: 'and', ast.Or: 'or'} - def _BoolOp(self, t): - self.write("(") - s = " %s " % self.boolops[t.op.__class__] - interleave(lambda: self.write(s), self.dispatch, t.values) - self.write(")") - - def _Attribute(self,t): - self.dispatch(t.value) - # Special case: 3.__abs__() is a syntax error, so if t.value - # is an integer literal then we need to either parenthesize - # it or add an extra space to get 3 .__abs__(). - if isinstance(t.value, getattr(ast, 'Constant', getattr(ast, 'Num', None))) and isinstance(t.value.n, int): - self.write(" ") - 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 sys.version_info[:2] < (3, 5): - 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(")") - - def _Subscript(self, t): - self.dispatch(t.value) - self.write("[") - self.dispatch(t.slice) - self.write("]") - - def _Starred(self, t): - self.write("*") - self.dispatch(t.value) - - # slice - def _Ellipsis(self, t): - self.write("...") - - def _Index(self, t): - self.dispatch(t.value) - - def _Slice(self, t): - 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) - - def _ExtSlice(self, t): - interleave(lambda: self.write(', '), self.dispatch, t.dims) - - # argument - def _arg(self, t): - self.write(t.arg) - if t.annotation: - self.write(": ") - self.dispatch(t.annotation) - - # others - def _arguments(self, t): - first = True - # normal arguments - all_args = getattr(t, 'posonlyargs', []) + t.args - defaults = [None] * (len(all_args) - len(t.defaults)) + t.defaults - for index, elements in enumerate(zip(all_args, defaults), 1): - a, d = elements - if first:first = False - else: self.write(", ") - self.dispatch(a) - if d: - self.write("=") - self.dispatch(d) - if index == len(getattr(t, 'posonlyargs', ())): - self.write(", /") - - # varargs, or bare '*' if no varargs but keyword-only arguments present - if t.vararg or getattr(t, "kwonlyargs", False): - if first:first = False - else: self.write(", ") - self.write("*") - if t.vararg: - if hasattr(t.vararg, 'arg'): - self.write(t.vararg.arg) - if t.vararg.annotation: - self.write(": ") - self.dispatch(t.vararg.annotation) - else: - self.write(t.vararg) - if getattr(t, 'varargannotation', None): - self.write(": ") - self.dispatch(t.varargannotation) - - # keyword-only arguments - if getattr(t, "kwonlyargs", False): - for a, d in zip(t.kwonlyargs, t.kw_defaults): - if first:first = False - else: self.write(", ") - self.dispatch(a), - if d: - self.write("=") - self.dispatch(d) - - # kwargs - if t.kwarg: - if first:first = False - else: self.write(", ") - if hasattr(t.kwarg, 'arg'): - self.write("**"+t.kwarg.arg) - if t.kwarg.annotation: - self.write(": ") - self.dispatch(t.kwarg.annotation) - else: - self.write("**"+t.kwarg) - if getattr(t, 'kwargannotation', None): - self.write(": ") - self.dispatch(t.kwargannotation) - - def _keyword(self, t): - if t.arg is None: - # starting from Python 3.5 this denotes a kwargs part of the invocation - self.write("**") - else: - self.write(t.arg) - self.write("=") - self.dispatch(t.value) - - def _Lambda(self, t): - self.write("(") - self.write("lambda ") - self.dispatch(t.args) - self.write(": ") - self.dispatch(t.body) - self.write(")") - - def _alias(self, t): - self.write(t.name) - if t.asname: - self.write(" as "+t.asname) - - def _withitem(self, t): - self.dispatch(t.context_expr) - if t.optional_vars: - self.write(" as ") - self.dispatch(t.optional_vars) - -def 转(tree): - v = cStringIO() - Unparser(tree, file=v) - return v.getvalue() \ No newline at end of file -- Gitee From 539ac688694f1b1cbb702f22ad00993a61fdb56f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E5=A4=B4=E8=89=BA=E6=9C=AF=E5=AE=B6=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=AE=A4?= <5647384+labsite@user.noreply.gitee.com> Date: Thu, 26 Aug 2021 00:19:35 +0000 Subject: [PATCH 08/12] =?UTF-8?q?add=20=E6=9C=A8=E5=85=B0/=E8=BD=AC.py.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\346\234\250\345\205\260/\350\275\254.py" | 49 ++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 "\346\234\250\345\205\260/\350\275\254.py" diff --git "a/\346\234\250\345\205\260/\350\275\254.py" "b/\346\234\250\345\205\260/\350\275\254.py" new file mode 100644 index 0000000..fb63f6c --- /dev/null +++ "b/\346\234\250\345\205\260/\350\275\254.py" @@ -0,0 +1,49 @@ +from astunparse.unparse import Unparser +from __future__ import absolute_import +from six.moves import cStringIO + +函数转换 = { + "println": "print", + "tuple": "", + "char": "chr", + "isa": "isinstance", + "ceil": "math.ceil", + "floor": "math.floor", + "fabs": "math.fabs", + "sqrt": "math.sqrt", + "log": "math.log", + "log10": "math.log10", + "exp": "math.exp", + "pow": "math.pow", + "sin": "math.sin", + "cos": "math.cos", + "tan": "math.tan", + "asin": "math.asin", + "acos": "math.acos", +} + +class 转(Unparser): + def __init__(self, tree, file = sys.stdout): + self.f = file + self.future_imports = [] + self._indent = 0 + self.dispatch(tree) + print("import sys\nfrom math import *\nARGV = sys.argv[1:]\n", file=self.f) + self.f.flush() + + def _Name(self, t): + if node.id == "PI": + self.write("pi") + else: + self.write(t.id) + + def _Call(self, node): + if isinstance(node.func, ast.Name): + if node.func.id in 函数转换: + node.func.id = 函数转换[node.func.id] + super().visit_Call(node) + +def 转(树): + v = cStringIO() + Unparser(树, file=v) + return v.getvalue() \ No newline at end of file -- Gitee From 9890d6cf1340e711331194da2e6701c8a1d3e344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E5=A4=B4=E8=89=BA=E6=9C=AF=E5=AE=B6=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=AE=A4?= <5647384+labsite@user.noreply.gitee.com> Date: Thu, 26 Aug 2021 02:39:29 +0000 Subject: [PATCH 09/12] update setup.py. --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 4f08e6f..e8b201c 100644 --- a/setup.py +++ b/setup.py @@ -29,6 +29,7 @@ setuptools.setup( ], install_requires=[ 'rply-ulang', + 'astunparse' ], python_requires="== 3.7.*" ) \ No newline at end of file -- Gitee From 18a655540f275b10d383ae1110b8bf7d3e25fb83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E5=A4=B4=E8=89=BA=E6=9C=AF=E5=AE=B6=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=AE=A4?= <5647384+labsite@user.noreply.gitee.com> Date: Thu, 26 Aug 2021 10:40:09 +0000 Subject: [PATCH 10/12] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20?= =?UTF-8?q?=E6=9C=A8=E5=85=B0/=E8=BD=AC.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\346\234\250\345\205\260/\350\275\254.py" | 49 ---------------------- 1 file changed, 49 deletions(-) delete mode 100644 "\346\234\250\345\205\260/\350\275\254.py" diff --git "a/\346\234\250\345\205\260/\350\275\254.py" "b/\346\234\250\345\205\260/\350\275\254.py" deleted file mode 100644 index fb63f6c..0000000 --- "a/\346\234\250\345\205\260/\350\275\254.py" +++ /dev/null @@ -1,49 +0,0 @@ -from astunparse.unparse import Unparser -from __future__ import absolute_import -from six.moves import cStringIO - -函数转换 = { - "println": "print", - "tuple": "", - "char": "chr", - "isa": "isinstance", - "ceil": "math.ceil", - "floor": "math.floor", - "fabs": "math.fabs", - "sqrt": "math.sqrt", - "log": "math.log", - "log10": "math.log10", - "exp": "math.exp", - "pow": "math.pow", - "sin": "math.sin", - "cos": "math.cos", - "tan": "math.tan", - "asin": "math.asin", - "acos": "math.acos", -} - -class 转(Unparser): - def __init__(self, tree, file = sys.stdout): - self.f = file - self.future_imports = [] - self._indent = 0 - self.dispatch(tree) - print("import sys\nfrom math import *\nARGV = sys.argv[1:]\n", file=self.f) - self.f.flush() - - def _Name(self, t): - if node.id == "PI": - self.write("pi") - else: - self.write(t.id) - - def _Call(self, node): - if isinstance(node.func, ast.Name): - if node.func.id in 函数转换: - node.func.id = 函数转换[node.func.id] - super().visit_Call(node) - -def 转(树): - v = cStringIO() - Unparser(树, file=v) - return v.getvalue() \ No newline at end of file -- Gitee From 63fc029aee3567fc5dc95b0e7878cb8e79e14230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E5=A4=B4=E8=89=BA=E6=9C=AF=E5=AE=B6=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=AE=A4?= <5647384+labsite@user.noreply.gitee.com> Date: Thu, 26 Aug 2021 10:40:49 +0000 Subject: [PATCH 11/12] =?UTF-8?q?add=20=E6=9C=A8=E5=85=B0/=E7=94=9F?= =?UTF-8?q?=E6=88=90/python.py.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\347\224\237\346\210\220/python.py" | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 "\346\234\250\345\205\260/\347\224\237\346\210\220/python.py" diff --git "a/\346\234\250\345\205\260/\347\224\237\346\210\220/python.py" "b/\346\234\250\345\205\260/\347\224\237\346\210\220/python.py" new file mode 100644 index 0000000..debce0d --- /dev/null +++ "b/\346\234\250\345\205\260/\347\224\237\346\210\220/python.py" @@ -0,0 +1,52 @@ +from __future__ import absolute_import +from astunparse import Unparser +from six.moves import cStringIO +import ast +import sys + +函数转换 = { + "println": "print", + "tuple": "", + "char": "chr", + "isa": "isinstance", + "ceil": "math.ceil", + "floor": "math.floor", + "fabs": "math.fabs", + "sqrt": "math.sqrt", + "log": "math.log", + "log10": "math.log10", + "exp": "math.exp", + "pow": "math.pow", + "sin": "math.sin", + "cos": "math.cos", + "tan": "math.tan", + "asin": "math.asin", + "acos": "math.acos", +} + +class 转(Unparser): + def __init__(self, tree, file = sys.stdout): + self.f = file + self.future_imports = [] + self._indent = 0 + self.dispatch(tree) + self.v = cStringIO() + self.f.flush() + self.v.write("\nimport sys\nfrom math import *\nARGV = sys.argv[1:]" + self.f.getvalue()) + self.v.flush() + + def _Name(self, 节点): + if 节点.id == "PI": + self.write("pi") + else: + self.write(节点.id) + + def _Call(self, 节点): + if isinstance(节点.func, ast.Name): + if 节点.func.id in 函数转换: + 节点.func.id = 函数转换[节点.func.id] + super()._Call(节点) + +def 转python(树): + v = cStringIO() + return 转(树, file=v).v.getvalue() \ No newline at end of file -- Gitee From 4315608ab0b088691469fad1f793b25f06f319ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E5=A4=B4=E8=89=BA=E6=9C=AF=E5=AE=B6=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=AE=A4?= <5647384+labsite@user.noreply.gitee.com> Date: Thu, 26 Aug 2021 10:41:30 +0000 Subject: [PATCH 12/12] =?UTF-8?q?update=20=E6=9C=A8=E5=85=B0/=E4=B8=AD.py.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\346\234\250\345\205\260/\344\270\255.py" | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git "a/\346\234\250\345\205\260/\344\270\255.py" "b/\346\234\250\345\205\260/\344\270\255.py" index 6fe314f..ab7a23c 100755 --- "a/\346\234\250\345\205\260/\344\270\255.py" +++ "b/\346\234\250\345\205\260/\344\270\255.py" @@ -9,7 +9,7 @@ from 木兰.环境 import 创建全局变量 from 木兰.交互 import 开始交互 from 木兰.功用.反馈信息 import 反馈信息 from 木兰.功用.调试辅助 import 语法树相关 -import 转 +from 木兰.生成.python import 转python def 用途(程序): 介绍 = '''使用方法: %s 源码文件 @@ -17,6 +17,7 @@ def 用途(程序): --版本, -版 显示版本 --python变木兰, -兰 将 Python 源码转换为木兰源码 --语法树, -树 语法树信息 + --木兰变python, -p 将木兰源码转换为 python 源码 ''' sys.stderr.write(介绍 % os.path.basename(程序)) sys.exit(-1) @@ -28,12 +29,12 @@ def 中(argv=None): try: 选项, 参数 = getopt.getopt( argv[1:], - '兰版树转', + '兰版树p', [ "语法树", "python变木兰", '版本', - '转python', + '木兰变python', ]) except getopt.GetoptError as e: try: @@ -46,7 +47,7 @@ def 中(argv=None): 版本 = False python变木兰 = False 语法树 = False - 转python = False + 木兰变python = False for 某项, 值 in 选项: if 某项 in ('-版', '--版本'): @@ -55,8 +56,8 @@ def 中(argv=None): python变木兰 = True elif 某项 in ("-树", "--语法树"): 语法树 = True - elif 某项 in ('–转', '--转python'): - 转python = True + elif 某项 in ('–转', '--木兰变python'): + 木兰变python = True if 版本: @@ -102,5 +103,5 @@ def 中(argv=None): except SyntaxError as 语法错误: sys.stderr.write(f"语法错误: {语法错误}\n") - if 转python: - print(转.转(节点)) \ No newline at end of file + if 木兰变python: + print(转python(节点)) \ No newline at end of file -- Gitee