DRY Python 3.6 grammar rules

This commit is contained in:
rocky
2016-10-22 12:24:01 -04:00
parent 9b7d978944
commit 0480455ae1
3 changed files with 39 additions and 31 deletions

View File

@@ -42,13 +42,22 @@ class PythonParser(GenericASTBuilder):
return
def add_unique_rules(self, rules, customize):
"""Add rules to grammar
"""Add rules (a list of string) to grammar
"""
for rule in rules:
if len(rule) == 0:
continue
opname = rule.split('::=')[0].strip()
self.add_unique_rule(rule, opname, 0, customize)
return
def add_unique_doc_rules(self, rules_str, customize):
"""Add rules (a docstring-like list of rules) to grammar
"""
rules = [r.strip() for r in rules_str.split("\n")]
self.add_unique_rules(rules, customize)
return
def cleanup(self):
"""
Remove recursive references to allow garbage

View File

@@ -500,7 +500,6 @@ class Python3Parser(PythonParser):
load_attr ::= expr LOOKUP_METHOD
call_function ::= expr CALL_METHOD
"""
saw_format_value = False
for i, token in enumerate(tokens):
opname = token.type
opname_base = opname[:opname.rfind('_')]
@@ -513,28 +512,6 @@ class Python3Parser(PythonParser):
assign2_pypy ::= expr expr designator designator
""", nop_func)
continue
elif opname == 'FORMAT_VALUE':
# Python 3.6+
self.addRule("""
expr ::= fstring_single
fstring_single ::= expr FORMAT_VALUE
""", nop_func)
elif opname == 'BUILD_STRING':
# Python 3.6+
v = token.attr
fstring_expr_or_str_n = "fstring_expr_or_str_%s" % v
rule = """
expr ::= fstring_expr
fstring_expr ::= expr FORMAT_VALUE
str ::= LOAD_CONST
fstring_expr_or_str ::= fstring_expr
fstring_expr_or_str ::= str
expr ::= fstring_multi
fstring_multi ::= %s BUILD_STRING
%s ::= %sBUILD_STRING
""" % (fstring_expr_or_str_n, fstring_expr_or_str_n, "fstring_expr_or_str " * v)
self.addRule(rule, nop_func)
elif opname in ('CALL_FUNCTION', 'CALL_FUNCTION_VAR',
'CALL_FUNCTION_VAR_KW', 'CALL_FUNCTION_KW'):
self.custom_classfunc_rule(opname, token, customize)
@@ -741,7 +718,6 @@ class Python33ParserSingle(Python33Parser, PythonParserSingle):
def info(args):
# Check grammar
# Should also add a way to dump grammar
p = Python3Parser()
if len(args) > 0:
arg = args[0]
@@ -753,7 +729,9 @@ def info(args):
elif arg == '3.2':
p = Python32Parser()
p.checkGrammar()
if len(sys.argv) > 1 and sys.argv[1] == 'dump':
print('-' * 50)
p.dumpGrammar()
if __name__ == '__main__':
import sys

View File

@@ -16,16 +16,37 @@ class Python36Parser(Python35Parser):
def p_36misc(self, args):
"""
fstring_single ::= expr FORMAT_VALUE
fstring_expr ::= expr FORMAT_VALUE
str ::= LOAD_CONST
fstring_multi ::= fstring_expr_or_strs BUILD_STRING
fstring_expr_or_strs ::= fstring_expr_or_strs fstring_expr_or_str
fstring_expr_or_strs ::= fstring_expr_or_str
fstring_expr_or_str ::= fstring_expr
fstring_expr_or_str ::= str
"""
def add_custom_rules(self, tokens, customize):
super(Python36Parser, self).add_custom_rules(tokens, customize)
for i, token in enumerate(tokens):
opname = token.type
if opname == 'FORMAT_VALUE':
rules_str = """
expr ::= fstring_single
fstring_single ::= expr FORMAT_VALUE
"""
self.add_unique_doc_rules(rules_str, customize)
elif opname == 'BUILD_STRING':
v = token.attr
fstring_expr_or_str_n = "fstring_expr_or_str_%s" % v
rules_str = """
expr ::= fstring_expr
fstring_expr ::= expr FORMAT_VALUE
str ::= LOAD_CONST
fstring_expr_or_str ::= fstring_expr
fstring_expr_or_str ::= str
expr ::= fstring_multi
fstring_multi ::= %s BUILD_STRING
%s ::= %sBUILD_STRING
""" % (fstring_expr_or_str_n, fstring_expr_or_str_n, "fstring_expr_or_str " * v)
self.add_unique_doc_rules(rules_str, customize)
class Python36ParserSingle(Python36Parser, PythonParserSingle):
pass