diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 67cb856b..ccd017c8 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -392,9 +392,6 @@ class Python3Parser(PythonParser): ''' load_genexpr ::= LOAD_GENEXPR load_genexpr ::= BUILD_TUPLE_1 LOAD_GENEXPR LOAD_CONST - - # Is there something general going on here? - dict_comp ::= load_closure LOAD_DICTCOMP LOAD_CONST MAKE_CLOSURE_0 expr GET_ITER CALL_FUNCTION_1 ''' def p_expr3(self, args): @@ -574,6 +571,10 @@ class Python3Parser(PythonParser): seen_LOAD_BUILD_CLASS = False seen_GET_AWAITABLE_YIELD_FROM = False + # This is used in parse36.py as well as here + self.seen_LOAD_DICTCOMP = False + + # Loop over instructions adding custom grammar rules based on # a specific instruction seen. @@ -783,6 +784,7 @@ class Python3Parser(PythonParser): self.addRule("expr ::= LOAD_CLASSNAME", nop_func) custom_ops_seen.add(opname) elif opname == 'LOAD_DICTCOMP': + self.seen_LOAD_DICTCOMP = True if has_get_iter_call_function1: rule_pat = ("dict_comp ::= LOAD_DICTCOMP %sMAKE_FUNCTION_0 expr " "GET_ITER CALL_FUNCTION_1") @@ -815,6 +817,17 @@ class Python3Parser(PythonParser): # DRY with MAKE_FUNCTION # Note: this probably doesn't handle kwargs proprerly + if opname == 'MAKE_CLOSURE_0' and self.seen_LOAD_DICTCOMP: + # Is there something general going on here? + # Note that 3.6+ doesn't do this, but we'll remove + # this rule in parse36.py + rule = """ + dict_comp ::= load_closure LOAD_DICTCOMP LOAD_CONST + MAKE_CLOSURE_0 expr + GET_ITER CALL_FUNCTION_1 + """ + self.addRule(rule, nop_func) + args_pos, args_kw, annotate_args = token.attr # FIXME: Fold test into add_make_function_rule diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index 4859fad6..17d0ef56 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -36,9 +36,6 @@ class Python36Parser(Python35Parser): # 3.6 redoes how return_closure works. FIXME: Isolate to LOAD_CLOSURE return_closure ::= LOAD_CLOSURE DUP_TOP STORE_NAME RETURN_VALUE RETURN_LAST - # Is there something general going on here? FIXME: Isolate to LOAD_DICTCOMP - dict_comp ::= load_closure LOAD_DICTCOMP LOAD_CONST MAKE_FUNCTION_8 expr GET_ITER CALL_FUNCTION_1 - stmt ::= conditional_lambda conditional_lambda ::= expr jmp_false expr return_if_lambda return_stmt_lambda LAMBDA_MARKER @@ -106,6 +103,14 @@ class Python36Parser(Python35Parser): fstring_single ::= expr FORMAT_VALUE """ self.add_unique_doc_rules(rules_str, customize) + elif opname == 'MAKE_FUNCTION_8' and self.seen_LOAD_DICTCOMP: + # Is there something general going on here? + rule = """ + dict_comp ::= load_closure LOAD_DICTCOMP LOAD_CONST + MAKE_FUNCTION_8 expr + GET_ITER CALL_FUNCTION_1 + """ + self.addRule(rule, nop_func) elif opname == 'BEFORE_ASYNC_WITH': rules_str = """ stmt ::= async_with_stmt