You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 09:22:40 +08:00
Add pop return check from decompyle3
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2017-2020, 2022-2023 Rocky Bernstein
|
# Copyright (c) 2017-2020, 2022-2024 Rocky Bernstein
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,9 +17,12 @@ spark grammar differences over Python 3.7 for Python 3.8
|
|||||||
"""
|
"""
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
from uncompyle6.parser import PythonParserSingle, nop_func
|
|
||||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||||
|
|
||||||
|
from uncompyle6.parser import PythonParserSingle, nop_func
|
||||||
from uncompyle6.parsers.parse37 import Python37Parser
|
from uncompyle6.parsers.parse37 import Python37Parser
|
||||||
|
from uncompyle6.parsers.reducecheck.pop_return import pop_return_check
|
||||||
|
|
||||||
|
|
||||||
class Python38Parser(Python37Parser):
|
class Python38Parser(Python37Parser):
|
||||||
def p_38_stmt(self, args):
|
def p_38_stmt(self, args):
|
||||||
@@ -362,13 +365,24 @@ class Python38Parser(Python37Parser):
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
def customize_grammar_rules(self, tokens, customize):
|
def customize_reduce_checks_full38(self, tokens, customize):
|
||||||
super(Python37Parser, self).customize_grammar_rules(tokens, customize)
|
"""
|
||||||
|
Extra tests when a reduction is made in the full grammar.
|
||||||
|
|
||||||
|
Reductions here are extended from those used in the lambda grammar
|
||||||
|
"""
|
||||||
self.remove_rules_38()
|
self.remove_rules_38()
|
||||||
|
self.check_reduce["pop_return"] = "tokens"
|
||||||
self.check_reduce["whileTruestmt38"] = "tokens"
|
self.check_reduce["whileTruestmt38"] = "tokens"
|
||||||
self.check_reduce["whilestmt38"] = "tokens"
|
self.check_reduce["whilestmt38"] = "tokens"
|
||||||
self.check_reduce["try_elsestmtl38"] = "AST"
|
self.check_reduce["try_elsestmtl38"] = "AST"
|
||||||
|
|
||||||
|
self.reduce_check_table["pop_return"] = pop_return_check
|
||||||
|
|
||||||
|
def customize_grammar_rules(self, tokens, customize):
|
||||||
|
super(Python37Parser, self).customize_grammar_rules(tokens, customize)
|
||||||
|
self.customize_reduce_checks_full38(tokens, customize)
|
||||||
|
|
||||||
# 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.
|
||||||
@@ -423,11 +437,7 @@ class Python38Parser(Python37Parser):
|
|||||||
# Determine if we have an iteration CALL_FUNCTION_1.
|
# Determine if we have an iteration CALL_FUNCTION_1.
|
||||||
has_get_iter_call_function1 = False
|
has_get_iter_call_function1 = False
|
||||||
for i, token in enumerate(tokens):
|
for i, token in enumerate(tokens):
|
||||||
if (
|
if token == "GET_ITER" and i < n - 2 and tokens[i + 1] == "CALL_FUNCTION_1":
|
||||||
token == "GET_ITER"
|
|
||||||
and i < n - 2
|
|
||||||
and tokens[i + 1] == "CALL_FUNCTION_1"
|
|
||||||
):
|
|
||||||
has_get_iter_call_function1 = True
|
has_get_iter_call_function1 = True
|
||||||
|
|
||||||
for i, token in enumerate(tokens):
|
for i, token in enumerate(tokens):
|
||||||
@@ -577,14 +587,10 @@ class Python38Parser(Python37Parser):
|
|||||||
"""
|
"""
|
||||||
self.addRule(rule, nop_func)
|
self.addRule(rule, nop_func)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def reduce_is_invalid(self, rule, ast, tokens, first, last):
|
def reduce_is_invalid(self, rule, ast, tokens, first, last):
|
||||||
invalid = super(Python38Parser,
|
invalid = super(Python38Parser, self).reduce_is_invalid(
|
||||||
self).reduce_is_invalid(rule, ast,
|
rule, ast, tokens, first, last
|
||||||
tokens, first, last)
|
)
|
||||||
self.remove_rules_38()
|
self.remove_rules_38()
|
||||||
if invalid:
|
if invalid:
|
||||||
return invalid
|
return invalid
|
||||||
@@ -612,7 +618,7 @@ if __name__ == "__main__":
|
|||||||
p = Python38Parser()
|
p = Python38Parser()
|
||||||
p.remove_rules_38()
|
p.remove_rules_38()
|
||||||
p.check_grammar()
|
p.check_grammar()
|
||||||
from xdis.version_info import PYTHON_VERSION_TRIPLE, IS_PYPY
|
from xdis.version_info import IS_PYPY, PYTHON_VERSION_TRIPLE
|
||||||
|
|
||||||
if PYTHON_VERSION_TRIPLE[:2] == (3, 8):
|
if PYTHON_VERSION_TRIPLE[:2] == (3, 8):
|
||||||
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
lhs, rhs, tokens, right_recursive, dup_rhs = p.check_sets()
|
||||||
@@ -635,7 +641,9 @@ if __name__ == "__main__":
|
|||||||
remain_tokens = set(remain_tokens) - opcode_set
|
remain_tokens = set(remain_tokens) - opcode_set
|
||||||
print(remain_tokens)
|
print(remain_tokens)
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
from spark_parser.spark import rule2str
|
from spark_parser.spark import rule2str
|
||||||
|
|
||||||
for rule in sorted(p.rule2name.items()):
|
for rule in sorted(p.rule2name.items()):
|
||||||
print(rule2str(rule[0]))
|
print(rule2str(rule[0]))
|
||||||
|
10
uncompyle6/parsers/reducecheck/pop_return.py
Normal file
10
uncompyle6/parsers/reducecheck/pop_return.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Copyright (c) 2020 Rocky Bernstein
|
||||||
|
|
||||||
|
|
||||||
|
def pop_return_check(
|
||||||
|
self, lhs: str, n: int, rule, ast, tokens: list, first: int, last: int
|
||||||
|
) -> bool:
|
||||||
|
# If the first instruction of return_expr (the instruction after POP_TOP) is
|
||||||
|
# has a linestart, then the POP_TOP was probably part of the previous
|
||||||
|
# statement, such as a call() where the return value is discarded.
|
||||||
|
return tokens[first + 1].linestart
|
Reference in New Issue
Block a user