You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 16:59:52 +08:00
Start custom grammar for 2.6 and ...
fix a python 2.6.9 deparse with lc if+and+not
This commit is contained in:
BIN
test/bytecode_2.6/06_list_ifnot_and.pyc
Normal file
BIN
test/bytecode_2.6/06_list_ifnot_and.pyc
Normal file
Binary file not shown.
18
test/simple_source/comprehension/06_list_ifnot_and.py
Normal file
18
test/simple_source/comprehension/06_list_ifnot_and.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Bug from python2.6/SimpleXMLRPCServer.py
|
||||||
|
# The problem in 2.6 is handling
|
||||||
|
|
||||||
|
# 72 JUMP_ABSOLUTE 17 (to 17)
|
||||||
|
# 75 POP_TOP
|
||||||
|
# 76 JUMP_ABSOLUTE 17 (to 17)
|
||||||
|
|
||||||
|
# And getting:
|
||||||
|
# list_for ::= expr _for designator list_iter JUMP_BACK
|
||||||
|
# list_iter ::= list_if JUMP_BACK
|
||||||
|
# ^^^^^^^^^ added to 2.6 grammar
|
||||||
|
# list_iter ::= list_for
|
||||||
|
|
||||||
|
|
||||||
|
def list_public_methods(obj):
|
||||||
|
return [member for member in dir(obj)
|
||||||
|
if not member.startswith('_') and
|
||||||
|
hasattr(getattr(obj, member), '__call__')]
|
@@ -463,11 +463,21 @@ def get_python_parser(version, debug_parser, compile_mode='exec'):
|
|||||||
|
|
||||||
# FIXME: there has to be a better way...
|
# FIXME: there has to be a better way...
|
||||||
if version < 3.0:
|
if version < 3.0:
|
||||||
import uncompyle6.parsers.parse2 as parse2
|
if version == 2.6:
|
||||||
if compile_mode == 'exec':
|
import uncompyle6.parsers.parse26 as parse26
|
||||||
p = parse2.Python2Parser(debug_parser)
|
if compile_mode == 'exec':
|
||||||
|
p = parse26.Python26Parser(debug_parser)
|
||||||
|
else:
|
||||||
|
p = parse26.Python26ParserSingle(debug_parser)
|
||||||
else:
|
else:
|
||||||
p = parse2.Python2ParserSingle(debug_parser)
|
import uncompyle6.parsers.parse2 as parse2
|
||||||
|
if compile_mode == 'exec':
|
||||||
|
p = parse2.Python2Parser(debug_parser)
|
||||||
|
else:
|
||||||
|
p = parse2.Python2ParserSingle(debug_parser)
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
import uncompyle6.parsers.parse3 as parse3
|
import uncompyle6.parsers.parse3 as parse3
|
||||||
if version == 3.2:
|
if version == 3.2:
|
||||||
|
23
uncompyle6/parsers/parse26.py
Normal file
23
uncompyle6/parsers/parse26.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Copyright (c) 2016 Rocky Bernstein
|
||||||
|
"""
|
||||||
|
spark grammar differences over Python2 for Python 2.6.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from uncompyle6.parser import PythonParserSingle
|
||||||
|
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||||
|
from uncompyle6.parsers.parse2 import Python2Parser
|
||||||
|
|
||||||
|
class Python26Parser(Python2Parser):
|
||||||
|
|
||||||
|
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
|
||||||
|
super(Python26Parser, self).__init__(debug_parser)
|
||||||
|
self.customized = {}
|
||||||
|
|
||||||
|
|
||||||
|
def p_lis_iter(self, args):
|
||||||
|
'''
|
||||||
|
list_iter ::= list_if JUMP_BACK
|
||||||
|
'''
|
||||||
|
|
||||||
|
class Python26ParserSingle(Python2Parser, PythonParserSingle):
|
||||||
|
pass
|
@@ -513,11 +513,8 @@ class Scanner26(scan.Scanner2):
|
|||||||
if op in self.pop_jump_if:
|
if op in self.pop_jump_if:
|
||||||
target = self.get_argument(i)
|
target = self.get_argument(i)
|
||||||
target += i + 3
|
target += i + 3
|
||||||
|
|
||||||
self.restructJump(i, target)
|
self.restructJump(i, target)
|
||||||
if self.op_hasArgument(op) and op not in self.opc.hasArgumentExtended:
|
i += self.op_size(op)
|
||||||
i += 3
|
|
||||||
else: i += 1
|
|
||||||
|
|
||||||
i=0
|
i=0
|
||||||
while i < len(self.code): # we can't use op_range for the moment
|
while i < len(self.code): # we can't use op_range for the moment
|
||||||
@@ -527,9 +524,17 @@ class Scanner26(scan.Scanner2):
|
|||||||
if self.code[target] == self.opc.JA:
|
if self.code[target] == self.opc.JA:
|
||||||
target = self.get_target(target)
|
target = self.get_target(target)
|
||||||
self.restructJump(i, target)
|
self.restructJump(i, target)
|
||||||
if self.op_hasArgument(op) and op not in self.opc.hasArgumentExtended:
|
i += self.op_size(op)
|
||||||
i += 3
|
i=0
|
||||||
else: i += 1
|
# while i < len(self.code): # we can't use op_range for the moment
|
||||||
|
# op = self.code[i]
|
||||||
|
# name = self.opc.opname[op]
|
||||||
|
# if self.op_hasArgument(op):
|
||||||
|
# oparg = self.get_argument(i)
|
||||||
|
# print("%d %s %d" % (i, name, oparg))
|
||||||
|
# else:
|
||||||
|
# print("%d %s" % (i, name))
|
||||||
|
# i += self.op_size(op)
|
||||||
|
|
||||||
def restructJump(self, pos, newTarget):
|
def restructJump(self, pos, newTarget):
|
||||||
if self.code[pos] not in self.opc.hasjabs + self.opc.hasjrel:
|
if self.code[pos] not in self.opc.hasjabs + self.opc.hasjrel:
|
||||||
@@ -698,7 +703,9 @@ class Scanner26(scan.Scanner2):
|
|||||||
# is this an if and
|
# is this an if and
|
||||||
if op == self.opc.PJIF:
|
if op == self.opc.PJIF:
|
||||||
match = self.rem_or(start, self.next_stmt[pos], self.opc.PJIF, target)
|
match = self.rem_or(start, self.next_stmt[pos], self.opc.PJIF, target)
|
||||||
match = self.remove_mid_line_ifs(match)
|
## We can't remove mid-line ifs because line structures have changed
|
||||||
|
## from restructBytecode().
|
||||||
|
## match = self.remove_mid_line_ifs(match)
|
||||||
if match:
|
if match:
|
||||||
if (code[pre[rtarget]] in (self.opc.JF, self.opc.JA)
|
if (code[pre[rtarget]] in (self.opc.JF, self.opc.JA)
|
||||||
and pre[rtarget] not in self.stmts
|
and pre[rtarget] not in self.stmts
|
||||||
|
Reference in New Issue
Block a user