@@ -164,29 +164,33 @@ dotted_name[expr_ty]:
164164 | NAME
165165
166166if_stmt[stmt_ty]:
167+ | invalid_if_stmt
167168 | 'if' a=named_expression ':' b=block c=elif_stmt {
168169 _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
169170 | 'if' a=named_expression ':' b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
170- | invalid_if_stmt
171171elif_stmt[stmt_ty]:
172+ | invalid_elif_stmt
172173 | 'elif' a=named_expression ':' b=block c=elif_stmt {
173174 _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
174175 | 'elif' a=named_expression ':' b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
175- | invalid_elif_stmt
176- else_block[asdl_stmt_seq*]: 'else' &&':' b=block { b }
176+ else_block[asdl_stmt_seq*]:
177+ | invalid_else_stmt
178+ | 'else' &&':' b=block { b }
177179
178180while_stmt[stmt_ty]:
179- | 'while' a=named_expression ':' b=block c=[else_block] { _PyAST_While(a, b, c, EXTRA) }
180181 | invalid_while_stmt
182+ | 'while' a=named_expression ':' b=block c=[else_block] { _PyAST_While(a, b, c, EXTRA) }
181183
182184for_stmt[stmt_ty]:
185+ | invalid_for_stmt
183186 | 'for' t=star_targets 'in' ~ ex=star_expressions &&':' tc=[TYPE_COMMENT] b=block el=[else_block] {
184187 _PyAST_For(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA) }
185188 | ASYNC 'for' t=star_targets 'in' ~ ex=star_expressions &&':' tc=[TYPE_COMMENT] b=block el=[else_block] {
186189 CHECK_VERSION(stmt_ty, 5, "Async for loops are", _PyAST_AsyncFor(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
187190 | invalid_for_target
188191
189192with_stmt[stmt_ty]:
193+ | invalid_with_stmt_indent
190194 | 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block {
191195 _PyAST_With(a, b, NULL, EXTRA) }
192196 | 'with' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
@@ -203,14 +207,18 @@ with_item[withitem_ty]:
203207 | e=expression { _PyAST_withitem(e, NULL, p->arena) }
204208
205209try_stmt[stmt_ty]:
210+ | invalid_try_stmt
206211 | 'try' &&':' b=block f=finally_block { _PyAST_Try(b, NULL, NULL, f, EXTRA) }
207212 | 'try' &&':' b=block ex[asdl_excepthandler_seq*]=except_block+ el=[else_block] f=[finally_block] { _PyAST_Try(b, ex, el, f, EXTRA) }
208213except_block[excepthandler_ty]:
214+ | invalid_except_stmt_indent
209215 | 'except' e=expression t=['as' z=NAME { z }] ':' b=block {
210216 _PyAST_ExceptHandler(e, (t) ? ((expr_ty) t)->v.Name.id : NULL, b, EXTRA) }
211217 | 'except' ':' b=block { _PyAST_ExceptHandler(NULL, NULL, b, EXTRA) }
212- | invalid_except_block
213- finally_block[asdl_stmt_seq*]: 'finally' ':' a=block { a }
218+ | invalid_except_stmt
219+ finally_block[asdl_stmt_seq*]:
220+ | invalid_finally_stmt
221+ | 'finally' &&':' a=block { a }
214222
215223match_stmt[stmt_ty]:
216224 | "match" subject=subject_expr ':' NEWLINE INDENT cases[asdl_match_case_seq*]=case_block+ DEDENT {
@@ -221,9 +229,9 @@ subject_expr[expr_ty]:
221229 _PyAST_Tuple(CHECK(asdl_expr_seq*, _PyPegen_seq_insert_in_front(p, value, values)), Load, EXTRA) }
222230 | named_expression
223231case_block[match_case_ty]:
232+ | invalid_case_block
224233 | "case" pattern=patterns guard=guard? ':' body=block {
225234 _PyAST_match_case(pattern, guard, body, p->arena) }
226- | invalid_case_block
227235guard[expr_ty]: 'if' guard=named_expression { guard }
228236
229237patterns[expr_ty]:
@@ -334,6 +342,7 @@ function_def[stmt_ty]:
334342 | function_def_raw
335343
336344function_def_raw[stmt_ty]:
345+ | invalid_def_raw
337346 | 'def' n=NAME '(' params=[params] ')' a=['->' z=expression { z }] &&':' tc=[func_type_comment] b=block {
338347 _PyAST_FunctionDef(n->v.Name.id,
339348 (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)),
@@ -418,6 +427,7 @@ class_def[stmt_ty]:
418427 | a=decorators b=class_def_raw { _PyPegen_class_def_decorators(p, a, b) }
419428 | class_def_raw
420429class_def_raw[stmt_ty]:
430+ | invalid_class_def_raw
421431 | 'class' a=NAME b=['(' z=[arguments] ')' { z }] &&':' c=block {
422432 _PyAST_ClassDef(a->v.Name.id,
423433 (b) ? ((expr_ty) b)->v.Call.args : NULL,
@@ -876,23 +886,59 @@ invalid_import_from_targets:
876886invalid_with_stmt:
877887 | [ASYNC] 'with' ','.(expression ['as' star_target])+ &&':'
878888 | [ASYNC] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':'
879-
880- invalid_except_block:
889+ invalid_with_stmt_indent:
890+ | [ASYNC] a='with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT {
891+ RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) }
892+ | [ASYNC] a='with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT {
893+ RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) }
894+
895+ invalid_try_stmt:
896+ | a='try' ':' NEWLINE !INDENT {
897+ RAISE_INDENTATION_ERROR("expected an indented block after 'try' statement on line %d", a->lineno) }
898+ invalid_except_stmt:
881899 | 'except' a=expression ',' expressions ['as' NAME ] ':' {
882900 RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "exception group must be parenthesized") }
883- | 'except' expression ['as' NAME ] &&':'
884- | 'except' &&':'
885-
901+ | a='except' expression ['as' NAME ] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
902+ | a='except' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
903+ invalid_finally_stmt:
904+ | a='finally' ':' NEWLINE !INDENT {
905+ RAISE_INDENTATION_ERROR("expected an indented block after 'finally' statement on line %d", a->lineno) }
906+ invalid_except_stmt_indent:
907+ | a='except' expression ['as' NAME ] ':' NEWLINE !INDENT {
908+ RAISE_INDENTATION_ERROR("expected an indented block after 'except' statement on line %d", a->lineno) }
909+ | a='except' ':' NEWLINE !INDENT { RAISE_SYNTAX_ERROR("expected an indented block after except statement on line %d", a->lineno) }
886910invalid_match_stmt:
887911 | "match" subject_expr !':' { CHECK_VERSION(void*, 10, "Pattern matching is", RAISE_SYNTAX_ERROR("expected ':'") ) }
912+ | a="match" subject=subject_expr ':' NEWLINE !INDENT {
913+ RAISE_INDENTATION_ERROR("expected an indented block after 'match' statement on line %d", a->lineno) }
888914invalid_case_block:
889915 | "case" patterns guard? !':' { RAISE_SYNTAX_ERROR("expected ':'") }
916+ | a="case" patterns guard? ':' NEWLINE !INDENT {
917+ RAISE_INDENTATION_ERROR("expected an indented block after 'case' statement on line %d", a->lineno) }
890918invalid_if_stmt:
891919 | 'if' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
920+ | a='if' a=named_expression ':' NEWLINE !INDENT {
921+ RAISE_INDENTATION_ERROR("expected an indented block after 'if' statement on line %d", a->lineno) }
892922invalid_elif_stmt:
893923 | 'elif' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
924+ | a='elif' named_expression ':' NEWLINE !INDENT {
925+ RAISE_INDENTATION_ERROR("expected an indented block after 'elif' statement on line %d", a->lineno) }
926+ invalid_else_stmt:
927+ | a='else' ':' NEWLINE !INDENT {
928+ RAISE_INDENTATION_ERROR("expected an indented block after 'else' statement on line %d", a->lineno) }
894929invalid_while_stmt:
895930 | 'while' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
931+ | a='while' named_expression ':' NEWLINE !INDENT {
932+ RAISE_INDENTATION_ERROR("expected an indented block after 'while' statement on line %d", a->lineno) }
933+ invalid_for_stmt:
934+ | [ASYNC] a='for' star_targets 'in' star_expressions ':' NEWLINE !INDENT {
935+ RAISE_INDENTATION_ERROR("expected an indented block after 'for' statement on line %d", a->lineno) }
936+ invalid_def_raw:
937+ | [ASYNC] a='def' NAME '(' [params] ')' ['->' expression] ':' NEWLINE !INDENT {
938+ RAISE_INDENTATION_ERROR("expected an indented block after function definition on line %d", a->lineno) }
939+ invalid_class_def_raw:
940+ | a='class' NAME ['('[arguments] ')'] ':' NEWLINE !INDENT {
941+ RAISE_INDENTATION_ERROR("expected an indented block after class definition on line %d", a->lineno) }
896942
897943invalid_double_starred_kvpairs:
898944 | ','.double_starred_kvpair+ ',' invalid_kvpair
0 commit comments