Simplify scanner2 so it relies less on custimize dict

This commit is contained in:
rocky
2017-12-13 21:01:58 -05:00
parent aac793af09
commit 303e134359
2 changed files with 24 additions and 43 deletions

View File

@@ -250,23 +250,21 @@ class Python2Parser(PythonParser):
JUMP_BACK JUMP_BACK
""", nop_func) """, nop_func)
# Refactor the FIXME below and use the list below # For a rough break out on the first word. This may
# # For a rough break out on the first word. This may # include instructions that don't need customization,
# # include instructions that don't need customization, # but we'll do a finer check after the rough breakout.
# # but we'll do a finer check after the rough breakout. customize_instruction_basenames = frozenset(
# customize_instruction_basenames = frozenset( ('BUILD', 'CALL', 'CONTINUE',
# ('BUILD', 'CALL', 'CONTINUE_LOOP', 'DELETE', 'DELETE', 'DUP', 'EXEC', 'JUMP',
# 'EXEC_STMT', 'JUMP', 'LOAD', 'LOOKUP', 'LOAD', 'LOOKUP', 'MAKE', 'SETUP',
# 'MAKE', 'SETUP_EXCEPT', 'SETUP_FINALLY', 'RAISE', 'UNPACK'))
# 'UNPACK'))
for i, token in enumerate(tokens): for i, token in enumerate(tokens):
opname = token.kind opname = token.kind
# FIXME: remove the "v" thing in the code below if opname[:opname.find('_')] not in customize_instruction_basenames:
if opname in customize:
v = customize[opname]
else:
continue continue
opname_base = opname[:opname.rfind('_')] opname_base = opname[:opname.rfind('_')]
# The order of opname listed is roughly sorted below # The order of opname listed is roughly sorted below
@@ -304,9 +302,9 @@ class Python2Parser(PythonParser):
'dictcomp_func', 0, customize) 'dictcomp_func', 0, customize)
else: else:
kvlist_n = "kvlist_%s" % v kvlist_n = "kvlist_%s" % token.attr
self.add_unique_rules([ self.add_unique_rules([
(kvlist_n + " ::=" + ' kv3' * v), (kvlist_n + " ::=" + ' kv3' * token.attr),
"dict ::= %s %s" % (opname, kvlist_n) "dict ::= %s %s" % (opname, kvlist_n)
], customize) ], customize)
continue continue
@@ -344,8 +342,7 @@ class Python2Parser(PythonParser):
rule = 'call ::= expr ' + 'expr '*args_pos + 'kwarg '*args_kw \ rule = 'call ::= expr ' + 'expr '*args_pos + 'kwarg '*args_kw \
+ 'expr ' * nak + opname + 'expr ' * nak + opname
elif opname == 'CONTINUE_LOOP': elif opname == 'CONTINUE_LOOP':
self.add_unique_rule('continue ::= CONTINUE_LOOP', self.addRule('continue ::= CONTINUE_LOOP', nop_func)
opname, v, customize)
continue continue
elif opname_base in ('DUP_TOPX', 'RAISE_VARARGS'): elif opname_base in ('DUP_TOPX', 'RAISE_VARARGS'):
# FIXME: remove these conditions if they are not needed. # FIXME: remove these conditions if they are not needed.
@@ -390,28 +387,26 @@ class Python2Parser(PythonParser):
opname, token.attr, customize) opname, token.attr, customize)
continue continue
elif opname_base == 'MAKE_FUNCTION': elif opname_base == 'MAKE_FUNCTION':
# FIXME: remove v here
if i > 0 and tokens[i-1] == 'LOAD_LAMBDA': if i > 0 and tokens[i-1] == 'LOAD_LAMBDA':
self.addRule('mklambda ::= %s LOAD_LAMBDA %s' % self.addRule('mklambda ::= %s LOAD_LAMBDA %s' %
('pos_arg '*v, opname), nop_func) ('pos_arg ' * token.attr, opname), nop_func)
rule = 'mkfunc ::= %s LOAD_CONST %s' % ('expr '*v, opname) rule = 'mkfunc ::= %s LOAD_CONST %s' % ('expr ' * token.attr, opname)
elif opname_base == 'MAKE_CLOSURE': elif opname_base == 'MAKE_CLOSURE':
# FIXME: remove v here
# FIXME: use add_unique_rules to tidy this up. # FIXME: use add_unique_rules to tidy this up.
if i > 0 and tokens[i-1] == 'LOAD_LAMBDA': if i > 0 and tokens[i-1] == 'LOAD_LAMBDA':
self.addRule('mklambda ::= %s load_closure LOAD_LAMBDA %s' % self.addRule('mklambda ::= %s load_closure LOAD_LAMBDA %s' %
('expr '*v, opname), nop_func) ('expr ' * token.attr, opname), nop_func)
if i > 0: if i > 0:
prev_tok = tokens[i-1] prev_tok = tokens[i-1]
if prev_tok == 'LOAD_GENEXPR': if prev_tok == 'LOAD_GENEXPR':
self.add_unique_rules([ self.add_unique_rules([
('generator_exp ::= %s load_closure LOAD_GENEXPR %s expr' ('generator_exp ::= %s load_closure LOAD_GENEXPR %s expr'
' GET_ITER CALL_FUNCTION_1' % ' GET_ITER CALL_FUNCTION_1' %
('expr '*v, opname))], customize) ('expr ' * token.attr, opname))], customize)
pass pass
self.add_unique_rules([ self.add_unique_rules([
('mkfunc ::= %s load_closure LOAD_CONST %s' % ('mkfunc ::= %s load_closure LOAD_CONST %s' %
('expr '*v, opname))], customize) ('expr '* token.attr, opname))], customize)
if self.version >= 2.7: if self.version >= 2.7:
if i > 0: if i > 0:
@@ -420,13 +415,13 @@ class Python2Parser(PythonParser):
self.add_unique_rules([ self.add_unique_rules([
('dict_comp ::= %s load_closure LOAD_DICTCOMP %s expr' ('dict_comp ::= %s load_closure LOAD_DICTCOMP %s expr'
' GET_ITER CALL_FUNCTION_1' % ' GET_ITER CALL_FUNCTION_1' %
('expr '*v, opname))], customize) ('expr ' * token.attr, opname))], customize)
elif prev_tok == 'LOAD_SETCOMP': elif prev_tok == 'LOAD_SETCOMP':
self.add_unique_rules([ self.add_unique_rules([
"expr ::= set_comp", "expr ::= set_comp",
('set_comp ::= %s load_closure LOAD_SETCOMP %s expr' ('set_comp ::= %s load_closure LOAD_SETCOMP %s expr'
' GET_ITER CALL_FUNCTION_1' % ' GET_ITER CALL_FUNCTION_1' %
('expr '*v, opname)) ('expr ' * token.attr, opname))
], customize) ], customize)
pass pass
pass pass
@@ -456,7 +451,7 @@ class Python2Parser(PythonParser):
elif opname_base == 'UNPACK_LIST': elif opname_base == 'UNPACK_LIST':
rule = 'unpack_list ::= ' + opname + ' store' * token.attr rule = 'unpack_list ::= ' + opname + ' store' * token.attr
else: else:
raise Exception('unknown customize token %s' % opname) continue
self.addRule(rule, nop_func) self.addRule(rule, nop_func)
pass pass

