Tweaks to x0ret's anotation type handling

- match AST names a little better: AnnAssign -> ann_assign...
- localize Annotation type grammar change only when we have it
- Add reduce rule to combine assignment and annotate declaration
- Add annotation-type test from Python 3.6
- Docuemnt what's up with annotation types
This commit is contained in:
rocky
2019-06-11 10:38:10 -04:00
parent 21fd506fbb
commit 76dcaf9bf0
4 changed files with 47 additions and 12 deletions

View File

@@ -30,8 +30,7 @@ class Python36Parser(Python35Parser):
def p_36misc(self, args):
"""
sstmt ::= sstmt RETURN_LAST
"""sstmt ::= sstmt RETURN_LAST
# 3.6 redoes how return_closure works. FIXME: Isolate to LOAD_CLOSURE
return_closure ::= LOAD_CLOSURE DUP_TOP STORE_NAME RETURN_VALUE RETURN_LAST
@@ -144,10 +143,6 @@ class Python36Parser(Python35Parser):
compare_chained2 ::= expr COMPARE_OP come_froms JUMP_FORWARD
stmt ::= SETUP_ANNOTATIONS
stmt ::= annotated_assign
annotated_assign ::= expr store store_annotation
store_annotation ::= LOAD_NAME STORE_ANNOTATION
"""
def customize_grammar_rules(self, tokens, customize):
@@ -269,6 +264,22 @@ class Python36Parser(Python35Parser):
self.addRule(rule, nop_func)
rule = ('starred ::= %s %s' % ('expr ' * v, opname))
self.addRule(rule, nop_func)
elif opname == 'SETUP_ANNOTATIONS':
# 3.6 Variable Annotations PEP 526
# This seems to come before STORE_ANNOTATION, and doesn't
# correspond to direct Python source code.
rule = """
stmt ::= SETUP_ANNOTATIONS
stmt ::= ann_assign_init_value
stmt ::= ann_assign_no_init
ann_assign_init_value ::= expr store store_annotation
ann_assign_no_init ::= store_annotation
store_annotation ::= LOAD_NAME STORE_ANNOTATION
"""
self.addRule(rule, nop_func)
# Check to combine assignment + annotation into one statement
self.check_reduce['assign'] = 'token'
elif opname == 'SETUP_WITH':
rules_str = """
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt COME_FROM_WITH
@@ -294,6 +305,7 @@ class Python36Parser(Python35Parser):
self.addRule(rules_str, nop_func)
pass
pass
return
def custom_classfunc_rule(self, opname, token, customize, next_token):
@@ -393,6 +405,15 @@ class Python36Parser(Python35Parser):
tokens, first, last)
if invalid:
return invalid
if rule[0] == 'assign':
# Try to combine assignment + annotation into one statement
if (len(tokens) >= last + 1 and
tokens[last] == 'LOAD_NAME' and
tokens[last+1] == 'STORE_ANNOTATION' and
tokens[last-1].pattr == tokens[last+1].pattr):
# Will handle as ann_assign_init_value
return True
pass
if rule[0] == 'call_kw':
# Make sure we don't derive call_kw
nt = ast[0]