@@ -54,9 +54,9 @@ _PyLexer_record_ftstring_comment(struct tok_state *tok, ftstring_state *state,
5454 return 0 ;
5555}
5656
57- int
58- _PyLexer_finish_ftstring_expr (struct tok_state * tok , ftstring_state * state ,
59- struct token * token )
57+ static int
58+ finish_ftstring_expr (struct tok_state * tok , ftstring_state * state ,
59+ struct token * token )
6060{
6161 assert (token != NULL && state == _PyLexer_CurrentFTString (tok ));
6262 assert (state -> mode == FTSTRING_MODE_EXPRESSION && tok -> start != NULL );
@@ -127,6 +127,82 @@ _PyLexer_finish_ftstring_expr(struct tok_state *tok, ftstring_state *state,
127127 return 0 ;
128128}
129129
130+ static int
131+ begin_ftstring_expr (struct tok_state * tok , ftstring_state * state ,
132+ _PyTok_Off expr_start )
133+ {
134+ assert (state -> mode != FTSTRING_MODE_EXPRESSION );
135+ state -> expr_span = (_PyTok_Span ){expr_start , -1 };
136+ if (state -> comments != NULL ) {
137+ state -> comments -> count = 0 ;
138+ }
139+ if (state -> replacement_depth >= MAX_EXPR_NESTING ) {
140+ _PyTokenizer_syntaxerror (
141+ tok , "%c-string: expressions nested too deeply" ,
142+ _PyLexer_StringPrefix (state -> kind ));
143+ return -1 ;
144+ }
145+ state -> replacement_depth ++ ;
146+ state -> mode = FTSTRING_MODE_EXPRESSION ;
147+ state -> debug_expr = 0 ;
148+ return 0 ;
149+ }
150+
151+ int
152+ _PyLexer_ftstring_punctuation (struct tok_state * tok , ftstring_state * state ,
153+ struct token * token , int c )
154+ {
155+ assert (state -> mode == FTSTRING_MODE_EXPRESSION );
156+ assert (c == ':' || c == '}' || c == '!' );
157+ if (_PyLexer_FTStringBracketDepth (tok , state ) != state -> replacement_depth ) {
158+ return 0 ;
159+ }
160+ if (c == '!' ) {
161+ int next = tok_nextc (tok );
162+ tok_backup (tok , next );
163+ if (next == '=' ) {
164+ return 0 ;
165+ }
166+ }
167+ if (finish_ftstring_expr (tok , state , token ) < 0 ) {
168+ return -1 ;
169+ }
170+ if (c == ':' ) {
171+ state -> mode = FTSTRING_MODE_FORMAT_SPEC ;
172+ return COLON ;
173+ }
174+ return 0 ;
175+ }
176+
177+ int
178+ _PyLexer_close_ftstring_expr (struct tok_state * tok , ftstring_state * state ,
179+ int c )
180+ {
181+ assert (state -> mode == FTSTRING_MODE_EXPRESSION );
182+ assert (c == ')' || c == ']' || c == '}' );
183+ int depth = _PyLexer_FTStringBracketDepth (tok , state );
184+ if (depth < 0 ) {
185+ _PyTokenizer_syntaxerror (tok , "%c-string: unmatched '%c'" ,
186+ _PyLexer_StringPrefix (state -> kind ), c );
187+ return -1 ;
188+ }
189+ if (c == '}' && depth == state -> replacement_depth - 1 ) {
190+ state -> replacement_depth -- ;
191+ state -> mode = FTSTRING_MODE_MIDDLE ;
192+ state -> debug_expr = 0 ;
193+ }
194+ return 0 ;
195+ }
196+
197+ void
198+ _PyLexer_mark_ftstring_debug (struct tok_state * tok , ftstring_state * state )
199+ {
200+ assert (state -> mode == FTSTRING_MODE_EXPRESSION );
201+ if (_PyLexer_FTStringBracketDepth (tok , state ) == state -> replacement_depth ) {
202+ state -> debug_expr = 1 ;
203+ }
204+ }
205+
130206int
131207_PyLexer_check_string_prefixes (struct tok_state * tok ,
132208 int saw_b , int saw_r , int saw_u ,
@@ -408,21 +484,11 @@ _PyLexer_get_ftstring(struct tok_state *tok, ftstring_state *current, struct tok
408484 int peek = tok_nextc (tok );
409485 if (peek != '{' || in_format_spec ) {
410486 tok_backup (tok , peek );
411- current -> expr_span = (_PyTok_Span ){
412- _PyLexer_BufferOffset (tok , tok -> cur ), -1 };
413- if (current -> comments != NULL ) {
414- current -> comments -> count = 0 ;
415- }
487+ _PyTok_Off expr_start = _PyLexer_BufferOffset (tok , tok -> cur );
416488 tok_backup (tok , c );
417- if (current -> replacement_depth >= MAX_EXPR_NESTING ) {
418- _PyTokenizer_syntaxerror (
419- tok , "%c-string: expressions nested too deeply" ,
420- _PyLexer_StringPrefix (current -> kind ));
489+ if (begin_ftstring_expr (tok , current , expr_start ) < 0 ) {
421490 return MAKE_TOKEN (ERRORTOKEN );
422491 }
423- current -> replacement_depth ++ ;
424- current -> mode = FTSTRING_MODE_EXPRESSION ;
425- current -> debug_expr = 0 ;
426492 p_start = tok -> start ;
427493 p_end = tok -> cur ;
428494 if (p_start == p_end ) {
0 commit comments