You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
158 lines
7.1 KiB
Python
158 lines
7.1 KiB
Python
# Copyright (c) 2016-2017 Rocky Bernstein
|
|
"""
|
|
spark grammar differences over Python 3.1 for Python 3.0.
|
|
"""
|
|
from __future__ import print_function
|
|
|
|
from uncompyle6.parser import PythonParserSingle
|
|
from uncompyle6.parsers.parse31 import Python31Parser
|
|
|
|
class Python30Parser(Python31Parser):
|
|
|
|
def p_30(self, args):
|
|
"""
|
|
|
|
assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1 COME_FROM POP_TOP
|
|
return_if_lambda ::= RETURN_END_IF_LAMBDA COME_FROM POP_TOP
|
|
compare_chained2 ::= expr COMPARE_OP RETURN_END_IF_LAMBDA
|
|
|
|
# FIXME: combine with parse3.2
|
|
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK
|
|
COME_FROM_LOOP
|
|
whileTruestmt ::= SETUP_LOOP returns
|
|
COME_FROM_LOOP
|
|
|
|
# In many ways Python 3.0 code generation is more like Python 2.6 than
|
|
# it is 2.7 or 3.1. So we have a number of 2.6ish (and before) rules below
|
|
# Specifically POP_TOP is more prevelant since there is no POP_JUMP_IF_...
|
|
# instructions
|
|
|
|
_ifstmts_jump ::= c_stmts JUMP_FORWARD _come_froms POP_TOP COME_FROM
|
|
_ifstmts_jump ::= c_stmts COME_FROM POP_TOP
|
|
|
|
# Used to keep index order the same in semantic actions
|
|
jb_pop_top ::= JUMP_BACK _come_froms POP_TOP
|
|
|
|
while1stmt ::= SETUP_LOOP l_stmts COME_FROM_LOOP
|
|
whileelsestmt ::= SETUP_LOOP testexpr l_stmts
|
|
jb_pop_top POP_BLOCK
|
|
else_suitel COME_FROM_LOOP
|
|
# while1elsestmt ::= SETUP_LOOP l_stmts
|
|
# jb_pop_top POP_BLOCK
|
|
# else_suitel COME_FROM_LOOP
|
|
|
|
else_suitel ::= l_stmts COME_FROM_LOOP JUMP_BACK
|
|
|
|
ifelsestmtl ::= testexpr c_stmts_opt jb_pop_top else_suitel
|
|
iflaststmtl ::= testexpr c_stmts_opt jb_pop_top
|
|
iflaststmt ::= testexpr c_stmts_opt JUMP_ABSOLUTE COME_FROM POP_TOP
|
|
|
|
withasstmt ::= expr setupwithas store suite_stmts_opt
|
|
POP_BLOCK LOAD_CONST COME_FROM_FINALLY
|
|
LOAD_FAST DELETE_FAST WITH_CLEANUP END_FINALLY
|
|
setupwithas ::= DUP_TOP LOAD_ATTR STORE_FAST LOAD_ATTR CALL_FUNCTION_0 setup_finally
|
|
setup_finally ::= STORE_FAST SETUP_FINALLY LOAD_FAST DELETE_FAST
|
|
|
|
# Need to keep LOAD_FAST as index 1
|
|
set_comp_func_header ::= BUILD_SET_0 DUP_TOP STORE_FAST
|
|
set_comp_func ::= set_comp_func_header
|
|
LOAD_FAST FOR_ITER store comp_iter
|
|
JUMP_BACK POP_TOP JUMP_BACK RETURN_VALUE RETURN_LAST
|
|
|
|
list_comp_header ::= BUILD_LIST_0 DUP_TOP STORE_FAST
|
|
list_comp ::= list_comp_header
|
|
LOAD_FAST FOR_ITER store comp_iter
|
|
JUMP_BACK
|
|
|
|
set_comp_header ::= BUILD_SET_0 DUP_TOP STORE_FAST
|
|
set_comp ::= set_comp_header
|
|
LOAD_FAST FOR_ITER store comp_iter
|
|
JUMP_BACK
|
|
|
|
dict_comp_header ::= BUILD_MAP_0 DUP_TOP STORE_FAST
|
|
dict_comp ::= dict_comp_header
|
|
LOAD_FAST FOR_ITER store dict_comp_iter
|
|
JUMP_BACK
|
|
|
|
dict_comp_iter ::= expr expr ROT_TWO expr STORE_SUBSCR
|
|
|
|
# JUMP_IF_TRUE POP_TOP as a replacement
|
|
comp_if ::= expr jmp_false comp_iter
|
|
comp_if ::= expr jmp_false comp_iter JUMP_BACK COME_FROM POP_TOP
|
|
comp_if_not ::= expr jmp_true comp_iter JUMP_BACK COME_FROM POP_TOP
|
|
comp_iter ::= expr expr SET_ADD
|
|
comp_iter ::= expr expr LIST_APPEND
|
|
|
|
jump_forward_else ::= JUMP_FORWARD COME_FROM POP_TOP
|
|
jump_absolute_else ::= JUMP_ABSOLUTE COME_FROM POP_TOP
|
|
except_suite ::= c_stmts POP_EXCEPT jump_except POP_TOP
|
|
except_suite_finalize ::= SETUP_FINALLY c_stmts_opt except_var_finalize END_FINALLY
|
|
_jump COME_FROM POP_TOP
|
|
jump_except ::= JUMP_FORWARD COME_FROM POP_TOP
|
|
jump_except ::= JUMP_ABSOLUTE COME_FROM POP_TOP
|
|
or ::= expr jmp_false expr jmp_true expr
|
|
or ::= expr jmp_true expr
|
|
|
|
################################################################################
|
|
# In many ways 3.0 is like 2.6. One similarity is there is no JUMP_IF_TRUE and
|
|
# JUMP_IF_FALSE
|
|
# The below rules in fact are the same or similar.
|
|
|
|
jmp_true ::= JUMP_IF_TRUE POP_TOP
|
|
jmp_false ::= JUMP_IF_FALSE _come_froms POP_TOP
|
|
|
|
for_block ::= l_stmts_opt _come_froms POP_TOP JUMP_BACK
|
|
|
|
except_handler ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts
|
|
POP_TOP END_FINALLY come_froms
|
|
except_handler ::= jmp_abs COME_FROM_EXCEPT except_stmts
|
|
POP_TOP END_FINALLY
|
|
|
|
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
|
|
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
|
|
compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP
|
|
jmp_false compare_chained2 _come_froms
|
|
compare_chained2 ::= expr COMPARE_OP RETURN_END_IF
|
|
"""
|
|
|
|
def customize_grammar_rules(self, tokens, customize):
|
|
super(Python30Parser, self).customize_grammar_rules(tokens, customize)
|
|
self.remove_rules("""
|
|
iflaststmtl ::= testexpr c_stmts_opt JUMP_BACK COME_FROM_LOOP
|
|
ifelsestmtl ::= testexpr c_stmts_opt JUMP_BACK else_suitel
|
|
iflaststmt ::= testexpr c_stmts_opt JUMP_ABSOLUTE
|
|
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD _come_froms
|
|
jump_forward_else ::= JUMP_FORWARD ELSE
|
|
jump_absolute_else ::= JUMP_ABSOLUTE ELSE
|
|
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt COME_FROM JUMP_BACK POP_BLOCK
|
|
COME_FROM_LOOP
|
|
whilestmt ::= SETUP_LOOP testexpr returns
|
|
POP_BLOCK COME_FROM_LOOP
|
|
assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1
|
|
return_if_lambda ::= RETURN_END_IF_LAMBDA
|
|
except_suite ::= c_stmts POP_EXCEPT jump_except
|
|
whileelsestmt ::= SETUP_LOOP testexpr l_stmts JUMP_BACK POP_BLOCK
|
|
else_suitel COME_FROM_LOOP
|
|
|
|
# No JUMP_IF_FALSE_OR_POP
|
|
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
|
|
""")
|
|
|
|
return
|
|
pass
|
|
|
|
class Python30ParserSingle(Python30Parser, PythonParserSingle):
|
|
pass
|