From 33918bd9d2526fad948af65930a714330f52c27b Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 26 Jan 2020 02:58:33 -0500 Subject: [PATCH] More 3.x "if" checking. Abbreviate stmts->sstmt --- uncompyle6/parser.py | 2 +- uncompyle6/parsers/parse3.py | 1 - uncompyle6/parsers/reducecheck/ifstmt.py | 5 +++-- uncompyle6/semantics/pysource.py | 16 ++++++++++++---- uncompyle6/semantics/transform.py | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/uncompyle6/parser.py b/uncompyle6/parser.py index fd71f46f..df1c9f4c 100644 --- a/uncompyle6/parser.py +++ b/uncompyle6/parser.py @@ -89,7 +89,7 @@ class PythonParser(GenericASTBuilder): # singleton reduction that we can simplify. It also happens to be optional # in its other derivation self.optional_nt |= frozenset( - ("come_froms", "suite_stmts", "l_stmts_opt", "c_stmts_opt", "stmts_opt") + ("come_froms", "suite_stmts", "l_stmts_opt", "c_stmts_opt", "stmts_opt", "stmt") ) # Reduce singleton reductions in these nonterminals: diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 90f07494..f11a0981 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -380,7 +380,6 @@ class Python3Parser(PythonParser): iflaststmt ::= testexpr _iflaststmts_jump ifelsestmt ::= testexpr stmts_opt jump_absolute_else else_suite ifelsestmt ::= testexpr stmts_opt jump_forward_else else_suite _come_froms - iflaststmt ::= testexpr _ifstmts_jump else_suite ::= stmts diff --git a/uncompyle6/parsers/reducecheck/ifstmt.py b/uncompyle6/parsers/reducecheck/ifstmt.py index d31b3720..7ddabae9 100644 --- a/uncompyle6/parsers/reducecheck/ifstmt.py +++ b/uncompyle6/parsers/reducecheck/ifstmt.py @@ -20,11 +20,12 @@ def ifstmt(self, lhs, n, rule, ast, tokens, first, last): last_offset = tokens[l].offset for i in range(first, l): t = tokens[i] - if t.kind == "POP_JUMP_IF_FALSE": + # instead of POP_JUMP_IF, should we use op attributes? + if t.kind in ("POP_JUMP_IF_FALSE", "POP_JUMP_IF_TRUE"): pjif_target = t.attr if pjif_target > last_offset: # In come cases, where we have long bytecode, a - # "POP_JUMP_IF_FALSE" offset might be too + # "POP_JUMP_IF_TRUE/FALSE" offset might be too # large for the instruction; so instead it # jumps to a JUMP_FORWARD. Allow that here. if tokens[l] == "JUMP_FORWARD": diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 582f17a9..02214467 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1103,7 +1103,10 @@ class SourceWalker(GenericASTTraversal, object): code = Code(cn.attr, self.scanner, self.currentclass) ast = self.build_ast(code._tokens, code._customize) self.customize(code._customize) - ast = ast[0][0][0] + + # Remove single reductions as in ("stmts", "sstmt"): + while len(ast) == 1: + ast = ast[0] n = ast[iter_index] assert n == "comp_iter", n @@ -1368,7 +1371,11 @@ class SourceWalker(GenericASTTraversal, object): code = Code(node[1].attr, self.scanner, self.currentclass) ast = self.build_ast(code._tokens, code._customize) self.customize(code._customize) - ast = ast[0][0][0] + + # Remove single reductions as in ("stmts", "sstmt"): + while len(ast) == 1: + ast = ast[0] + store = ast[3] collection = node[collection_index] @@ -2208,6 +2215,7 @@ class SourceWalker(GenericASTTraversal, object): pass return + # This code is only for Python 1.x - 2.1 ish! def get_tuple_parameter(self, ast, name): """ If the name of the formal parameter starts with dot, @@ -2224,8 +2232,8 @@ class SourceWalker(GenericASTTraversal, object): assert ast == "stmts" for i in range(len(ast)): # search for an assign-statement - assert ast[i][0] == "stmt" - node = ast[i][0][0] + assert ast[i] == "sstmt" + node = ast[i][0] if node == "assign" and node[0] == ASSIGN_TUPLE_PARAM(name): # okay, this assigns '.n' to something del ast[i] diff --git a/uncompyle6/semantics/transform.py b/uncompyle6/semantics/transform.py index 9a5710b3..7f6a27eb 100644 --- a/uncompyle6/semantics/transform.py +++ b/uncompyle6/semantics/transform.py @@ -346,7 +346,7 @@ class TreeTransform(GenericASTTraversal, object): def n_stmts(self, node): if node.first_child() == "SETUP_ANNOTATIONS": - prev = node[0][0][0] + prev = node[0][0] new_stmts = [node[0]] for i, sstmt in enumerate(node[1:]): ann_assign = sstmt[0][0]