@@ -94,7 +94,7 @@ assignment[stmt_ty]:
94
94
CHECK_VERSION(6, "Variable annotations syntax is", _Py_AnnAssign(a, b, c, 0, EXTRA)) }
95
95
| a=(z=star_targets '=' { z })+ b=(yield_expr | star_expressions) !'=' tc=[TYPE_COMMENT] {
96
96
_Py_Assign(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
97
- | a=single_target b=augassign c=(yield_expr | star_expressions) {
97
+ | a=single_target b=augassign ~ c=(yield_expr | star_expressions) {
98
98
_Py_AugAssign(a, b->kind, c, EXTRA) }
99
99
| invalid_assignment
100
100
@@ -122,7 +122,9 @@ yield_stmt[stmt_ty]: y=yield_expr { _Py_Expr(y, EXTRA) }
122
122
123
123
assert_stmt[stmt_ty]: 'assert' a=expression b=[',' z=expression { z }] { _Py_Assert(a, b, EXTRA) }
124
124
125
- del_stmt[stmt_ty]: 'del' a=del_targets { _Py_Delete(a, EXTRA) }
125
+ del_stmt[stmt_ty]:
126
+ | 'del' a=del_targets &(';' | NEWLINE) { _Py_Delete(a, EXTRA) }
127
+ | invalid_del_stmt
126
128
127
129
import_stmt[stmt_ty]: import_name | import_from
128
130
import_name[stmt_ty]: 'import' a=dotted_as_names { _Py_Import(a, EXTRA) }
@@ -165,10 +167,11 @@ while_stmt[stmt_ty]:
165
167
| 'while' a=named_expression ':' b=block c=[else_block] { _Py_While(a, b, c, EXTRA) }
166
168
167
169
for_stmt[stmt_ty]:
168
- | 'for' t=star_targets 'in' ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
170
+ | 'for' t=star_targets 'in' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
169
171
_Py_For(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA) }
170
- | ASYNC 'for' t=star_targets 'in' ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
172
+ | ASYNC 'for' t=star_targets 'in' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
171
173
CHECK_VERSION(5, "Async for loops are", _Py_AsyncFor(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
174
+ | invalid_for_target
172
175
173
176
with_stmt[stmt_ty]:
174
177
| 'with' '(' a=','.with_item+ ','? ')' ':' b=block {
@@ -180,7 +183,9 @@ with_stmt[stmt_ty]:
180
183
| ASYNC 'with' a=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
181
184
CHECK_VERSION(5, "Async with statements are", _Py_AsyncWith(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
182
185
with_item[withitem_ty]:
183
- | e=expression o=['as' t=target { t }] { _Py_withitem(e, o, p->arena) }
186
+ | e=expression 'as' t=target &(',' | ')' | ':') { _Py_withitem(e, t, p->arena) }
187
+ | invalid_with_item
188
+ | e=expression { _Py_withitem(e, NULL, p->arena) }
184
189
185
190
try_stmt[stmt_ty]:
186
191
| 'try' ':' b=block f=finally_block { _Py_Try(b, NULL, NULL, f, EXTRA) }
@@ -312,7 +317,7 @@ star_named_expression[expr_ty]:
312
317
| '*' a=bitwise_or { _Py_Starred(a, Load, EXTRA) }
313
318
| named_expression
314
319
named_expression[expr_ty]:
315
- | a=NAME ':=' b=expression { _Py_NamedExpr(CHECK(_PyPegen_set_expr_context(p, a, Store)), b, EXTRA) }
320
+ | a=NAME ':=' ~ b=expression { _Py_NamedExpr(CHECK(_PyPegen_set_expr_context(p, a, Store)), b, EXTRA) }
316
321
| expression !':='
317
322
| invalid_named_expression
318
323
@@ -489,18 +494,20 @@ strings[expr_ty] (memo): a=STRING+ { _PyPegen_concatenate_strings(p, a) }
489
494
list[expr_ty]:
490
495
| '[' a=[star_named_expressions] ']' { _Py_List(a, Load, EXTRA) }
491
496
listcomp[expr_ty]:
492
- | '[' a=named_expression b=for_if_clauses ']' { _Py_ListComp(a, b, EXTRA) }
497
+ | '[' a=named_expression ~ b=for_if_clauses ']' { _Py_ListComp(a, b, EXTRA) }
493
498
| invalid_comprehension
494
499
tuple[expr_ty]:
495
500
| '(' a=[y=star_named_expression ',' z=[star_named_expressions] { _PyPegen_seq_insert_in_front(p, y, z) } ] ')' {
496
501
_Py_Tuple(a, Load, EXTRA) }
497
- group[expr_ty]: '(' a=(yield_expr | named_expression) ')' { a }
502
+ group[expr_ty]:
503
+ | '(' a=(yield_expr | named_expression) ')' { a }
504
+ | invalid_group
498
505
genexp[expr_ty]:
499
- | '(' a=expression b=for_if_clauses ')' { _Py_GeneratorExp(a, b, EXTRA) }
506
+ | '(' a=expression ~ b=for_if_clauses ')' { _Py_GeneratorExp(a, b, EXTRA) }
500
507
| invalid_comprehension
501
508
set[expr_ty]: '{' a=expressions_list '}' { _Py_Set(a, EXTRA) }
502
509
setcomp[expr_ty]:
503
- | '{' a=expression b=for_if_clauses '}' { _Py_SetComp(a, b, EXTRA) }
510
+ | '{' a=expression ~ b=for_if_clauses '}' { _Py_SetComp(a, b, EXTRA) }
504
511
| invalid_comprehension
505
512
dict[expr_ty]:
506
513
| '{' a=[double_starred_kvpairs] '}' {
@@ -516,10 +523,11 @@ kvpair[KeyValuePair*]: a=expression ':' b=expression { _PyPegen_key_value_pair(p
516
523
for_if_clauses[asdl_seq*]:
517
524
| for_if_clause+
518
525
for_if_clause[comprehension_ty]:
519
- | ASYNC 'for' a=star_targets 'in' b=disjunction c=('if' z=disjunction { z })* {
526
+ | ASYNC 'for' a=star_targets 'in' ~ b=disjunction c=('if' z=disjunction { z })* {
520
527
CHECK_VERSION(6, "Async comprehensions are", _Py_comprehension(a, b, c, 1, p->arena)) }
521
- | 'for' a=star_targets 'in' b=disjunction c=('if' z=disjunction { z })* {
528
+ | 'for' a=star_targets 'in' ~ b=disjunction c=('if' z=disjunction { z })* {
522
529
_Py_comprehension(a, b, c, 0, p->arena) }
530
+ | invalid_for_target
523
531
524
532
yield_expr[expr_ty]:
525
533
| 'yield' 'from' a=expression { _Py_YieldFrom(a, EXTRA) }
@@ -589,19 +597,15 @@ single_subscript_attribute_target[expr_ty]:
589
597
| a=t_primary '[' b=slices ']' !t_lookahead { _Py_Subscript(a, b, Store, EXTRA) }
590
598
591
599
del_targets[asdl_seq*]: a=','.del_target+ [','] { a }
592
- # The lookaheads to del_target_end ensure that we don't match expressions where a prefix of the
593
- # expression matches our rule, thereby letting these cases fall through to invalid_del_target.
594
600
del_target[expr_ty] (memo):
595
- | a=t_primary '.' b=NAME &del_target_end { _Py_Attribute(a, b->v.Name.id, Del, EXTRA) }
596
- | a=t_primary '[' b=slices ']' &del_target_end { _Py_Subscript(a, b, Del, EXTRA) }
601
+ | a=t_primary '.' b=NAME !t_lookahead { _Py_Attribute(a, b->v.Name.id, Del, EXTRA) }
602
+ | a=t_primary '[' b=slices ']' !t_lookahead { _Py_Subscript(a, b, Del, EXTRA) }
597
603
| del_t_atom
598
604
del_t_atom[expr_ty]:
599
- | a=NAME &del_target_end { _PyPegen_set_expr_context(p, a, Del) }
605
+ | a=NAME { _PyPegen_set_expr_context(p, a, Del) }
600
606
| '(' a=del_target ')' { _PyPegen_set_expr_context(p, a, Del) }
601
607
| '(' a=[del_targets] ')' { _Py_Tuple(a, Del, EXTRA) }
602
608
| '[' a=[del_targets] ']' { _Py_List(a, Del, EXTRA) }
603
- | invalid_del_target
604
- del_target_end: ')' | ']' | ',' | ';' | NEWLINE
605
609
606
610
targets[asdl_seq*]: a=','.target+ [','] { a }
607
611
target[expr_ty] (memo):
@@ -652,16 +656,23 @@ invalid_assignment:
652
656
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "illegal target for annotation") }
653
657
| (star_targets '=')* a=star_expressions '=' {
654
658
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
655
- _PyPegen_get_invalid_target (a),
656
- "cannot assign to %s", _PyPegen_get_expr_name(_PyPegen_get_invalid_target (a))) }
659
+ GET_INVALID_TARGET (a),
660
+ "cannot assign to %s", _PyPegen_get_expr_name(GET_INVALID_TARGET (a))) }
657
661
| (star_targets '=')* a=yield_expr '=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "assignment to yield expression not possible") }
658
662
| a=star_expressions augassign (yield_expr | star_expressions) {
659
663
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
660
664
a,
661
665
"'%s' is an illegal expression for augmented assignment",
662
666
_PyPegen_get_expr_name(a)
663
667
)}
664
-
668
+ invalid_del_stmt:
669
+ | 'del' a=star_expressions {
670
+ GET_INVALID_DEL_TARGET(a) != NULL ?
671
+ RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
672
+ GET_INVALID_DEL_TARGET(a),
673
+ "cannot delete %s", _PyPegen_get_expr_name(GET_INVALID_DEL_TARGET(a))
674
+ ) :
675
+ RAISE_SYNTAX_ERROR("invalid syntax") }
665
676
invalid_block:
666
677
| NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block") }
667
678
invalid_comprehension:
@@ -684,9 +695,25 @@ invalid_lambda_star_etc:
684
695
invalid_double_type_comments:
685
696
| TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT {
686
697
RAISE_SYNTAX_ERROR("Cannot have two type comments on def") }
687
- invalid_del_target:
688
- | a=star_expression &del_target_end {
689
- RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot delete %s", _PyPegen_get_expr_name(a)) }
698
+ invalid_with_item:
699
+ | expression 'as' a=expression {
700
+ RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
701
+ GET_INVALID_TARGET(a),
702
+ "cannot assign to %s", _PyPegen_get_expr_name(GET_INVALID_TARGET(a))
703
+ ) }
704
+
705
+ invalid_for_target:
706
+ | ASYNC? 'for' a=star_expressions {
707
+ GET_INVALID_FOR_TARGET(a) != NULL ?
708
+ RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
709
+ GET_INVALID_FOR_TARGET(a),
710
+ "cannot assign to %s", _PyPegen_get_expr_name(GET_INVALID_FOR_TARGET(a))
711
+ ) :
712
+ RAISE_SYNTAX_ERROR("invalid syntax") }
713
+
714
+ invalid_group:
715
+ | '(' a=starred_expression ')' {
716
+ RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "can't use starred expression here") }
690
717
invalid_import_from_targets:
691
718
| import_from_as_names ',' {
692
719
RAISE_SYNTAX_ERROR("trailing comma not allowed without surrounding parentheses") }
0 commit comments