From 97ce330b000471006afafe4e83793eed1c68bd04 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 10 Oct 2016 11:55:39 -0400 Subject: [PATCH] Python 1.5 scanner and parser and .. .. slightly improved Forgot to check in files before. Handle Python pre 2.2. classes --- uncompyle6/parsers/parse15.py | 36 +++++++++++++++++++++++++++++ uncompyle6/scanners/scanner15.py | 27 ++++++++++++++++++++++ uncompyle6/semantics/pysource.py | 39 +++++++++++++++++++++----------- 3 files changed, 89 insertions(+), 13 deletions(-) create mode 100644 uncompyle6/parsers/parse15.py create mode 100644 uncompyle6/scanners/scanner15.py diff --git a/uncompyle6/parsers/parse15.py b/uncompyle6/parsers/parse15.py new file mode 100644 index 00000000..fb2e8b14 --- /dev/null +++ b/uncompyle6/parsers/parse15.py @@ -0,0 +1,36 @@ +# Copyright (c) 2016 Rocky Bernstein +# Copyright (c) 2000-2002 by hartmut Goebel + +from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG +from uncompyle6.parser import PythonParserSingle +from uncompyle6.parsers.parse21 import Python21Parser + +class Python15Parser(Python21Parser): + + def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG): + super(Python15Parser, self).__init__(debug_parser) + self.customized = {} + + def p_import15(self, args): + """ + importstmt ::= filler IMPORT_NAME STORE_FAST + importstmt ::= filler IMPORT_NAME STORE_NAME + + importfrom ::= filler IMPORT_NAME importlist + importfrom ::= filler filler IMPORT_NAME importlist POP_TOP + + importlist ::= importlist IMPORT_FROM + importlist ::= IMPORT_FROM + """ + +class Python15ParserSingle(Python21Parser, PythonParserSingle): + pass + +if __name__ == '__main__': + # Check grammar + p = Python15Parser() + p.checkGrammar() + p.dumpGrammar() + +# local variables: +# tab-width: 4 diff --git a/uncompyle6/scanners/scanner15.py b/uncompyle6/scanners/scanner15.py new file mode 100644 index 00000000..b5681234 --- /dev/null +++ b/uncompyle6/scanners/scanner15.py @@ -0,0 +1,27 @@ +# Copyright (c) 2016 by Rocky Bernstein +""" +Python 1.5 bytecode scanner/deparser + +This massages tokenized 1.5 bytecode to make it more amenable for +grammar parsing. +""" + +import uncompyle6.scanners.scanner21 as scan +# from uncompyle6.scanners.scanner26 import ingest as ingest26 + +# bytecode verification, verify(), uses JUMP_OPs from here +from xdis.opcodes import opcode_15 +JUMP_OPs = opcode_15.JUMP_OPs + +# We base this off of 2.2 instead of the other way around +# because we cleaned things up this way. +# The history is that 2.7 support is the cleanest, +# then from that we got 2.6 and so on. +class Scanner15(scan.Scanner21): + def __init__(self, show_asm=False): + scan.Scanner21.__init__(self, show_asm) + self.opc = opcode_15 + self.opname = opcode_15.opname + self.version = 1.5 + self.genexpr_name = ''; + return diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 1689224e..83f349f0 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -263,7 +263,6 @@ TABLE_DIRECT = { 'classdefdeco1': ( '%|@%c\n%c', 0, 1), 'kwarg': ( '%[0]{pattr}=%c', 1), 'kwargs': ( '%D', (0, maxint, ', ') ), - 'importlist2': ( '%C', (0, maxint, ', ') ), 'assert_expr_or': ( '%c or %c', 0, 2 ), 'assert_expr_and': ( '%c and %c', 0, 2 ), @@ -560,19 +559,27 @@ class SourceWalker(GenericASTTraversal, object): }) - if 2.0 <= version <= 2.3: + if version < 2.0: TABLE_DIRECT.update({ - 'tryfinallystmt': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n', 1, 4 ) + 'importlist': ( '%C', (0, maxint, ', ') ), + }) + else: + TABLE_DIRECT.update({ + 'importlist2': ( '%C', (0, maxint, ', ') ), + }) + if version <= 2.3: + TABLE_DIRECT.update({ + 'tryfinallystmt': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n', 1, 4 ) }) - elif version >= 2.5: - ######################## - # Import style for 2.5+ - ######################## - TABLE_DIRECT.update({ - 'importmultiple': ( '%|import %c%c\n', 2, 3 ), - 'import_cont' : ( ', %c', 2 ), - }) + elif version >= 2.5: + ######################## + # Import style for 2.5+ + ######################## + TABLE_DIRECT.update({ + 'importmultiple': ( '%|import %c%c\n', 2, 3 ), + 'import_cont' : ( ', %c', 2 ), + }) ######################################## # Python 2.6+ @@ -1551,7 +1558,11 @@ class SourceWalker(GenericASTTraversal, object): if not (node == 'build_list'): return - self.write('(') + n_subclasses = len(node[:-1]) + if n_subclasses > 0 or self.version > 2.1: + # Not an old-style pre-2.2 class + self.write('(') + line_separator = ', ' sep = '' for elem in node[:-1]: @@ -1559,7 +1570,9 @@ class SourceWalker(GenericASTTraversal, object): self.write(sep, value) sep = line_separator - self.write(')') + if n_subclasses > 0 or self.version > 2.1: + # Not an old-style pre-2.2 class + self.write(')') def print_super_classes3(self, node): n = len(node)-1