blacken (reformat) a parser.py

This commit is contained in:
rocky
2020-01-18 05:23:16 -05:00
parent af7b05922f
commit eacc3f5cc7

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2015-2019 Rocky Bernstein # Copyright (c) 2015-2020 Rocky Bernstein
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org> # Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com> # Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
# Copyright (c) 1999 John Aycock # Copyright (c) 1999 John Aycock
@@ -28,21 +28,24 @@ from xdis.magics import py_str2float
from spark_parser import GenericASTBuilder, DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from spark_parser import GenericASTBuilder, DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from uncompyle6.show import maybe_show_asm from uncompyle6.show import maybe_show_asm
class ParserError(Exception): class ParserError(Exception):
def __init__(self, token, offset): def __init__(self, token, offset):
self.token = token self.token = token
self.offset = offset self.offset = offset
def __str__(self): def __str__(self):
return "Parse error at or near `%r' instruction at offset %s\n" % \ return "Parse error at or near `%r' instruction at offset %s\n" % (
(self.token, self.offset) self.token,
self.offset,
)
def nop_func(self, args): def nop_func(self, args):
return None return None
class PythonParser(GenericASTBuilder):
class PythonParser(GenericASTBuilder):
def __init__(self, SyntaxTree, start, debug): def __init__(self, SyntaxTree, start, debug):
super(PythonParser, self).__init__(SyntaxTree, start, debug) super(PythonParser, self).__init__(SyntaxTree, start, debug)
# FIXME: customize per python parser version # FIXME: customize per python parser version
@@ -52,24 +55,32 @@ class PythonParser(GenericASTBuilder):
# stmts -> stmts stmt -> stmts stmt stmt ... # stmts -> stmts stmt -> stmts stmt stmt ...
# collect as stmts -> stmt stmt ... # collect as stmts -> stmt stmt ...
nt_list = [ nt_list = [
'stmts', 'except_stmts', '_stmts', 'attributes', "l_stmts", "_come_froms",
'exprlist', 'kvlist', 'kwargs', 'come_froms', '_come_froms', "_stmts",
'importlist', "attributes",
"come_froms",
"except_stmts",
"exprlist",
"importlist",
"kvlist",
"kwargs",
"l_stmts",
"stmts",
# Python < 3 # Python < 3
'print_items', "print_items",
# PyPy: # PyPy:
'imports_cont', "imports_cont",
'kvlist_n', "kvlist_n",
# Python 3.6+ # Python 3.6+
'come_from_loops', "come_from_loops",
# Python 3.7+ # Python 3.7+
'importlist37', "importlist37",
] ]
self.collect = frozenset(nt_list) self.collect = frozenset(nt_list)
# For these items we need to keep the 1st epslion reduction since # For these items we need to keep the 1st epslion reduction since
# the nonterminal name is used in a semantic action. # the nonterminal name is used in a semantic action.
self.keep_epsilon = frozenset(('kvlist_n', 'kvlist')) self.keep_epsilon = frozenset(("kvlist_n", "kvlist"))
# ??? Do we need a debug option to skip eliding singleton reductions? # ??? Do we need a debug option to skip eliding singleton reductions?
# Time will tell if it if useful in debugging # Time will tell if it if useful in debugging
@@ -77,20 +88,22 @@ class PythonParser(GenericASTBuilder):
# FIXME: optional_nt is a misnomer. It's really about there being a # FIXME: optional_nt is a misnomer. It's really about there being a
# singleton reduction that we can simplify. It also happens to be optional # singleton reduction that we can simplify. It also happens to be optional
# in its other derivation # in its other derivation
self.optional_nt |= frozenset(('come_froms', 'suite_stmts', 'l_stmts_opt', self.optional_nt |= frozenset(
'c_stmts_opt')) ("come_froms", "suite_stmts", "l_stmts_opt", "c_stmts_opt")
)
# Reduce singleton reductions in these nonterminals: # Reduce singleton reductions in these nonterminals:
# FIXME: would love to do expr, sstmts, stmts and # FIXME: would love to do expr, sstmts, stmts and
# so on but that would require major changes to the # so on but that would require major changes to the
# semantic actions # semantic actions
self.singleton = frozenset(('str', 'store', '_stmts', 'suite_stmts_opt', self.singleton = frozenset(
'inplace_op')) ("str", "store", "_stmts", "suite_stmts_opt", "inplace_op")
)
# Instructions filled in from scanner # Instructions filled in from scanner
self.insts = [] self.insts = []
def ast_first_offset(self, ast): def ast_first_offset(self, ast):
if hasattr(ast, 'offset'): if hasattr(ast, "offset"):
return ast.offset return ast.offset
else: else:
return self.ast_first_offset(ast[0]) return self.ast_first_offset(ast[0])
@@ -103,6 +116,7 @@ class PythonParser(GenericASTBuilder):
many arguments it has. Often it is not used. many arguments it has. Often it is not used.
""" """
if rule not in self.new_rules: if rule not in self.new_rules:
# print("XXX ", rule) # debug
self.new_rules.add(rule) self.new_rules.add(rule)
self.addRule(rule, nop_func) self.addRule(rule, nop_func)
customize[opname] = arg_count customize[opname] = arg_count
@@ -117,7 +131,7 @@ class PythonParser(GenericASTBuilder):
for rule in rules: for rule in rules:
if len(rule) == 0: if len(rule) == 0:
continue continue
opname = rule.split('::=')[0].strip() opname = rule.split("::=")[0].strip()
self.add_unique_rule(rule, opname, 0, customize) self.add_unique_rule(rule, opname, 0, customize)
return return
@@ -145,49 +159,52 @@ class PythonParser(GenericASTBuilder):
"""Customized format and print for our kind of tokens """Customized format and print for our kind of tokens
which gets called in debugging grammar reduce rules which gets called in debugging grammar reduce rules
""" """
def fix(c): def fix(c):
s = str(c) s = str(c)
last_token_pos = s.find('_') last_token_pos = s.find("_")
if last_token_pos == -1: if last_token_pos == -1:
return s return s
else: else:
return s[:last_token_pos] return s[:last_token_pos]
prefix = '' prefix = ""
if parent and tokens: if parent and tokens:
p_token = tokens[parent] p_token = tokens[parent]
if hasattr(p_token, 'linestart') and p_token.linestart: if hasattr(p_token, "linestart") and p_token.linestart:
prefix = 'L.%3d: ' % p_token.linestart prefix = "L.%3d: " % p_token.linestart
else: else:
prefix = ' ' prefix = " "
if hasattr(p_token, 'offset'): if hasattr(p_token, "offset"):
prefix += "%3s" % fix(p_token.offset) prefix += "%3s" % fix(p_token.offset)
if len(rule[1]) > 1: if len(rule[1]) > 1:
prefix += '-%-3s ' % fix(tokens[last_token_pos-1].offset) prefix += "-%-3s " % fix(tokens[last_token_pos - 1].offset)
else: else:
prefix += ' ' prefix += " "
else: else:
prefix = ' ' prefix = " "
print("%s%s ::= %s (%d)" % (prefix, rule[0], ' '.join(rule[1]), last_token_pos)) print("%s%s ::= %s (%d)" % (prefix, rule[0], " ".join(rule[1]), last_token_pos))
def error(self, instructions, index): def error(self, instructions, index):
# Find the last line boundary # Find the last line boundary
start, finish = -1, -1 start, finish = -1, -1
for start in range(index, -1, -1): for start in range(index, -1, -1):
if instructions[start].linestart: break if instructions[start].linestart:
break
pass pass
for finish in range(index+1, len(instructions)): for finish in range(index + 1, len(instructions)):
if instructions[finish].linestart: break if instructions[finish].linestart:
break
pass pass
if start > 0: if start > 0:
err_token = instructions[index] err_token = instructions[index]
print("Instruction context:") print("Instruction context:")
for i in range(start, finish): for i in range(start, finish):
if i != index: if i != index:
indent = ' ' indent = " "
else: else:
indent = '-> ' indent = "-> "
print("%s%s" % (indent, instructions[i])) print("%s%s" % (indent, instructions[i]))
raise ParserError(err_token, err_token.offset) raise ParserError(err_token, err_token.offset)
else: else:
@@ -198,8 +215,8 @@ class PythonParser(GenericASTBuilder):
represented by the attr field of token""" represented by the attr field of token"""
# Low byte indicates number of positional paramters, # Low byte indicates number of positional paramters,
# high byte number of keyword parameters # high byte number of keyword parameters
args_pos = token.attr & 0xff args_pos = token.attr & 0xFF
args_kw = (token.attr >> 8) & 0xff args_kw = (token.attr >> 8) & 0xFF
return args_pos, args_kw return args_pos, args_kw
def nonterminal(self, nt, args): def nonterminal(self, nt, args):
@@ -215,7 +232,7 @@ class PythonParser(GenericASTBuilder):
# stmts -> stmts stmt -> stmts stmt -> ... # stmts -> stmts stmt -> stmts stmt -> ...
# stmms -> stmt stmt ... # stmms -> stmt stmt ...
# #
if not hasattr(args[0], 'append'): if not hasattr(args[0], "append"):
# Was in self.optional_nt as a single item, but we find we have # Was in self.optional_nt as a single item, but we find we have
# more than one now... # more than one now...
rv = GenericASTBuilder.nonterminal(self, nt, [args[0]]) rv = GenericASTBuilder.nonterminal(self, nt, [args[0]])
@@ -230,7 +247,7 @@ class PythonParser(GenericASTBuilder):
rv.append(args[1]) rv.append(args[1])
elif n == 1 and args[0] in self.singleton: elif n == 1 and args[0] in self.singleton:
rv = GenericASTBuilder.nonterminal(self, nt, args[0]) rv = GenericASTBuilder.nonterminal(self, nt, args[0])
del args[0] # save memory del args[0] # save memory
elif n == 1 and nt in self.optional_nt: elif n == 1 and nt in self.optional_nt:
rv = args[0] rv = args[0]
else: else:
@@ -243,10 +260,10 @@ class PythonParser(GenericASTBuilder):
return GenericASTBuilder.ambiguity(self, children) return GenericASTBuilder.ambiguity(self, children)
def resolve(self, list): def resolve(self, list):
if len(list) == 2 and 'function_def' in list and 'assign' in list: if len(list) == 2 and "function_def" in list and "assign" in list:
return 'function_def' return "function_def"
if 'grammar' in list and 'expr' in list: if "grammar" in list and "expr" in list:
return 'expr' return "expr"
# print >> sys.stderr, 'resolve', str(list) # print >> sys.stderr, 'resolve', str(list)
return GenericASTBuilder.resolve(self, list) return GenericASTBuilder.resolve(self, list)
@@ -254,17 +271,17 @@ class PythonParser(GenericASTBuilder):
# Common Python 2 and Python 3 grammar rules # # Common Python 2 and Python 3 grammar rules #
############################################### ###############################################
def p_start(self, args): def p_start(self, args):
''' """
# The start or goal symbol # The start or goal symbol
stmts ::= sstmt+ stmts ::= sstmt+
''' """
def p_call_stmt(self, args): def p_call_stmt(self, args):
''' """
# eval-mode compilation. Single-mode interactive compilation # eval-mode compilation. Single-mode interactive compilation
# adds another rule. # adds another rule.
call_stmt ::= expr POP_TOP call_stmt ::= expr POP_TOP
''' """
def p_stmt(self, args): def p_stmt(self, args):
""" """
@@ -354,7 +371,7 @@ class PythonParser(GenericASTBuilder):
pass pass
def p_function_def(self, args): def p_function_def(self, args):
''' """
stmt ::= function_def stmt ::= function_def
function_def ::= mkfunc store function_def ::= mkfunc store
stmt ::= function_def_deco stmt ::= function_def_deco
@@ -364,15 +381,15 @@ class PythonParser(GenericASTBuilder):
mkfuncdeco0 ::= mkfunc mkfuncdeco0 ::= mkfunc
load_closure ::= load_closure LOAD_CLOSURE load_closure ::= load_closure LOAD_CLOSURE
load_closure ::= LOAD_CLOSURE load_closure ::= LOAD_CLOSURE
''' """
def p_generator_exp(self, args): def p_generator_exp(self, args):
''' """
expr ::= generator_exp expr ::= generator_exp
stmt ::= genexpr_func stmt ::= genexpr_func
genexpr_func ::= LOAD_FAST FOR_ITER store comp_iter JUMP_BACK genexpr_func ::= LOAD_FAST FOR_ITER store comp_iter JUMP_BACK
''' """
def p_jump(self, args): def p_jump(self, args):
""" """
@@ -392,7 +409,7 @@ class PythonParser(GenericASTBuilder):
""" """
def p_augmented_assign(self, args): def p_augmented_assign(self, args):
''' """
stmt ::= aug_assign1 stmt ::= aug_assign1
stmt ::= aug_assign2 stmt ::= aug_assign2
@@ -418,10 +435,10 @@ class PythonParser(GenericASTBuilder):
inplace_op ::= INPLACE_AND inplace_op ::= INPLACE_AND
inplace_op ::= INPLACE_XOR inplace_op ::= INPLACE_XOR
inplace_op ::= INPLACE_OR inplace_op ::= INPLACE_OR
''' """
def p_assign(self, args): def p_assign(self, args):
''' """
stmt ::= assign stmt ::= assign
assign ::= expr DUP_TOP designList assign ::= expr DUP_TOP designList
assign ::= expr store assign ::= expr store
@@ -430,7 +447,7 @@ class PythonParser(GenericASTBuilder):
stmt ::= assign3 stmt ::= assign3
assign2 ::= expr expr ROT_TWO store store assign2 ::= expr expr ROT_TWO store store
assign3 ::= expr expr expr ROT_THREE ROT_TWO store store store assign3 ::= expr expr expr ROT_THREE ROT_TWO store store store
''' """
def p_forstmt(self, args): def p_forstmt(self, args):
""" """
@@ -611,8 +628,8 @@ def parse(p, tokens, customize):
def get_python_parser( def get_python_parser(
version, debug_parser=PARSER_DEFAULT_DEBUG, compile_mode='exec', version, debug_parser=PARSER_DEFAULT_DEBUG, compile_mode="exec", is_pypy=False
is_pypy = False): ):
"""Returns parser object for Python version 2 or 3, 3.2, 3.5on, """Returns parser object for Python version 2 or 3, 3.2, 3.5on,
etc., depending on the parameters passed. *compile_mode* is either etc., depending on the parameters passed. *compile_mode* is either
'exec', 'eval', or 'single'. See 'exec', 'eval', or 'single'. See
@@ -633,91 +650,106 @@ def get_python_parser(
if version < 2.2: if version < 2.2:
if version == 1.0: if version == 1.0:
import uncompyle6.parsers.parse10 as parse10 import uncompyle6.parsers.parse10 as parse10
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse10.Python10Parser(debug_parser) p = parse10.Python10Parser(debug_parser)
else: else:
p = parse10.Python01ParserSingle(debug_parser) p = parse10.Python01ParserSingle(debug_parser)
elif version == 1.1: elif version == 1.1:
import uncompyle6.parsers.parse11 as parse11 import uncompyle6.parsers.parse11 as parse11
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse11.Python11Parser(debug_parser) p = parse11.Python11Parser(debug_parser)
else: else:
p = parse11.Python11ParserSingle(debug_parser) p = parse11.Python11ParserSingle(debug_parser)
if version == 1.2: if version == 1.2:
import uncompyle6.parsers.parse12 as parse12 import uncompyle6.parsers.parse12 as parse12
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse12.Python12Parser(debug_parser) p = parse12.Python12Parser(debug_parser)
else: else:
p = parse12.Python12ParserSingle(debug_parser) p = parse12.Python12ParserSingle(debug_parser)
if version == 1.3: if version == 1.3:
import uncompyle6.parsers.parse13 as parse13 import uncompyle6.parsers.parse13 as parse13
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse13.Python13Parser(debug_parser) p = parse13.Python13Parser(debug_parser)
else: else:
p = parse13.Python13ParserSingle(debug_parser) p = parse13.Python13ParserSingle(debug_parser)
elif version == 1.4: elif version == 1.4:
import uncompyle6.parsers.parse14 as parse14 import uncompyle6.parsers.parse14 as parse14
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse14.Python14Parser(debug_parser) p = parse14.Python14Parser(debug_parser)
else: else:
p = parse14.Python14ParserSingle(debug_parser) p = parse14.Python14ParserSingle(debug_parser)
elif version == 1.5: elif version == 1.5:
import uncompyle6.parsers.parse15 as parse15 import uncompyle6.parsers.parse15 as parse15
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse15.Python15Parser(debug_parser) p = parse15.Python15Parser(debug_parser)
else: else:
p = parse15.Python15ParserSingle(debug_parser) p = parse15.Python15ParserSingle(debug_parser)
elif version == 1.6: elif version == 1.6:
import uncompyle6.parsers.parse16 as parse16 import uncompyle6.parsers.parse16 as parse16
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse16.Python16Parser(debug_parser) p = parse16.Python16Parser(debug_parser)
else: else:
p = parse16.Python16ParserSingle(debug_parser) p = parse16.Python16ParserSingle(debug_parser)
elif version == 2.1: elif version == 2.1:
import uncompyle6.parsers.parse21 as parse21 import uncompyle6.parsers.parse21 as parse21
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse21.Python21Parser(debug_parser) p = parse21.Python21Parser(debug_parser)
else: else:
p = parse21.Python21ParserSingle(debug_parser) p = parse21.Python21ParserSingle(debug_parser)
elif version == 2.2: elif version == 2.2:
import uncompyle6.parsers.parse22 as parse22 import uncompyle6.parsers.parse22 as parse22
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse22.Python22Parser(debug_parser) p = parse22.Python22Parser(debug_parser)
else: else:
p = parse22.Python22ParserSingle(debug_parser) p = parse22.Python22ParserSingle(debug_parser)
elif version == 2.3: elif version == 2.3:
import uncompyle6.parsers.parse23 as parse23 import uncompyle6.parsers.parse23 as parse23
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse23.Python23Parser(debug_parser) p = parse23.Python23Parser(debug_parser)
else: else:
p = parse23.Python23ParserSingle(debug_parser) p = parse23.Python23ParserSingle(debug_parser)
elif version == 2.4: elif version == 2.4:
import uncompyle6.parsers.parse24 as parse24 import uncompyle6.parsers.parse24 as parse24
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse24.Python24Parser(debug_parser) p = parse24.Python24Parser(debug_parser)
else: else:
p = parse24.Python24ParserSingle(debug_parser) p = parse24.Python24ParserSingle(debug_parser)
elif version == 2.5: elif version == 2.5:
import uncompyle6.parsers.parse25 as parse25 import uncompyle6.parsers.parse25 as parse25
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse25.Python25Parser(debug_parser) p = parse25.Python25Parser(debug_parser)
else: else:
p = parse25.Python25ParserSingle(debug_parser) p = parse25.Python25ParserSingle(debug_parser)
elif version == 2.6: elif version == 2.6:
import uncompyle6.parsers.parse26 as parse26 import uncompyle6.parsers.parse26 as parse26
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse26.Python26Parser(debug_parser) p = parse26.Python26Parser(debug_parser)
else: else:
p = parse26.Python26ParserSingle(debug_parser) p = parse26.Python26ParserSingle(debug_parser)
elif version == 2.7: elif version == 2.7:
import uncompyle6.parsers.parse27 as parse27 import uncompyle6.parsers.parse27 as parse27
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse27.Python27Parser(debug_parser) p = parse27.Python27Parser(debug_parser)
else: else:
p = parse27.Python27ParserSingle(debug_parser) p = parse27.Python27ParserSingle(debug_parser)
else: else:
import uncompyle6.parsers.parse2 as parse2 import uncompyle6.parsers.parse2 as parse2
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse2.Python2Parser(debug_parser) p = parse2.Python2Parser(debug_parser)
else: else:
p = parse2.Python2ParserSingle(debug_parser) p = parse2.Python2ParserSingle(debug_parser)
@@ -726,62 +758,72 @@ def get_python_parser(
pass pass
else: else:
import uncompyle6.parsers.parse3 as parse3 import uncompyle6.parsers.parse3 as parse3
if version == 3.0: if version == 3.0:
import uncompyle6.parsers.parse30 as parse30 import uncompyle6.parsers.parse30 as parse30
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse30.Python30Parser(debug_parser) p = parse30.Python30Parser(debug_parser)
else: else:
p = parse30.Python30ParserSingle(debug_parser) p = parse30.Python30ParserSingle(debug_parser)
elif version == 3.1: elif version == 3.1:
import uncompyle6.parsers.parse31 as parse31 import uncompyle6.parsers.parse31 as parse31
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse31.Python31Parser(debug_parser) p = parse31.Python31Parser(debug_parser)
else: else:
p = parse31.Python31ParserSingle(debug_parser) p = parse31.Python31ParserSingle(debug_parser)
elif version == 3.2: elif version == 3.2:
import uncompyle6.parsers.parse32 as parse32 import uncompyle6.parsers.parse32 as parse32
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse32.Python32Parser(debug_parser) p = parse32.Python32Parser(debug_parser)
else: else:
p = parse32.Python32ParserSingle(debug_parser) p = parse32.Python32ParserSingle(debug_parser)
elif version == 3.3: elif version == 3.3:
import uncompyle6.parsers.parse33 as parse33 import uncompyle6.parsers.parse33 as parse33
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse33.Python33Parser(debug_parser) p = parse33.Python33Parser(debug_parser)
else: else:
p = parse33.Python33ParserSingle(debug_parser) p = parse33.Python33ParserSingle(debug_parser)
elif version == 3.4: elif version == 3.4:
import uncompyle6.parsers.parse34 as parse34 import uncompyle6.parsers.parse34 as parse34
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse34.Python34Parser(debug_parser) p = parse34.Python34Parser(debug_parser)
else: else:
p = parse34.Python34ParserSingle(debug_parser) p = parse34.Python34ParserSingle(debug_parser)
elif version == 3.5: elif version == 3.5:
import uncompyle6.parsers.parse35 as parse35 import uncompyle6.parsers.parse35 as parse35
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse35.Python35Parser(debug_parser) p = parse35.Python35Parser(debug_parser)
else: else:
p = parse35.Python35ParserSingle(debug_parser) p = parse35.Python35ParserSingle(debug_parser)
elif version == 3.6: elif version == 3.6:
import uncompyle6.parsers.parse36 as parse36 import uncompyle6.parsers.parse36 as parse36
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse36.Python36Parser(debug_parser) p = parse36.Python36Parser(debug_parser)
else: else:
p = parse36.Python36ParserSingle(debug_parser) p = parse36.Python36ParserSingle(debug_parser)
elif version == 3.7: elif version == 3.7:
import uncompyle6.parsers.parse37 as parse37 import uncompyle6.parsers.parse37 as parse37
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse37.Python37Parser(debug_parser) p = parse37.Python37Parser(debug_parser)
else: else:
p = parse37.Python37ParserSingle(debug_parser) p = parse37.Python37ParserSingle(debug_parser)
elif version == 3.8: elif version == 3.8:
import uncompyle6.parsers.parse38 as parse38 import uncompyle6.parsers.parse38 as parse38
if compile_mode == 'exec':
if compile_mode == "exec":
p = parse38.Python38Parser(debug_parser) p = parse38.Python38Parser(debug_parser)
else: else:
p = parse38.Python38ParserSingle(debug_parser) p = parse38.Python38ParserSingle(debug_parser)
else: else:
if compile_mode == 'exec': if compile_mode == "exec":
p = parse3.Python3Parser(debug_parser) p = parse3.Python3Parser(debug_parser)
else: else:
p = parse3.Python3ParserSingle(debug_parser) p = parse3.Python3ParserSingle(debug_parser)
@@ -789,18 +831,25 @@ def get_python_parser(
# p.dump_grammar() # debug # p.dump_grammar() # debug
return p return p
class PythonParserSingle(PythonParser): class PythonParserSingle(PythonParser):
def p_call_stmt_single(self, args): def p_call_stmt_single(self, args):
''' """
# single-mode compilation. Eval-mode interactive compilation # single-mode compilation. Eval-mode interactive compilation
# drops the last rule. # drops the last rule.
call_stmt ::= expr PRINT_EXPR call_stmt ::= expr PRINT_EXPR
''' """
def python_parser(version, co, out=sys.stdout, showasm=False, def python_parser(
parser_debug=PARSER_DEFAULT_DEBUG, is_pypy=False): version,
co,
out=sys.stdout,
showasm=False,
parser_debug=PARSER_DEFAULT_DEBUG,
is_pypy=False,
):
""" """
Parse a code object to an abstract syntax tree representation. Parse a code object to an abstract syntax tree representation.
@@ -817,6 +866,7 @@ def python_parser(version, co, out=sys.stdout, showasm=False,
assert iscode(co) assert iscode(co)
from uncompyle6.scanner import get_scanner from uncompyle6.scanner import get_scanner
scanner = get_scanner(version, is_pypy) scanner = get_scanner(version, is_pypy)
tokens, customize = scanner.ingest(co) tokens, customize = scanner.ingest(co)
maybe_show_asm(showasm, tokens) maybe_show_asm(showasm, tokens)
@@ -828,10 +878,13 @@ def python_parser(version, co, out=sys.stdout, showasm=False,
return parse(p, tokens, customize) return parse(p, tokens, customize)
if __name__ == '__main__': if __name__ == "__main__":
def parse_test(co): def parse_test(co):
from uncompyle6 import PYTHON_VERSION, IS_PYPY from uncompyle6 import PYTHON_VERSION, IS_PYPY
ast = python_parser(PYTHON_VERSION, co, showasm=True, is_pypy=IS_PYPY) ast = python_parser(PYTHON_VERSION, co, showasm=True, is_pypy=IS_PYPY)
print(ast) print(ast)
return return
parse_test(parse_test.__code__) parse_test(parse_test.__code__)