diff --git a/uncompyle6/parser.py b/uncompyle6/parser.py index d17d8190..f897e2d5 100644 --- a/uncompyle6/parser.py +++ b/uncompyle6/parser.py @@ -603,11 +603,12 @@ def get_python_parser( p = parse34.Python34Parser(debug_parser) else: p = parse34.Python34ParserSingle(debug_parser) - elif version >= 3.5: + elif version == 3.5: + import uncompyle6.parsers.parse35 as parse35 if compile_mode == 'exec': - p = parse3.Python35onParser(debug_parser) + p = parse35.Python35Parser(debug_parser) else: - p = parse3.Python35onParserSingle(debug_parser) + p = parse35.Python35ParserSingle(debug_parser) else: if compile_mode == 'exec': p = parse3.Python3Parser(debug_parser) diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 926704b9..a51ad1b9 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -631,49 +631,6 @@ class Python33Parser(Python3Parser): yield_from ::= expr expr YIELD_FROM """ -class Python35onParser(Python3Parser): - def p_35on(self, args): - """ - # Python 3.5+ has WITH_CLEANUP_START/FINISH - - withstmt ::= expr SETUP_WITH exprlist suite_stmts_opt - POP_BLOCK LOAD_CONST COME_FROM - WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY - - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt - POP_BLOCK LOAD_CONST COME_FROM - WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY - - withasstmt ::= expr SETUP_WITH designator suite_stmts_opt - POP_BLOCK LOAD_CONST COME_FROM - WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY - - inplace_op ::= INPLACE_MATRIX_MULTIPLY - binary_op ::= BINARY_MATRIX_MULTIPLY - - # Python 3.5+ does jump optimization - # In <.3.5 the below is a JUMP_FORWARD to a JUMP_ABSOLUTE. - # in return_stmt, we will need the semantic actions in pysource.py - # to work out whether to dedent or not based on the presence of - # RETURN_END_IF vs RETURN_VALUE - - ifelsestmtc ::= testexpr c_stmts_opt JUMP_FORWARD else_suitec - return_stmt ::= ret_expr RETURN_END_IF - - - # Python 3.3+ also has yield from. 3.5 does it - # differently than 3.3, 3.4 - - expr ::= yield_from - yield_from ::= expr GET_YIELD_FROM_ITER LOAD_CONST YIELD_FROM - - # Python 3.4+ has more loop optimization that removes - # JUMP_FORWARD in some cases, and hence we also don't - # see COME_FROM - _ifstmts_jump ::= c_stmts_opt - - """ - class Python3ParserSingle(Python3Parser, PythonParserSingle): pass @@ -685,18 +642,15 @@ class Python32ParserSingle(Python32Parser, PythonParserSingle): class Python33ParserSingle(Python33Parser, PythonParserSingle): pass -class Python35onParserSingle(Python35onParser, PythonParserSingle): - pass - def info(args): # Check grammar # Should also add a way to dump grammar - import sys p = Python3Parser() if len(args) > 0: arg = args[0] if arg == '3.5': - p = Python35onParser() + from uncompyle6.parser.parse35 import Python35Parser + p = Python35Parser() elif arg == '3.3': p = Python33Parser() elif arg == '3.2': diff --git a/uncompyle6/parsers/parse35.py b/uncompyle6/parsers/parse35.py new file mode 100644 index 00000000..5a328197 --- /dev/null +++ b/uncompyle6/parsers/parse35.py @@ -0,0 +1,80 @@ +# Copyright (c) 2016 Rocky Bernstein +""" +spark grammar differences over Python3 for Python 3.5. +""" +from __future__ import print_function + +from uncompyle6.parser import PythonParserSingle +from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG +from uncompyle6.parsers.parse3 import Python3Parser + +class Python35Parser(Python3Parser): + + def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG): + super(Python35Parser, self).__init__(debug_parser) + self.customized = {} + + def p_35on(self, args): + """ + # Python 3.5+ has WITH_CLEANUP_START/FINISH + + withstmt ::= expr SETUP_WITH exprlist suite_stmts_opt + POP_BLOCK LOAD_CONST COME_FROM + WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY + + withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt + POP_BLOCK LOAD_CONST COME_FROM + WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY + + withasstmt ::= expr SETUP_WITH designator suite_stmts_opt + POP_BLOCK LOAD_CONST COME_FROM + WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY + + inplace_op ::= INPLACE_MATRIX_MULTIPLY + binary_op ::= BINARY_MATRIX_MULTIPLY + + # Python 3.5+ does jump optimization + # In <.3.5 the below is a JUMP_FORWARD to a JUMP_ABSOLUTE. + # in return_stmt, we will need the semantic actions in pysource.py + # to work out whether to dedent or not based on the presence of + # RETURN_END_IF vs RETURN_VALUE + + ifelsestmtc ::= testexpr c_stmts_opt JUMP_FORWARD else_suitec + return_stmt ::= ret_expr RETURN_END_IF + + + # Python 3.3+ also has yield from. 3.5 does it + # differently than 3.3, 3.4 + + expr ::= yield_from + yield_from ::= expr GET_YIELD_FROM_ITER LOAD_CONST YIELD_FROM + + # Python 3.4+ has more loop optimization that removes + # JUMP_FORWARD in some cases, and hence we also don't + # see COME_FROM + _ifstmts_jump ::= c_stmts_opt + """ +class Python35ParserSingle(Python35Parser, PythonParserSingle): + pass + +if __name__ == '__main__': + # Check grammar + p = Python35Parser() + p.checkGrammar() + from uncompyle6 import PYTHON_VERSION, IS_PYPY + if PYTHON_VERSION == 3.5: + lhs, rhs, tokens, right_recursive = p.checkSets() + from uncompyle6.scanner import get_scanner + s = get_scanner(PYTHON_VERSION, IS_PYPY) + opcode_set = set(s.opc.opname).union(set( + """JUMP_BACK CONTINUE RETURN_END_IF COME_FROM + LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME + LAMBDA_MARKER RETURN_LAST + """.split())) + remain_tokens = set(tokens) - opcode_set + import re + remain_tokens = set([re.sub('_\d+$','', t) for t in remain_tokens]) + remain_tokens = set([re.sub('_CONT$','', t) for t in remain_tokens]) + remain_tokens = set(remain_tokens) - opcode_set + print(remain_tokens) + # print(sorted(p.rule2name.items()))