File tree 2 files changed +51
-1
lines changed
2 files changed +51
-1
lines changed Original file line number Diff line number Diff line change @@ -501,7 +501,6 @@ def test_single_statement(self):
501
501
self .compile_single ("if x:\n f(x)\n else:\n g(x)" )
502
502
self .compile_single ("class T:\n pass" )
503
503
504
- @support .skip_if_new_parser ('Pegen does not disallow multiline single stmts' )
505
504
def test_bad_single_statement (self ):
506
505
self .assertInvalidSingle ('1\n 2' )
507
506
self .assertInvalidSingle ('def f(): pass' )
Original file line number Diff line number Diff line change @@ -911,6 +911,52 @@ _PyPegen_number_token(Parser *p)
911
911
p -> arena );
912
912
}
913
913
914
+ static int // bool
915
+ newline_in_string (Parser * p , const char * cur )
916
+ {
917
+ for (char c = * cur ; cur >= p -> tok -> buf ; c = * -- cur ) {
918
+ if (c == '\'' || c == '"' ) {
919
+ return 1 ;
920
+ }
921
+ }
922
+ return 0 ;
923
+ }
924
+
925
+ /* Check that the source for a single input statement really is a single
926
+ statement by looking at what is left in the buffer after parsing.
927
+ Trailing whitespace and comments are OK. */
928
+ static int // bool
929
+ bad_single_statement (Parser * p )
930
+ {
931
+ const char * cur = strchr (p -> tok -> buf , '\n' );
932
+
933
+ /* Newlines are allowed if preceded by a line continuation character
934
+ or if they appear inside a string. */
935
+ if (!cur || * (cur - 1 ) == '\\' || newline_in_string (p , cur )) {
936
+ return 0 ;
937
+ }
938
+ char c = * cur ;
939
+
940
+ for (;;) {
941
+ while (c == ' ' || c == '\t' || c == '\n' || c == '\014' ) {
942
+ c = * ++ cur ;
943
+ }
944
+
945
+ if (!c ) {
946
+ return 0 ;
947
+ }
948
+
949
+ if (c != '#' ) {
950
+ return 1 ;
951
+ }
952
+
953
+ /* Suck up comment. */
954
+ while (c && c != '\n' ) {
955
+ c = * ++ cur ;
956
+ }
957
+ }
958
+ }
959
+
914
960
void
915
961
_PyPegen_Parser_Free (Parser * p )
916
962
{
@@ -1014,6 +1060,11 @@ _PyPegen_run_parser(Parser *p)
1014
1060
return NULL ;
1015
1061
}
1016
1062
1063
+ if (p -> start_rule == Py_single_input && bad_single_statement (p )) {
1064
+ p -> tok -> done = E_BADSINGLE ; // This is not necessary for now, but might be in the future
1065
+ return RAISE_SYNTAX_ERROR ("multiple statements found while compiling a single statement" );
1066
+ }
1067
+
1017
1068
return res ;
1018
1069
}
1019
1070
You can’t perform that action at this time.
0 commit comments