diff --git a/test/simple_source/bug33/01_triple_compare.py b/test/simple_source/bug33/01_triple_compare.py index 5523c6b9..f0985f19 100644 --- a/test/simple_source/bug33/01_triple_compare.py +++ b/test/simple_source/bug33/01_triple_compare.py @@ -1,4 +1,5 @@ # In Python 3.3+ this uses grammar rule -# cmp_list2 ::= expr COMPARE_OP RETURN_VALUE +# compare_chained2 ::= expr COMPARE_OP RETURN_VALUE + def _is_valid_netmask(self, netmask): return 0 <= netmask <= self._max_prefixlen diff --git a/uncompyle6/parser.py b/uncompyle6/parser.py index 02f5695b..415d78d4 100644 --- a/uncompyle6/parser.py +++ b/uncompyle6/parser.py @@ -504,14 +504,17 @@ class PythonParser(GenericASTBuilder): return_lambda ::= ret_expr RETURN_VALUE_LAMBDA LAMBDA_MARKER return_lambda ::= ret_expr RETURN_VALUE_LAMBDA - # Doesn't seemt to be used anymore, but other conditional_lambda's are + # Doesn't seem to be used anymore, but other conditional_lambda's are # conditional_lambda ::= expr jmp_false return_if_stmt return_stmt LAMBDA_MARKER - cmp ::= cmp_list - cmp ::= compare + cmp ::= compare_chained + cmp ::= compare compare ::= expr expr COMPARE_OP - cmp_list ::= expr cmp_list1 ROT_TWO POP_TOP _come_from - cmp_list2 ::= expr COMPARE_OP JUMP_FORWARD + + # A compare_chained is two comparisions like x <= y <= z + compare_chained ::= expr compare_chained1 ROT_TWO POP_TOP _come_from + compare_chained2 ::= expr COMPARE_OP JUMP_FORWARD + mapexpr ::= BUILD_MAP kvlist kvlist ::= kvlist kv diff --git a/uncompyle6/parsers/parse2.py b/uncompyle6/parsers/parse2.py index 2f0ddda3..507d0151 100644 --- a/uncompyle6/parsers/parse2.py +++ b/uncompyle6/parsers/parse2.py @@ -203,8 +203,10 @@ class Python2Parser(PythonParser): binary_subscr2 ::= expr expr DUP_TOPX_2 BINARY_SUBSCR conditional ::= expr jmp_false expr JUMP_ABSOLUTE expr - cmp_list2 ::= expr COMPARE_OP RETURN_VALUE - cmp_list2 ::= expr COMPARE_OP RETURN_VALUE_LAMBDA + + # compare_chained2 is used in a "chained_compare": x <= y <= z + compare_chained2 ::= expr COMPARE_OP RETURN_VALUE + compare_chained2 ::= expr COMPARE_OP RETURN_VALUE_LAMBDA """ def p_slice2(self, args): diff --git a/uncompyle6/parsers/parse26.py b/uncompyle6/parsers/parse26.py index 9524aab1..43e01331 100644 --- a/uncompyle6/parsers/parse26.py +++ b/uncompyle6/parsers/parse26.py @@ -243,10 +243,12 @@ class Python26Parser(Python2Parser): def p_misc26(self, args): """ conditional ::= expr jmp_false expr jf_cf_pop expr come_from_opt - and ::= expr JUMP_IF_FALSE POP_TOP expr JUMP_IF_FALSE POP_TOP - cmp_list ::= expr cmp_list1 ROT_TWO COME_FROM POP_TOP _come_from - cmp_list1 ::= expr DUP_TOP ROT_THREE COMPARE_OP jmp_false cmp_list1 _come_from - cmp_list1 ::= expr DUP_TOP ROT_THREE COMPARE_OP jmp_false cmp_list2 _come_from + and ::= expr JUMP_IF_FALSE POP_TOP expr JUMP_IF_FALSE POP_TOP + + # compare_chained is like x <= y <= z + compare_chained ::= expr compare_chained1 ROT_TWO COME_FROM POP_TOP _come_from + compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP jmp_false compare_chained1 _come_from + compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP jmp_false compare_chained2 _come_from return_if_lambda ::= RETURN_END_IF_LAMBDA POP_TOP conditional_lambda ::= expr jmp_false_then expr return_if_lambda diff --git a/uncompyle6/parsers/parse27.py b/uncompyle6/parsers/parse27.py index a22bfd2d..463474d6 100644 --- a/uncompyle6/parsers/parse27.py +++ b/uncompyle6/parsers/parse27.py @@ -77,12 +77,11 @@ class Python27Parser(Python2Parser): or ::= expr JUMP_IF_TRUE_OR_POP expr COME_FROM and ::= expr JUMP_IF_FALSE_OR_POP expr COME_FROM - cmp_list1 ::= expr DUP_TOP ROT_THREE - COMPARE_OP JUMP_IF_FALSE_OR_POP - cmp_list1 COME_FROM - cmp_list1 ::= expr DUP_TOP ROT_THREE - COMPARE_OP JUMP_IF_FALSE_OR_POP - cmp_list2 COME_FROM + # compare_chained1 is used exclusively in chained_compare + compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP + compare_chained1 COME_FROM + compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP + compare_chained2 COME_FROM """ def p_stmt27(self, args): diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 95e600ef..7b273634 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -334,10 +334,11 @@ class Python3Parser(PythonParser): or ::= expr JUMP_IF_TRUE_OR_POP expr COME_FROM and ::= expr JUMP_IF_FALSE_OR_POP expr COME_FROM - cmp_list1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP - cmp_list1 COME_FROM - cmp_list1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP - cmp_list2 COME_FROM + # compare_chained1 is used exclusively in chained_compare + compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP + compare_chained1 COME_FROM + compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP + compare_chained2 COME_FROM """ def p_stmt3(self, args): diff --git a/uncompyle6/parsers/parse32.py b/uncompyle6/parsers/parse32.py index ae15a1ad..37c30adb 100644 --- a/uncompyle6/parsers/parse32.py +++ b/uncompyle6/parsers/parse32.py @@ -10,8 +10,9 @@ from uncompyle6.parsers.parse3 import Python3Parser class Python32Parser(Python3Parser): def p_32to35(self, args): """ - conditional ::= expr jmp_false expr jump_forward_else expr COME_FROM - cmp_list2 ::= expr COMPARE_OP RETURN_VALUE + conditional ::= expr jmp_false expr jump_forward_else expr COME_FROM + # used exclusively in compare_chained + compare_chained2 ::= expr COMPARE_OP RETURN_VALUE # Store locals is only in Python 3.0 to 3.3 stmt ::= store_locals @@ -57,7 +58,7 @@ class Python32Parser(Python3Parser): def add_custom_rules(self, tokens, customize): # self.remove_rules(""" - # cmp_list2 ::= expr COMPARE_OP RETURN_VALUE + # compare_chained2 ::= expr COMPARE_OP RETURN_VALUE # """) super(Python32Parser, self).add_custom_rules(tokens, customize) for i, token in enumerate(tokens): diff --git a/uncompyle6/semantics/consts.py b/uncompyle6/semantics/consts.py index e9fc7274..ab87fded 100644 --- a/uncompyle6/semantics/consts.py +++ b/uncompyle6/semantics/consts.py @@ -193,9 +193,9 @@ TABLE_DIRECT = { 'conditional_lambda': ( '%c if %c else %c', 2, 0, 4), 'compare': ( '%p %[-1]{pattr.replace("-", " ")} %p', (0, 19), (1, 19) ), - 'cmp_list': ( '%p %p', (0, 29), (1, 30)), - 'cmp_list1': ( '%[3]{pattr} %p %p', (0, 19), (-2, 19)), - 'cmp_list2': ( '%[1]{pattr} %p', (0, 19)), + 'compare_chained': ( '%p %p', (0, 29), (1, 30)), + 'compare_chained1': ( '%[3]{pattr} %p %p', (0, 19), (-2, 19)), + 'compare_chained2': ( '%[1]{pattr} %p', (0, 19)), # 'classdef': (), # handled by n_classdef() 'funcdef': ( '\n\n%|def %c\n', -2), # -2 to handle closures 'funcdefdeco': ( '\n\n%c', 0),