| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- # Copyright (c) 2018, 2022 Rocky Bernstein
- from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
- from uncompyle6.parser import PythonParserSingle, nop_func
- from uncompyle6.parsers.parse15 import Python15Parser
- class Python14Parser(Python15Parser):
- def p_misc14(self, args):
- """
- # Not much here yet, but will probably need to add UNARY_CALL,
- # LOAD_LOCAL, SET_FUNC_ARGS
- args ::= RESERVE_FAST UNPACK_ARG args_store
- args_store ::= STORE_FAST*
- call ::= expr tuple BINARY_CALL
- expr ::= call
- kv ::= DUP_TOP expr ROT_TWO LOAD_CONST STORE_SUBSCR
- mkfunc ::= LOAD_CODE BUILD_FUNCTION
- print_expr_stmt ::= expr PRINT_EXPR
- raise_stmt2 ::= expr expr RAISE_EXCEPTION
- star_args ::= RESERVE_FAST UNPACK_VARARG_1 args_store
- stmt ::= args
- stmt ::= print_expr_stmt
- stmt ::= star_args
- stmt ::= varargs
- varargs ::= RESERVE_FAST UNPACK_VARARG_0 args_store
- # Not strictly needed, but tidies up output
- stmt ::= doc_junk
- doc_junk ::= LOAD_CONST POP_TOP
- # Not sure why later Python's omit the COME_FROM
- jb_pop14 ::= JUMP_BACK COME_FROM POP_TOP
- whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt
- jb_pop14
- POP_BLOCK else_suitel COME_FROM
- print_items_nl_stmt ::= expr PRINT_ITEM_CONT print_items_opt PRINT_NEWLINE_CONT
- # 1.4 doesn't have linenotab, and although this shouldn't
- # be a show stopper, our CONTINUE detection is off here.
- continue ::= JUMP_BACK
- """
- def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
- super(Python14Parser, self).__init__(debug_parser)
- 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"
- for i, token in enumerate(tokens):
- opname = token.kind
- opname_base = opname[:opname.rfind("_")]
- if opname_base == "UNPACK_VARARG":
- if token.attr > 1:
- self.addRule(f"star_args ::= RESERVE_FAST {opname} args_store", nop_func)
- 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):
- pass
- if __name__ == '__main__':
- # Check grammar
- p = Python14Parser()
- p.check_grammar()
- p.dump_grammar()
- # local variables:
- # tab-width: 4
|