You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Fix bug in 2.6 tryelse get test_grammar working...
localize grammar rules
This commit is contained in:
@@ -5,4 +5,4 @@ if [[ $0 == ${BASH_SOURCE[0]} ]] ; then
|
|||||||
echo "This script should be *sourced* rather than run directly through bash"
|
echo "This script should be *sourced* rather than run directly through bash"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
export PYVERSIONS='3.5.3 3.6.2 2.6.9 3.3.6 2.7.14 3.4.2'
|
export PYVERSIONS='3.5.3 3.6.3 2.6.9 3.3.6 2.7.14 3.4.2'
|
||||||
|
@@ -17,10 +17,9 @@ def test_grammar():
|
|||||||
(lhs, rhs, tokens,
|
(lhs, rhs, tokens,
|
||||||
right_recursive, dup_rhs) = p.check_sets()
|
right_recursive, dup_rhs) = p.check_sets()
|
||||||
expect_lhs = set(['expr1024', 'pos_arg'])
|
expect_lhs = set(['expr1024', 'pos_arg'])
|
||||||
unused_rhs = set(['list', 'call', 'mkfunc',
|
unused_rhs = set(['list', 'mkfunc',
|
||||||
'mklambda',
|
'mklambda',
|
||||||
'unpack',])
|
'unpack',])
|
||||||
|
|
||||||
expect_right_recursive = frozenset([('designList',
|
expect_right_recursive = frozenset([('designList',
|
||||||
('store', 'DUP_TOP', 'designList'))])
|
('store', 'DUP_TOP', 'designList'))])
|
||||||
if PYTHON3:
|
if PYTHON3:
|
||||||
@@ -32,13 +31,24 @@ def test_grammar():
|
|||||||
except_pop_except generator_exp classdefdeco2
|
except_pop_except generator_exp classdefdeco2
|
||||||
dict
|
dict
|
||||||
""".split()))
|
""".split()))
|
||||||
if 3.0 <= PYTHON_VERSION:
|
if PYTHON_VERSION >= 3.0:
|
||||||
expect_lhs.add("annotate_arg")
|
expect_lhs.add("annotate_arg")
|
||||||
expect_lhs.add("annotate_tuple")
|
expect_lhs.add("annotate_tuple")
|
||||||
unused_rhs.add("mkfunc_annotate")
|
unused_rhs.add("mkfunc_annotate")
|
||||||
|
if PYTHON_VERSION != 3.6:
|
||||||
|
# 3.6 has at least one non-custom call rule
|
||||||
|
# the others don't
|
||||||
|
unused_rhs.add('call')
|
||||||
|
else:
|
||||||
|
# These are custom rules set in 3.5
|
||||||
|
unused_rhs.add('build_map_unpack_with_call')
|
||||||
|
unused_rhs.add('unmapexpr')
|
||||||
|
pass
|
||||||
pass
|
pass
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
expect_lhs.add('kwarg')
|
expect_lhs.add('kwarg')
|
||||||
|
unused_rhs.add('call')
|
||||||
|
|
||||||
assert expect_lhs == set(lhs)
|
assert expect_lhs == set(lhs)
|
||||||
assert unused_rhs == set(rhs)
|
assert unused_rhs == set(rhs)
|
||||||
|
@@ -268,7 +268,6 @@ class PythonParser(GenericASTBuilder):
|
|||||||
|
|
||||||
stmt ::= return_stmt
|
stmt ::= return_stmt
|
||||||
return_stmt ::= ret_expr RETURN_VALUE
|
return_stmt ::= ret_expr RETURN_VALUE
|
||||||
return_stmt_lambda ::= ret_expr RETURN_VALUE_LAMBDA
|
|
||||||
|
|
||||||
# return_stmts are a sequence of statements that ends in a RETURN statement.
|
# return_stmts are a sequence of statements that ends in a RETURN statement.
|
||||||
# In later Python versions with jump optimization, this can cause JUMPs
|
# In later Python versions with jump optimization, this can cause JUMPs
|
||||||
@@ -487,14 +486,10 @@ class PythonParser(GenericASTBuilder):
|
|||||||
ret_expr_or_cond ::= ret_cond
|
ret_expr_or_cond ::= ret_cond
|
||||||
|
|
||||||
stmt ::= return_lambda
|
stmt ::= return_lambda
|
||||||
stmt ::= conditional_lambda
|
|
||||||
|
|
||||||
return_lambda ::= ret_expr RETURN_VALUE_LAMBDA LAMBDA_MARKER
|
return_lambda ::= ret_expr RETURN_VALUE_LAMBDA LAMBDA_MARKER
|
||||||
return_lambda ::= ret_expr RETURN_VALUE_LAMBDA
|
return_lambda ::= ret_expr RETURN_VALUE_LAMBDA
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
compare ::= compare_chained
|
compare ::= compare_chained
|
||||||
compare ::= compare_single
|
compare ::= compare_single
|
||||||
compare_single ::= expr expr COMPARE_OP
|
compare_single ::= expr expr COMPARE_OP
|
||||||
|
@@ -67,6 +67,8 @@ class Python2Parser(PythonParser):
|
|||||||
return_if_stmts ::= _stmts return_if_stmt
|
return_if_stmts ::= _stmts return_if_stmt
|
||||||
return_if_stmt ::= ret_expr RETURN_END_IF
|
return_if_stmt ::= ret_expr RETURN_END_IF
|
||||||
|
|
||||||
|
return_stmt_lambda ::= ret_expr RETURN_VALUE_LAMBDA
|
||||||
|
|
||||||
stmt ::= break_stmt
|
stmt ::= break_stmt
|
||||||
break_stmt ::= BREAK_LOOP
|
break_stmt ::= BREAK_LOOP
|
||||||
|
|
||||||
|
@@ -71,9 +71,12 @@ class Python25Parser(Python26Parser):
|
|||||||
return_if_stmts ::= return_if_stmt
|
return_if_stmts ::= return_if_stmt
|
||||||
return_stmt ::= ret_expr RETURN_END_IF POP_TOP
|
return_stmt ::= ret_expr RETURN_END_IF POP_TOP
|
||||||
return_stmt ::= ret_expr RETURN_VALUE POP_TOP
|
return_stmt ::= ret_expr RETURN_VALUE POP_TOP
|
||||||
|
return_stmt_lambda ::= ret_expr RETURN_VALUE_LAMBDA
|
||||||
setupwithas ::= DUP_TOP LOAD_ATTR ROT_TWO LOAD_ATTR CALL_FUNCTION_0 setup_finally
|
setupwithas ::= DUP_TOP LOAD_ATTR ROT_TWO LOAD_ATTR CALL_FUNCTION_0 setup_finally
|
||||||
stmt ::= classdefdeco
|
stmt ::= classdefdeco
|
||||||
stmt ::= conditional_lambda
|
stmt ::= conditional_lambda
|
||||||
|
conditional_lambda ::= expr jmp_false_then expr return_if_lambda
|
||||||
|
return_stmt_lambda LAMBDA_MARKER
|
||||||
""")
|
""")
|
||||||
super(Python25Parser, self).add_custom_rules(tokens, customize)
|
super(Python25Parser, self).add_custom_rules(tokens, customize)
|
||||||
if self.version == 2.5:
|
if self.version == 2.5:
|
||||||
|
@@ -248,6 +248,7 @@ class Python26Parser(Python2Parser):
|
|||||||
compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP
|
compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP
|
||||||
jmp_false compare_chained2 _come_from
|
jmp_false compare_chained2 _come_from
|
||||||
return_if_lambda ::= RETURN_END_IF_LAMBDA POP_TOP
|
return_if_lambda ::= RETURN_END_IF_LAMBDA POP_TOP
|
||||||
|
stmt ::= conditional_lambda
|
||||||
conditional_lambda ::= expr jmp_false_then expr return_if_lambda
|
conditional_lambda ::= expr jmp_false_then expr return_if_lambda
|
||||||
return_stmt_lambda LAMBDA_MARKER
|
return_stmt_lambda LAMBDA_MARKER
|
||||||
"""
|
"""
|
||||||
|
@@ -126,6 +126,7 @@ class Python27Parser(Python2Parser):
|
|||||||
|
|
||||||
# Common with 2.6
|
# Common with 2.6
|
||||||
return_if_lambda ::= RETURN_END_IF_LAMBDA COME_FROM
|
return_if_lambda ::= RETURN_END_IF_LAMBDA COME_FROM
|
||||||
|
stmt ::= conditional_lambda
|
||||||
conditional_lambda ::= expr jmp_false expr return_if_lambda
|
conditional_lambda ::= expr jmp_false expr return_if_lambda
|
||||||
return_stmt_lambda LAMBDA_MARKER
|
return_stmt_lambda LAMBDA_MARKER
|
||||||
|
|
||||||
|
@@ -615,6 +615,8 @@ class Python3Parser(PythonParser):
|
|||||||
assign3_pypy ::= expr expr expr store store store
|
assign3_pypy ::= expr expr expr store store store
|
||||||
assign2_pypy ::= expr expr store store
|
assign2_pypy ::= expr expr store store
|
||||||
return_if_lambda ::= RETURN_END_IF_LAMBDA
|
return_if_lambda ::= RETURN_END_IF_LAMBDA
|
||||||
|
return_stmt_lambda ::= ret_expr RETURN_VALUE_LAMBDA
|
||||||
|
stmt ::= conditional_lambda
|
||||||
conditional_lambda ::= expr jmp_false expr return_if_lambda
|
conditional_lambda ::= expr jmp_false expr return_if_lambda
|
||||||
return_stmt_lambda LAMBDA_MARKER
|
return_stmt_lambda LAMBDA_MARKER
|
||||||
""", nop_func)
|
""", nop_func)
|
||||||
|
@@ -20,12 +20,12 @@ class Python36Parser(Python35Parser):
|
|||||||
# 3.6 redoes how return_closure works
|
# 3.6 redoes how return_closure works
|
||||||
return_closure ::= LOAD_CLOSURE DUP_TOP STORE_NAME RETURN_VALUE RETURN_LAST
|
return_closure ::= LOAD_CLOSURE DUP_TOP STORE_NAME RETURN_VALUE RETURN_LAST
|
||||||
|
|
||||||
|
stmt ::= conditional_lambda
|
||||||
conditional_lambda ::= expr jmp_false expr return_if_lambda
|
conditional_lambda ::= expr jmp_false expr return_if_lambda
|
||||||
return_stmt_lambda LAMBDA_MARKER
|
return_stmt_lambda LAMBDA_MARKER
|
||||||
|
return_stmt_lambda ::= ret_expr RETURN_VALUE_LAMBDA
|
||||||
return_if_lambda ::= RETURN_END_IF_LAMBDA
|
return_if_lambda ::= RETURN_END_IF_LAMBDA
|
||||||
|
|
||||||
fstring_multi ::= fstring_expr_or_strs BUILD_STRING
|
|
||||||
fstring_expr_or_strs ::= fstring_expr_or_str+
|
|
||||||
|
|
||||||
func_args36 ::= expr BUILD_TUPLE_0
|
func_args36 ::= expr BUILD_TUPLE_0
|
||||||
call ::= func_args36 unmapexpr CALL_FUNCTION_EX
|
call ::= func_args36 unmapexpr CALL_FUNCTION_EX
|
||||||
@@ -96,9 +96,11 @@ class Python36Parser(Python35Parser):
|
|||||||
fstring_expr_or_str ::= fstring_expr
|
fstring_expr_or_str ::= fstring_expr
|
||||||
fstring_expr_or_str ::= str
|
fstring_expr_or_str ::= str
|
||||||
|
|
||||||
expr ::= fstring_multi
|
expr ::= fstring_multi
|
||||||
fstring_multi ::= %s BUILD_STRING
|
fstring_multi ::= fstring_expr_or_strs BUILD_STRING
|
||||||
%s ::= %sBUILD_STRING
|
fstring_expr_or_strs ::= fstring_expr_or_str+
|
||||||
|
fstring_multi ::= %s BUILD_STRING
|
||||||
|
%s ::= %sBUILD_STRING
|
||||||
""" % (fstring_expr_or_str_n, fstring_expr_or_str_n, "fstring_expr_or_str " * v)
|
""" % (fstring_expr_or_str_n, fstring_expr_or_str_n, "fstring_expr_or_str " * v)
|
||||||
self.add_unique_doc_rules(rules_str, customize)
|
self.add_unique_doc_rules(rules_str, customize)
|
||||||
|
|
||||||
|
@@ -1023,33 +1023,45 @@ class Scanner2(Scanner):
|
|||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# FIXME: All the < 2.7 conditions are is horrible. We need a better way.
|
# FIXME FIXME FIXME
|
||||||
|
# All the conditions are horrible, and I am not sure I
|
||||||
|
# undestand fully what's going l
|
||||||
|
# WeR REALLY REALLY need a better way to handle control flow
|
||||||
|
# Expecially for < 2.7
|
||||||
if label is not None and label != -1:
|
if label is not None and label != -1:
|
||||||
# In Python < 2.7, the POP_TOP in:
|
if self.version == 2.7:
|
||||||
# RETURN_VALUE, POP_TOP
|
# FIXME: rocky: I think we need something like this...
|
||||||
# does now start a new statement
|
if label in self.setup_loops:
|
||||||
# Otherwise, we have want to add a "COME_FROM"
|
source = self.setup_loops[label]
|
||||||
if not (self.version < 2.7 and
|
else:
|
||||||
code[label] == self.opc.POP_TOP and
|
source = offset
|
||||||
code[self.prev[label]] == self.opc.RETURN_VALUE):
|
targets[label] = targets.get(label, []) + [source]
|
||||||
|
elif not (code[label] == self.opc.POP_TOP and
|
||||||
|
code[self.prev[label]] == self.opc.RETURN_VALUE):
|
||||||
# In Python < 2.7, don't add a COME_FROM, for:
|
# In Python < 2.7, don't add a COME_FROM, for:
|
||||||
# JUMP_FORWARD, END_FINALLY
|
# RETURN_VALUE POP_TOP .. END_FINALLY
|
||||||
# or:
|
# or:
|
||||||
# JUMP_FORWARD, POP_TOP, END_FINALLY
|
# RETURN_VALUE POP_TOP .. POP_TOP END_FINALLY
|
||||||
if not (self.version < 2.7 and op == self.opc.JUMP_FORWARD
|
skip_come_from = False
|
||||||
and ((code[offset+3] == self.opc.END_FINALLY)
|
if self.version <= 2.1:
|
||||||
or (code[offset+3] == self.opc.POP_TOP
|
skip_come_from = (code[offset+3] == self.opc.END_FINALLY or
|
||||||
and code[offset+4] == self.opc.END_FINALLY))):
|
(code[offset+3] == self.opc.POP_TOP
|
||||||
|
and code[offset+4] == self.opc.END_FINALLY))
|
||||||
|
else:
|
||||||
|
skip_come_from = (code[offset+3] == self.opc.END_FINALLY or
|
||||||
|
(op != self.opc.JUMP_FORWARD
|
||||||
|
and code[offset+3] == self.opc.POP_TOP
|
||||||
|
and code[offset+4] == self.opc.END_FINALLY))
|
||||||
|
if not skip_come_from:
|
||||||
# FIXME: rocky: I think we need something like this...
|
# FIXME: rocky: I think we need something like this...
|
||||||
if offset not in set(self.ignore_if) or self.version == 2.7:
|
if offset not in set(self.ignore_if):
|
||||||
if label in self.setup_loops:
|
if label in self.setup_loops:
|
||||||
source = self.setup_loops[label]
|
source = self.setup_loops[label]
|
||||||
else:
|
else:
|
||||||
source = offset
|
source = offset
|
||||||
targets[label] = targets.get(label, []) + [source]
|
targets[label] = targets.get(label, []) + [source]
|
||||||
|
pass
|
||||||
pass
|
pass
|
||||||
|
|
||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
elif op == self.opc.END_FINALLY and offset in self.fixed_jumps and self.version == 2.7:
|
elif op == self.opc.END_FINALLY and offset in self.fixed_jumps and self.version == 2.7:
|
||||||
|
Reference in New Issue
Block a user