Fix Python 1.5- bug in handling unpack list

This commit is contained in:
rocky
2018-06-04 10:32:55 -04:00
parent 7fd21aa227
commit 096563cf91
8 changed files with 50 additions and 3 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,3 @@
# Python 1.4 tzparse.py, but also appears in 1.5
[tzname, delta] = __file__

View File

@@ -13,6 +13,7 @@ class Python14Parser(Python15Parser):
# SET_FUNC_ARGS, and RESERVE_FAST # SET_FUNC_ARGS, and RESERVE_FAST
# FIXME: should check that this indeed around __doc__ # FIXME: should check that this indeed around __doc__
# Possibly not strictly needed
stmt ::= doc_junk stmt ::= doc_junk
doc_junk ::= LOAD_CONST POP_TOP doc_junk ::= LOAD_CONST POP_TOP
@@ -35,6 +36,26 @@ class Python14Parser(Python15Parser):
super(Python14Parser, self).__init__(debug_parser) super(Python14Parser, self).__init__(debug_parser)
self.customized = {} self.customized = {}
def customize_grammar_rules(self, tokens, customize):
super(Python14Parser, self).customize_grammar_rules(tokens, customize)
self.remove_rules("""
whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt
jb_pop
POP_BLOCK else_suitel COME_FROM
""")
self.check_reduce['doc_junk'] = 'tokens'
def reduce_is_invalid(self, rule, ast, tokens, first, last):
invalid = super(Python14Parser,
self).reduce_is_invalid(rule, ast,
tokens, first, last)
if invalid or tokens is None:
return invalid
if rule[0] == 'doc_junk':
return not isinstance(tokens[first].pattr, str)
class Python14ParserSingle(Python14Parser, PythonParserSingle): class Python14ParserSingle(Python14Parser, PythonParserSingle):
pass pass

View File

@@ -2,7 +2,7 @@
# Copyright (c) 2000-2002 by hartmut Goebel <hartmut@goebel.noris.de> # Copyright (c) 2000-2002 by hartmut Goebel <hartmut@goebel.noris.de>
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 from uncompyle6.parser import PythonParserSingle, nop_func
from uncompyle6.parsers.parse21 import Python21Parser from uncompyle6.parsers.parse21 import Python21Parser
class Python15Parser(Python21Parser): class Python15Parser(Python21Parser):
@@ -23,6 +23,17 @@ class Python15Parser(Python21Parser):
importlist ::= IMPORT_FROM importlist ::= IMPORT_FROM
""" """
def customize_grammar_rules(self, tokens, customize):
super(Python15Parser, self).customize_grammar_rules(tokens, customize)
for i, token in enumerate(tokens):
opname = token.kind
opname_base = opname[:opname.rfind('_')]
if opname_base == 'UNPACK_LIST':
self.addRule("store ::= unpack_list", nop_func)
class Python15ParserSingle(Python15Parser, PythonParserSingle): class Python15ParserSingle(Python15Parser, PythonParserSingle):
pass pass

View File

@@ -294,7 +294,6 @@ class Python2Parser(PythonParser):
# The order of opname listed is roughly sorted below # The order of opname listed is roughly sorted below
if opname_base in ('BUILD_LIST', 'BUILD_SET', 'BUILD_TUPLE'): if opname_base in ('BUILD_LIST', 'BUILD_SET', 'BUILD_TUPLE'):
v = token.attr
collection = opname_base[opname_base.find('_')+1:].lower() collection = opname_base[opname_base.find('_')+1:].lower()
rule = '%s ::= %s%s' % (collection, (token.attr * 'expr '), opname) rule = '%s ::= %s%s' % (collection, (token.attr * 'expr '), opname)
self.add_unique_rules([ self.add_unique_rules([
@@ -395,7 +394,6 @@ class Python2Parser(PythonParser):
""", nop_func) """, nop_func)
continue continue
elif opname == 'JUMP_IF_NOT_DEBUG': elif opname == 'JUMP_IF_NOT_DEBUG':
v = token.attr
self.addRule(""" self.addRule("""
jmp_true_false ::= POP_JUMP_IF_TRUE jmp_true_false ::= POP_JUMP_IF_TRUE
jmp_true_false ::= POP_JUMP_IF_FALSE jmp_true_false ::= POP_JUMP_IF_FALSE

View File

@@ -25,3 +25,17 @@ class Scanner15(scan.Scanner21):
self.version = 1.5 self.version = 1.5
self.genexpr_name = '<generator expression>' self.genexpr_name = '<generator expression>'
return return
def ingest(self, co, classname=None, code_objects={}, show_asm=None):
"""
Pick out tokens from an uncompyle6 code object, and transform them,
returning a list of uncompyle6 Token's.
The transformations are made to assist the deparsing grammar.
"""
tokens, customize = scan.Scanner21.ingest(self, co, classname, code_objects, show_asm)
for t in tokens:
if t.op == self.opc.UNPACK_LIST:
t.kind = 'UNPACK_LIST_%d' % t.attr
pass
return tokens, customize