You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Better grammar specialization for Python 3
This commit is contained in:
@@ -554,6 +554,8 @@ class Python3Parser(PythonParser):
|
|||||||
this.
|
this.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
is_pypy = False
|
||||||
|
|
||||||
# For a rough break out on the first word. This may
|
# For a rough break out on the first word. This may
|
||||||
# include instructions that don't need customization,
|
# include instructions that don't need customization,
|
||||||
# but we'll do a finer check after the rough breakout.
|
# but we'll do a finer check after the rough breakout.
|
||||||
@@ -562,7 +564,19 @@ class Python3Parser(PythonParser):
|
|||||||
'JUMP', 'LOAD', 'LOOKUP', 'MAKE',
|
'JUMP', 'LOAD', 'LOOKUP', 'MAKE',
|
||||||
'RAISE', 'UNPACK'))
|
'RAISE', 'UNPACK'))
|
||||||
|
|
||||||
is_pypy = False
|
# Opcode names in the custom_ops_seen set have rules that get added
|
||||||
|
# unconditionally and the rules are constant. So they need to be done
|
||||||
|
# only once and if we see the opcode a second we don't have to consider
|
||||||
|
# adding more rules.
|
||||||
|
#
|
||||||
|
# Note: BUILD_TUPLE_UNPACK_WITH_CALL gets considered by
|
||||||
|
# default because it starts with BUILD. So we'll set to ignore it from
|
||||||
|
# the start.
|
||||||
|
custom_ops_seen = set(('BUILD_TUPLE_UNPACK_WITH_CALL',))
|
||||||
|
|
||||||
|
# In constrast to custom_ops_seen, seen_xxx rules here are part of some
|
||||||
|
# other rule; so if we see them a second time we still have to loop
|
||||||
|
# over customization
|
||||||
seen_LOAD_BUILD_CLASS = False
|
seen_LOAD_BUILD_CLASS = False
|
||||||
seen_GET_AWAITABLE_YIELD_FROM = False
|
seen_GET_AWAITABLE_YIELD_FROM = False
|
||||||
|
|
||||||
@@ -577,7 +591,6 @@ 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_lambda ::= ret_expr RETURN_VALUE_LAMBDA
|
|
||||||
stmt ::= conditional_lambda
|
stmt ::= conditional_lambda
|
||||||
conditional_lambda ::= expr jmp_false expr return_if_lambda
|
conditional_lambda ::= expr jmp_false expr return_if_lambda
|
||||||
return_lambda LAMBDA_MARKER
|
return_lambda LAMBDA_MARKER
|
||||||
@@ -602,7 +615,8 @@ class Python3Parser(PythonParser):
|
|||||||
|
|
||||||
# Do a quick breakout before testing potentially
|
# Do a quick breakout before testing potentially
|
||||||
# each of the dozen or so instruction in if elif.
|
# each of the dozen or so instruction in if elif.
|
||||||
if opname[:opname.find('_')] not in customize_instruction_basenames:
|
if (opname[:opname.find('_')] not in customize_instruction_basenames
|
||||||
|
or opname in custom_ops_seen):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
opname_base = opname[:opname.rfind('_')]
|
opname_base = opname[:opname.rfind('_')]
|
||||||
@@ -611,15 +625,15 @@ class Python3Parser(PythonParser):
|
|||||||
# This is in 3.6+
|
# This is in 3.6+
|
||||||
kvlist_n = 'expr ' * (token.attr)
|
kvlist_n = 'expr ' * (token.attr)
|
||||||
rule = "dict ::= %sLOAD_CONST %s" % (kvlist_n, opname)
|
rule = "dict ::= %sLOAD_CONST %s" % (kvlist_n, opname)
|
||||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
self.addRule(rule, nop_func)
|
||||||
elif opname.startswith('BUILD_LIST_UNPACK'):
|
elif opname.startswith('BUILD_LIST_UNPACK'):
|
||||||
v = token.attr
|
v = token.attr
|
||||||
rule = ('build_list_unpack ::= ' + 'expr1024 ' * int(v//1024) +
|
rule = ('build_list_unpack ::= ' + 'expr1024 ' * int(v//1024) +
|
||||||
'expr32 ' * int((v//32) % 32) +
|
'expr32 ' * int((v//32) % 32) +
|
||||||
'expr ' * (v % 32) + opname)
|
'expr ' * (v % 32) + opname)
|
||||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
self.addRule(rule, nop_func)
|
||||||
rule = 'expr ::= build_list_unpack'
|
rule = 'expr ::= build_list_unpack'
|
||||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
self.addRule(rule, nop_func)
|
||||||
elif opname_base == 'BUILD_MAP':
|
elif opname_base == 'BUILD_MAP':
|
||||||
kvlist_n = "kvlist_%s" % token.attr
|
kvlist_n = "kvlist_%s" % token.attr
|
||||||
if opname == 'BUILD_MAP_n':
|
if opname == 'BUILD_MAP_n':
|
||||||
@@ -660,8 +674,6 @@ class Python3Parser(PythonParser):
|
|||||||
rule = ('build_map_unpack_with_call ::= ' + 'expr1024 ' * int(v//1024) +
|
rule = ('build_map_unpack_with_call ::= ' + 'expr1024 ' * int(v//1024) +
|
||||||
'expr32 ' * int((v//32) % 32) +
|
'expr32 ' * int((v//32) % 32) +
|
||||||
'expr ' * (v % 32) + opname)
|
'expr ' * (v % 32) + opname)
|
||||||
elif opname.startswith('BUILD_TUPLE_UNPACK_WITH_CALL'):
|
|
||||||
continue
|
|
||||||
elif opname_base in ('BUILD_LIST', 'BUILD_SET', 'BUILD_TUPLE'):
|
elif opname_base in ('BUILD_LIST', 'BUILD_SET', 'BUILD_TUPLE'):
|
||||||
v = token.attr
|
v = token.attr
|
||||||
|
|
||||||
@@ -723,16 +735,19 @@ class Python3Parser(PythonParser):
|
|||||||
self.addRule("""
|
self.addRule("""
|
||||||
del_stmt ::= expr DELETE_ATTR
|
del_stmt ::= expr DELETE_ATTR
|
||||||
""", nop_func)
|
""", nop_func)
|
||||||
|
custom_ops_seen.add(opname)
|
||||||
elif opname == 'DELETE_DEREF':
|
elif opname == 'DELETE_DEREF':
|
||||||
self.addRule("""
|
self.addRule("""
|
||||||
stmt ::= del_deref_stmt
|
stmt ::= del_deref_stmt
|
||||||
del_deref_stmt ::= DELETE_DEREF
|
del_deref_stmt ::= DELETE_DEREF
|
||||||
""", nop_func)
|
""", nop_func)
|
||||||
|
custom_ops_seen.add(opname)
|
||||||
elif opname == 'DELETE_SUBSCR':
|
elif opname == 'DELETE_SUBSCR':
|
||||||
self.addRule("""
|
self.addRule("""
|
||||||
del_stmt ::= delete_subscr
|
del_stmt ::= delete_subscr
|
||||||
delete_subscr ::= expr expr DELETE_SUBSCR
|
delete_subscr ::= expr expr DELETE_SUBSCR
|
||||||
""", nop_func)
|
""", nop_func)
|
||||||
|
custom_ops_seen.add(opname)
|
||||||
elif opname == 'JUMP_IF_NOT_DEBUG':
|
elif opname == 'JUMP_IF_NOT_DEBUG':
|
||||||
v = token.attr
|
v = token.attr
|
||||||
self.addRule("""
|
self.addRule("""
|
||||||
@@ -747,19 +762,17 @@ class Python3Parser(PythonParser):
|
|||||||
LOAD_ASSERT expr CALL_FUNCTION_1
|
LOAD_ASSERT expr CALL_FUNCTION_1
|
||||||
RAISE_VARARGS_1 COME_FROM,
|
RAISE_VARARGS_1 COME_FROM,
|
||||||
""", nop_func)
|
""", nop_func)
|
||||||
continue
|
custom_ops_seen.add(opname)
|
||||||
elif opname == 'LOAD_BUILD_CLASS':
|
elif opname == 'LOAD_BUILD_CLASS':
|
||||||
seen_LOAD_BUILD_CLASS = True
|
seen_LOAD_BUILD_CLASS = True
|
||||||
self.custom_build_class_rule(opname, i, token, tokens, customize)
|
self.custom_build_class_rule(opname, i, token, tokens, customize)
|
||||||
elif opname == 'LOAD_CLASSDEREF':
|
elif opname == 'LOAD_CLASSDEREF':
|
||||||
# Python 3.4+
|
# Python 3.4+
|
||||||
self.add_unique_rule("expr ::= LOAD_CLASSDEREF",
|
self.addRule("expr ::= LOAD_CLASSDEREF", nop_func)
|
||||||
opname, token.attr, customize)
|
custom_ops_seen.add(opname)
|
||||||
continue
|
|
||||||
elif opname == 'LOAD_CLASSNAME':
|
elif opname == 'LOAD_CLASSNAME':
|
||||||
self.add_unique_rule("expr ::= LOAD_CLASSNAME",
|
self.addRule("expr ::= LOAD_CLASSNAME", nop_func)
|
||||||
opname, token.attr, customize)
|
custom_ops_seen.add(opname)
|
||||||
continue
|
|
||||||
elif opname == 'LOAD_DICTCOMP':
|
elif opname == 'LOAD_DICTCOMP':
|
||||||
if has_get_iter_call_function1:
|
if has_get_iter_call_function1:
|
||||||
rule_pat = ("dict_comp ::= LOAD_DICTCOMP %sMAKE_FUNCTION_0 expr "
|
rule_pat = ("dict_comp ::= LOAD_DICTCOMP %sMAKE_FUNCTION_0 expr "
|
||||||
@@ -771,16 +784,14 @@ class Python3Parser(PythonParser):
|
|||||||
elif opname == 'LOAD_SETCOMP':
|
elif opname == 'LOAD_SETCOMP':
|
||||||
# Should this be generalized and put under MAKE_FUNCTION?
|
# Should this be generalized and put under MAKE_FUNCTION?
|
||||||
if has_get_iter_call_function1:
|
if has_get_iter_call_function1:
|
||||||
self.add_unique_rule("expr ::= set_comp",
|
self.addRule("expr ::= set_comp", nop_func)
|
||||||
opname, token.attr, customize)
|
|
||||||
rule_pat = ("set_comp ::= LOAD_SETCOMP %sMAKE_FUNCTION_0 expr "
|
rule_pat = ("set_comp ::= LOAD_SETCOMP %sMAKE_FUNCTION_0 expr "
|
||||||
"GET_ITER CALL_FUNCTION_1")
|
"GET_ITER CALL_FUNCTION_1")
|
||||||
self.add_make_function_rule(rule_pat, opname, token.attr, customize)
|
self.add_make_function_rule(rule_pat, opname, token.attr, customize)
|
||||||
elif opname == 'LOOKUP_METHOD':
|
elif opname == 'LOOKUP_METHOD':
|
||||||
# A PyPy speciality - DRY with parse2
|
# A PyPy speciality - DRY with parse2
|
||||||
self.add_unique_rule("attribute ::= expr LOOKUP_METHOD",
|
self.addRule("attribute ::= expr LOOKUP_METHOD", nop_func)
|
||||||
opname, token.attr, customize)
|
custom_ops_seen.add(opname)
|
||||||
continue
|
|
||||||
elif opname.startswith('MAKE_CLOSURE'):
|
elif opname.startswith('MAKE_CLOSURE'):
|
||||||
# DRY with MAKE_FUNCTION
|
# DRY with MAKE_FUNCTION
|
||||||
# Note: this probably doesn't handle kwargs proprerly
|
# Note: this probably doesn't handle kwargs proprerly
|
||||||
@@ -963,34 +974,40 @@ class Python3Parser(PythonParser):
|
|||||||
rule = ('mkfunc_annotate ::= %s%sannotate_tuple LOAD_CONST EXTENDED_ARG %s' %
|
rule = ('mkfunc_annotate ::= %s%sannotate_tuple LOAD_CONST EXTENDED_ARG %s' %
|
||||||
(('pos_arg ' * (args_pos)),
|
(('pos_arg ' * (args_pos)),
|
||||||
('call ' * (annotate_args-1)), opname))
|
('call ' * (annotate_args-1)), opname))
|
||||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
self.addRule(rule, nop_func)
|
||||||
|
elif opname == 'RETURN_VALUE_LAMBDA':
|
||||||
|
self.addRule("""
|
||||||
|
return_lambda ::= ret_expr RETURN_VALUE_LAMBDA
|
||||||
|
""", nop_func)
|
||||||
|
custom_ops_seen.add(opname)
|
||||||
elif opname == 'RAISE_VARARGS_0':
|
elif opname == 'RAISE_VARARGS_0':
|
||||||
self.addRule("""
|
self.addRule("""
|
||||||
stmt ::= raise_stmt0
|
stmt ::= raise_stmt0
|
||||||
raise_stmt0 ::= RAISE_VARARGS_0
|
raise_stmt0 ::= RAISE_VARARGS_0
|
||||||
""", nop_func)
|
""", nop_func)
|
||||||
continue
|
custom_ops_seen.add(opname)
|
||||||
elif opname == 'RAISE_VARARGS_1':
|
elif opname == 'RAISE_VARARGS_1':
|
||||||
self.addRule("""
|
self.addRule("""
|
||||||
stmt ::= raise_stmt1
|
stmt ::= raise_stmt1
|
||||||
raise_stmt1 ::= expr RAISE_VARARGS_1
|
raise_stmt1 ::= expr RAISE_VARARGS_1
|
||||||
""", nop_func)
|
""", nop_func)
|
||||||
continue
|
custom_ops_seen.add(opname)
|
||||||
elif opname == 'RAISE_VARARGS_2':
|
elif opname == 'RAISE_VARARGS_2':
|
||||||
self.addRule("""
|
self.addRule("""
|
||||||
stmt ::= raise_stmt2
|
stmt ::= raise_stmt2
|
||||||
raise_stmt2 ::= expr expr RAISE_VARARGS_2
|
raise_stmt2 ::= expr expr RAISE_VARARGS_2
|
||||||
""", nop_func)
|
""", nop_func)
|
||||||
continue
|
custom_ops_seen.add(opname)
|
||||||
elif opname_base in ('UNPACK_EX',):
|
elif opname_base in ('UNPACK_EX',):
|
||||||
before_count, after_count = token.attr
|
before_count, after_count = token.attr
|
||||||
rule = 'unpack ::= ' + opname + ' store' * (before_count + after_count + 1)
|
rule = 'unpack ::= ' + opname + ' store' * (before_count + after_count + 1)
|
||||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
self.addRule(rule, nop_func)
|
||||||
elif opname_base in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
|
elif opname_base in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'):
|
||||||
rule = 'unpack ::= ' + opname + ' store' * token.attr
|
rule = 'unpack ::= ' + opname + ' store' * token.attr
|
||||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
self.addRule(rule, nop_func)
|
||||||
elif opname_base == 'UNPACK_LIST':
|
elif opname_base == 'UNPACK_LIST':
|
||||||
rule = 'unpack_list ::= ' + opname + ' store' * token.attr
|
rule = 'unpack_list ::= ' + opname + ' store' * token.attr
|
||||||
|
self.addRule(rule, nop_func)
|
||||||
self.check_reduce['aug_assign1'] = 'AST'
|
self.check_reduce['aug_assign1'] = 'AST'
|
||||||
self.check_reduce['aug_assign2'] = 'AST'
|
self.check_reduce['aug_assign2'] = 'AST'
|
||||||
self.check_reduce['while1stmt'] = 'noAST'
|
self.check_reduce['while1stmt'] = 'noAST'
|
||||||
|
Reference in New Issue
Block a user