View File

@@ -98,11 +98,8 @@ class Scanner2(Scanner):
# list of tokens/instructions # list of tokens/instructions
tokens = [] tokens = []
# "customize" is a dict whose keys are nonterminals # "customize" is ny pretty much legacy.
# and the value is the argument stack entries for that # We still use it though to signal we have a PyPy program
# nonterminal. The count is a little hoaky. It is mostly
# not used, but sometimes it is.
# "customize" is a dict whose keys are nonterminals
customize = {} customize = {}
if self.is_pypy: if self.is_pypy:
@@ -249,17 +246,6 @@ class Scanner2(Scanner):
op_name = 'BUILD_MAP_n' op_name = 'BUILD_MAP_n'
else: else:
op_name = '%s_%d' % (op_name, oparg) op_name = '%s_%d' % (op_name, oparg)
customize[op_name] = oparg
elif self.is_pypy and op_name in frozenset(
"""LOOKUP_METHOD JUMP_IF_NOT_DEBUG SETUP_EXCEPT SETUP_FINALLY""".split()):
# The value in the dict is in special cases in semantic actions, such
# as CALL_FUNCTION. The value is not used in these cases, so we put
# in arbitrary value 0.
customize[op_name] = 0
elif op_name in """
CONTINUE_LOOP EXEC_STMT LOAD_LISTCOMP LOAD_SETCOMP
""".split():
customize[op_name] = 0
elif op == self.opc.JUMP_ABSOLUTE: elif op == self.opc.JUMP_ABSOLUTE:
# Further classify JUMP_ABSOLUTE into backward jumps # Further classify JUMP_ABSOLUTE into backward jumps
# which are used in loops, and "CONTINUE" jumps which # which are used in loops, and "CONTINUE" jumps which