From 4abdffecb95a28de1fcf8da4a9af2cd5d41af878 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 11 Nov 2019 19:07:58 -0500 Subject: [PATCH] More 3.0 control-flow rules... Much more is needed though --- test/bytecode_3.0/02_while1_if_while1.pyc | Bin 222 -> 484 bytes .../bug30/02_while1_if_while1.py | 5 +++ uncompyle6/parsers/parse30.py | 30 +++++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/test/bytecode_3.0/02_while1_if_while1.pyc b/test/bytecode_3.0/02_while1_if_while1.pyc index c4282d8e527e49bcc16b56d23ff5e0643b3b91b9..7e44fe49d3bff37e971f19a5ef6ad92194147548 100644 GIT binary patch delta 282 zcmZ9F!3se^6o&sZ;}R~3wImx`3neU+y_AJgk_?61i)+f_V!;dC$MOkeTNmaqf-5H14aslFsLfNoC&1l6m?lagK?}OBnhr# z@GGDYSOG@iO7IKcnSCwuiLle4p#gsz43I{VdQ}~b%Q^d(iq8FfmNS|XByuRDlKKrj1-jp*~1H|{!V457rs5rTaF+hL^$Y*9` LX9QtZMqVZWoMj0* diff --git a/test/simple_source/bug30/02_while1_if_while1.py b/test/simple_source/bug30/02_while1_if_while1.py index 849bf110..f7ba63a5 100644 --- a/test/simple_source/bug30/02_while1_if_while1.py +++ b/test/simple_source/bug30/02_while1_if_while1.py @@ -7,3 +7,8 @@ while 1: raise RuntimeError else: raise RuntimeError + +# Adapted from 3.0.1 cgi.py +def _parseparam(s, end): + while end > 0 and s.count(''): + end = s.find(';') diff --git a/uncompyle6/parsers/parse30.py b/uncompyle6/parsers/parse30.py index 470fbe3d..6fb0b545 100644 --- a/uncompyle6/parsers/parse30.py +++ b/uncompyle6/parsers/parse30.py @@ -135,11 +135,12 @@ class Python30Parser(Python31Parser): return_if_stmt ::= ret_expr RETURN_END_IF COME_FROM POP_TOP and ::= expr jmp_false expr come_from_opt whilestmt ::= SETUP_LOOP testexpr l_stmts_opt come_from_opt - JUMP_BACK COME_FROM POP_TOP POP_BLOCK COME_FROM_LOOP + JUMP_BACK come_froms POP_TOP POP_BLOCK COME_FROM_LOOP whilestmt ::= SETUP_LOOP testexpr returns POP_TOP POP_BLOCK COME_FROM_LOOP + # compare_chained is like x <= y <= z compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP jmp_false compare_chained1 _come_froms @@ -174,7 +175,34 @@ class Python30Parser(Python31Parser): compare_chained2 COME_FROM """) + self.check_reduce['iflaststmtl'] = 'AST' + # self.check_reduce['ifelsestmt'] = 'AST' return + + def reduce_is_invalid(self, rule, ast, tokens, first, last): + invalid = super(Python30Parser, + self).reduce_is_invalid(rule, ast, + tokens, first, last) + if invalid: + return invalid + if ( + rule[0] in ("iflaststmtl",) and ast[0] == "testexpr" + ): + testexpr = ast[0] + if testexpr[0] == "testfalse": + testfalse = testexpr[0] + if testfalse[1] == "jmp_false": + jmp_false = testfalse[1] + if last == len(tokens): + last -= 1 + while (isinstance(tokens[first].offset, str) and first < last): + first += 1 + if first == last: + return True + while (first < last and isinstance(tokens[last].offset, str)): + last -= 1 + return not (tokens[first].offset <= jmp_false[0].attr <= tokens[last].offset) + pass class Python30ParserSingle(Python30Parser, PythonParserSingle):