summaryrefslogtreecommitdiff
path: root/Grammar
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2015-05-05 20:16:41 -0400
committerBenjamin Peterson <benjamin@python.org>2015-05-05 20:16:41 -0400
commit025e9ebd0a0a19f50ca83af6ada0ac65be1fa2a1 (patch)
treed769adcb6d4a557a00923f18ed2b0ca8b515a473 /Grammar
parent4ccc1514d070cabe80e8cfa0469dc03c12d08be2 (diff)
downloadcpython-git-025e9ebd0a0a19f50ca83af6ada0ac65be1fa2a1.tar.gz
PEP 448: additional unpacking generalizations (closes #2292)
Patch by Neil Girdhar.
Diffstat (limited to 'Grammar')
-rw-r--r--Grammar/Grammar24
1 files changed, 18 insertions, 6 deletions
diff --git a/Grammar/Grammar b/Grammar/Grammar
index 94898d375a..6915f5fde1 100644
--- a/Grammar/Grammar
+++ b/Grammar/Grammar
@@ -111,17 +111,29 @@ subscript: test | [test] ':' [test] [sliceop]
sliceop: ':' [test]
exprlist: (expr|star_expr) (',' (expr|star_expr))* [',']
testlist: test (',' test)* [',']
-dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) |
- (test (comp_for | (',' test)* [','])) )
+dictorsetmaker: ( ((test ':' test | '**' expr)
+ (comp_for | (',' (test ':' test | '**' expr))* [','])) |
+ ((test | star_expr)
+ (comp_for | (',' (test | star_expr))* [','])) )
classdef: 'class' NAME ['(' [arglist] ')'] ':' suite
-arglist: (argument ',')* (argument [',']
- |'*' test (',' argument)* [',' '**' test]
- |'**' test)
+arglist: argument (',' argument)* [',']
+
# The reason that keywords are test nodes instead of NAME is that using NAME
# results in an ambiguity. ast.c makes sure it's a NAME.
-argument: test [comp_for] | test '=' test # Really [keyword '='] test
+# "test '=' test" is really "keyword '=' test", but we have no such token.
+# These need to be in a single rule to avoid grammar that is ambiguous
+# to our LL(1) parser. Even though 'test' includes '*expr' in star_expr,
+# we explicitly match '*' here, too, to give it proper precedence.
+# Illegal combinations and orderings are blocked in ast.c:
+# multiple (test comp_for) arguements are blocked; keyword unpackings
+# that precede iterable unpackings are blocked; etc.
+argument: ( test [comp_for] |
+ test '=' test |
+ '**' expr |
+ star_expr )
+
comp_iter: comp_for | comp_if
comp_for: 'for' exprlist 'in' or_test [comp_iter]
comp_if: 'if' test_nocond [comp_iter]