Coverage Report

Created: 2026-07-14 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Parser/action_helpers.c
Line
Count
Source
1
#include <Python.h>
2
#include "pycore_pystate.h"         // _PyInterpreterState_GET()
3
#include "pycore_runtime.h"         // _PyRuntime
4
#include "pycore_unicodeobject.h"   // _PyUnicode_InternImmortal()
5
#include "pycore_pyerrors.h"        // _PyErr_EmitSyntaxWarning()
6
7
#include "pegen.h"
8
#include "string_parser.h"          // _PyPegen_decode_string()
9
10
11
void *
12
_PyPegen_dummy_name(Parser *p, ...)
13
66.4k
{
14
66.4k
    return &_PyRuntime.parser.dummy_name;
15
66.4k
}
16
17
/* Creates a single-element asdl_seq* that contains a */
18
asdl_seq *
19
_PyPegen_singleton_seq(Parser *p, void *a)
20
143k
{
21
143k
    assert(a != NULL);
22
143k
    asdl_seq *seq = (asdl_seq*)_Py_asdl_generic_seq_new(1, p->arena);
23
143k
    if (!seq) {
24
0
        return NULL;
25
0
    }
26
143k
    asdl_seq_SET_UNTYPED(seq, 0, a);
27
143k
    return seq;
28
143k
}
29
30
/* Creates a copy of seq and prepends a to it */
31
asdl_seq *
32
_PyPegen_seq_insert_in_front(Parser *p, void *a, asdl_seq *seq)
33
334k
{
34
334k
    assert(a != NULL);
35
334k
    if (!seq) {
36
11.8k
        return _PyPegen_singleton_seq(p, a);
37
11.8k
    }
38
39
323k
    asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena);
40
323k
    if (!new_seq) {
41
0
        return NULL;
42
0
    }
43
44
323k
    asdl_seq_SET_UNTYPED(new_seq, 0, a);
45
601k
    for (Py_ssize_t i = 1, l = asdl_seq_LEN(new_seq); i < l; i++) {
46
278k
        asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i - 1));
47
278k
    }
48
323k
    return new_seq;
49
323k
}
50
51
/* Creates a copy of seq and appends a to it */
52
asdl_seq *
53
_PyPegen_seq_append_to_end(Parser *p, asdl_seq *seq, void *a)
54
0
{
55
0
    assert(a != NULL);
56
0
    if (!seq) {
57
0
        return _PyPegen_singleton_seq(p, a);
58
0
    }
59
60
0
    asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena);
61
0
    if (!new_seq) {
62
0
        return NULL;
63
0
    }
64
65
0
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(new_seq); i + 1 < l; i++) {
66
0
        asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i));
67
0
    }
68
0
    asdl_seq_SET_UNTYPED(new_seq, asdl_seq_LEN(new_seq) - 1, a);
69
0
    return new_seq;
70
0
}
71
72
static Py_ssize_t
73
_get_flattened_seq_size(asdl_seq *seqs)
74
17.7k
{
75
17.7k
    Py_ssize_t size = 0;
76
102k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) {
77
85.2k
        asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i);
78
85.2k
        size += asdl_seq_LEN(inner_seq);
79
85.2k
    }
80
17.7k
    return size;
81
17.7k
}
82
83
/* Flattens an asdl_seq* of asdl_seq*s */
84
asdl_seq *
85
_PyPegen_seq_flatten(Parser *p, asdl_seq *seqs)
86
17.7k
{
87
17.7k
    Py_ssize_t flattened_seq_size = _get_flattened_seq_size(seqs);
88
17.7k
    assert(flattened_seq_size > 0);
89
90
17.7k
    asdl_seq *flattened_seq = (asdl_seq*)_Py_asdl_generic_seq_new(flattened_seq_size, p->arena);
91
17.7k
    if (!flattened_seq) {
92
0
        return NULL;
93
0
    }
94
95
17.7k
    int flattened_seq_idx = 0;
96
102k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) {
97
85.2k
        asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i);
98
177k
        for (Py_ssize_t j = 0, li = asdl_seq_LEN(inner_seq); j < li; j++) {
99
92.7k
            asdl_seq_SET_UNTYPED(flattened_seq, flattened_seq_idx++, asdl_seq_GET_UNTYPED(inner_seq, j));
100
92.7k
        }
101
85.2k
    }
102
17.7k
    assert(flattened_seq_idx == flattened_seq_size);
103
104
17.7k
    return flattened_seq;
105
17.7k
}
106
107
void *
108
_PyPegen_seq_last_item(asdl_seq *seq)
109
80
{
110
80
    Py_ssize_t len = asdl_seq_LEN(seq);
111
80
    return asdl_seq_GET_UNTYPED(seq, len - 1);
112
80
}
113
114
void *
115
_PyPegen_seq_first_item(asdl_seq *seq)
116
38
{
117
38
    return asdl_seq_GET_UNTYPED(seq, 0);
118
38
}
119
120
/* Creates a new name of the form <first_name>.<second_name> */
121
expr_ty
122
_PyPegen_join_names_with_dot(Parser *p, expr_ty first_name, expr_ty second_name)
123
4.74k
{
124
4.74k
    assert(first_name != NULL && second_name != NULL);
125
4.74k
    PyObject *uni = PyUnicode_FromFormat("%U.%U",
126
4.74k
            first_name->v.Name.id, second_name->v.Name.id);
127
4.74k
    if (!uni) {
128
0
        return NULL;
129
0
    }
130
4.74k
    PyInterpreterState *interp = _PyInterpreterState_GET();
131
4.74k
    _PyUnicode_InternImmortal(interp, &uni);
132
4.74k
    if (_PyArena_AddPyObject(p->arena, uni) < 0) {
133
0
        Py_DECREF(uni);
134
0
        return NULL;
135
0
    }
136
137
4.74k
    return _PyAST_Name(uni, Load, EXTRA_EXPR(first_name, second_name));
138
4.74k
}
139
140
/* Counts the total number of dots in seq's tokens */
141
int
142
_PyPegen_seq_count_dots(asdl_seq *seq)
143
3.52k
{
144
3.52k
    int number_of_dots = 0;
145
7.41k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) {
146
3.89k
        Token *current_expr = asdl_seq_GET_UNTYPED(seq, i);
147
3.89k
        switch (current_expr->type) {
148
665
            case ELLIPSIS:
149
665
                number_of_dots += 3;
150
665
                break;
151
3.22k
            case DOT:
152
3.22k
                number_of_dots += 1;
153
3.22k
                break;
154
0
            default:
155
0
                Py_UNREACHABLE();
156
3.89k
        }
157
3.89k
    }
158
159
3.52k
    return number_of_dots;
160
3.52k
}
161
162
/* Creates an alias with '*' as the identifier name */
163
alias_ty
164
_PyPegen_alias_for_star(Parser *p, int lineno, int col_offset, int end_lineno,
165
265
                        int end_col_offset, PyArena *arena) {
166
265
    PyObject *str = PyUnicode_InternFromString("*");
167
265
    if (!str) {
168
0
        return NULL;
169
0
    }
170
265
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
171
0
        Py_DECREF(str);
172
0
        return NULL;
173
0
    }
174
265
    return _PyAST_alias(str, NULL, lineno, col_offset, end_lineno, end_col_offset, arena);
175
265
}
176
177
/* Creates a new asdl_seq* with the identifiers of all the names in seq */
178
asdl_identifier_seq *
179
_PyPegen_map_names_to_ids(Parser *p, asdl_expr_seq *seq)
180
1.98k
{
181
1.98k
    Py_ssize_t len = asdl_seq_LEN(seq);
182
1.98k
    assert(len > 0);
183
184
1.98k
    asdl_identifier_seq *new_seq = _Py_asdl_identifier_seq_new(len, p->arena);
185
1.98k
    if (!new_seq) {
186
0
        return NULL;
187
0
    }
188
7.21k
    for (Py_ssize_t i = 0; i < len; i++) {
189
5.22k
        expr_ty e = asdl_seq_GET(seq, i);
190
5.22k
        asdl_seq_SET(new_seq, i, e->v.Name.id);
191
5.22k
    }
192
1.98k
    return new_seq;
193
1.98k
}
194
195
/* Constructs a CmpopExprPair */
196
CmpopExprPair *
197
_PyPegen_cmpop_expr_pair(Parser *p, cmpop_ty cmpop, expr_ty expr)
198
14.5k
{
199
14.5k
    assert(expr != NULL);
200
14.5k
    CmpopExprPair *a = _PyArena_Malloc(p->arena, sizeof(CmpopExprPair));
201
14.5k
    if (!a) {
202
0
        return NULL;
203
0
    }
204
14.5k
    a->cmpop = cmpop;
205
14.5k
    a->expr = expr;
206
14.5k
    return a;
207
14.5k
}
208
209
asdl_int_seq *
210
_PyPegen_get_cmpops(Parser *p, asdl_seq *seq)
211
5.40k
{
212
5.40k
    Py_ssize_t len = asdl_seq_LEN(seq);
213
5.40k
    assert(len > 0);
214
215
5.40k
    asdl_int_seq *new_seq = _Py_asdl_int_seq_new(len, p->arena);
216
5.40k
    if (!new_seq) {
217
0
        return NULL;
218
0
    }
219
19.2k
    for (Py_ssize_t i = 0; i < len; i++) {
220
13.8k
        CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i);
221
13.8k
        asdl_seq_SET(new_seq, i, pair->cmpop);
222
13.8k
    }
223
5.40k
    return new_seq;
224
5.40k
}
225
226
asdl_expr_seq *
227
_PyPegen_get_exprs(Parser *p, asdl_seq *seq)
228
5.40k
{
229
5.40k
    Py_ssize_t len = asdl_seq_LEN(seq);
230
5.40k
    assert(len > 0);
231
232
5.40k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
233
5.40k
    if (!new_seq) {
234
0
        return NULL;
235
0
    }
236
19.2k
    for (Py_ssize_t i = 0; i < len; i++) {
237
13.8k
        CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i);
238
13.8k
        asdl_seq_SET(new_seq, i, pair->expr);
239
13.8k
    }
240
5.40k
    return new_seq;
241
5.40k
}
242
243
/* Creates an asdl_seq* where all the elements have been changed to have ctx as context */
244
static asdl_expr_seq *
245
_set_seq_context(Parser *p, asdl_expr_seq *seq, expr_context_ty ctx)
246
4.81k
{
247
4.81k
    Py_ssize_t len = asdl_seq_LEN(seq);
248
4.81k
    if (len == 0) {
249
2.68k
        return NULL;
250
2.68k
    }
251
252
2.12k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
253
2.12k
    if (!new_seq) {
254
0
        return NULL;
255
0
    }
256
6.33k
    for (Py_ssize_t i = 0; i < len; i++) {
257
4.21k
        expr_ty e = asdl_seq_GET(seq, i);
258
4.21k
        expr_ty new_e = _PyPegen_set_expr_context(p, e, ctx);
259
4.21k
        if (!new_e) {
260
0
            return NULL;
261
0
        }
262
4.21k
        asdl_seq_SET(new_seq, i, new_e);
263
4.21k
    }
264
2.12k
    return new_seq;
265
2.12k
}
266
267
static expr_ty
268
_set_name_context(Parser *p, expr_ty e, expr_context_ty ctx)
269
194k
{
270
194k
    return _PyAST_Name(e->v.Name.id, ctx, EXTRA_EXPR(e, e));
271
194k
}
272
273
static expr_ty
274
_set_tuple_context(Parser *p, expr_ty e, expr_context_ty ctx)
275
4.18k
{
276
4.18k
    asdl_expr_seq *seq = _set_seq_context(p, e->v.Tuple.elts, ctx);
277
4.18k
    if (!seq && PyErr_Occurred()) {
278
0
        return NULL;
279
0
    }
280
4.18k
    return _PyAST_Tuple(seq, ctx, EXTRA_EXPR(e, e));
281
4.18k
}
282
283
static expr_ty
284
_set_list_context(Parser *p, expr_ty e, expr_context_ty ctx)
285
624
{
286
624
    asdl_expr_seq *seq = _set_seq_context(p, e->v.List.elts, ctx);
287
624
    if (!seq && PyErr_Occurred()) {
288
0
        return NULL;
289
0
    }
290
624
    return _PyAST_List(seq, ctx, EXTRA_EXPR(e, e));
291
624
}
292
293
static expr_ty
294
_set_subscript_context(Parser *p, expr_ty e, expr_context_ty ctx)
295
689
{
296
689
    return _PyAST_Subscript(e->v.Subscript.value, e->v.Subscript.slice,
297
689
                            ctx, EXTRA_EXPR(e, e));
298
689
}
299
300
static expr_ty
301
_set_attribute_context(Parser *p, expr_ty e, expr_context_ty ctx)
302
214
{
303
214
    return _PyAST_Attribute(e->v.Attribute.value, e->v.Attribute.attr,
304
214
                            ctx, EXTRA_EXPR(e, e));
305
214
}
306
307
static expr_ty
308
_set_starred_context(Parser *p, expr_ty e, expr_context_ty ctx)
309
348
{
310
348
    expr_ty inner = _PyPegen_set_expr_context(p, e->v.Starred.value, ctx);
311
348
    if (!inner) {
312
0
        return NULL;
313
0
    }
314
348
    return _PyAST_Starred(inner, ctx, EXTRA_EXPR(e, e));
315
348
}
316
317
/* Creates an `expr_ty` equivalent to `expr` but with `ctx` as context */
318
expr_ty
319
_PyPegen_set_expr_context(Parser *p, expr_ty expr, expr_context_ty ctx)
320
200k
{
321
200k
    assert(expr != NULL);
322
323
200k
    expr_ty new = NULL;
324
200k
    switch (expr->kind) {
325
194k
        case Name_kind:
326
194k
            new = _set_name_context(p, expr, ctx);
327
194k
            break;
328
4.18k
        case Tuple_kind:
329
4.18k
            new = _set_tuple_context(p, expr, ctx);
330
4.18k
            break;
331
624
        case List_kind:
332
624
            new = _set_list_context(p, expr, ctx);
333
624
            break;
334
689
        case Subscript_kind:
335
689
            new = _set_subscript_context(p, expr, ctx);
336
689
            break;
337
214
        case Attribute_kind:
338
214
            new = _set_attribute_context(p, expr, ctx);
339
214
            break;
340
348
        case Starred_kind:
341
348
            new = _set_starred_context(p, expr, ctx);
342
348
            break;
343
0
        default:
344
0
            new = expr;
345
200k
    }
346
200k
    return new;
347
200k
}
348
349
/* Constructs a KeyValuePair that is used when parsing a dict's key value pairs */
350
KeyValuePair *
351
_PyPegen_key_value_pair(Parser *p, expr_ty key, expr_ty value)
352
32.1k
{
353
32.1k
    KeyValuePair *a = _PyArena_Malloc(p->arena, sizeof(KeyValuePair));
354
32.1k
    if (!a) {
355
0
        return NULL;
356
0
    }
357
32.1k
    a->key = key;
358
32.1k
    a->value = value;
359
32.1k
    return a;
360
32.1k
}
361
362
/* Extracts all keys from an asdl_seq* of KeyValuePair*'s */
363
asdl_expr_seq *
364
_PyPegen_get_keys(Parser *p, asdl_seq *seq)
365
4.38k
{
366
4.38k
    Py_ssize_t len = asdl_seq_LEN(seq);
367
4.38k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
368
4.38k
    if (!new_seq) {
369
0
        return NULL;
370
0
    }
371
25.0k
    for (Py_ssize_t i = 0; i < len; i++) {
372
20.6k
        KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i);
373
20.6k
        asdl_seq_SET(new_seq, i, pair->key);
374
20.6k
    }
375
4.38k
    return new_seq;
376
4.38k
}
377
378
/* Extracts all values from an asdl_seq* of KeyValuePair*'s */
379
asdl_expr_seq *
380
_PyPegen_get_values(Parser *p, asdl_seq *seq)
381
4.38k
{
382
4.38k
    Py_ssize_t len = asdl_seq_LEN(seq);
383
4.38k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
384
4.38k
    if (!new_seq) {
385
0
        return NULL;
386
0
    }
387
25.0k
    for (Py_ssize_t i = 0; i < len; i++) {
388
20.6k
        KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i);
389
20.6k
        asdl_seq_SET(new_seq, i, pair->value);
390
20.6k
    }
391
4.38k
    return new_seq;
392
4.38k
}
393
394
/* Constructs a KeyPatternPair that is used when parsing mapping & class patterns */
395
KeyPatternPair *
396
_PyPegen_key_pattern_pair(Parser *p, expr_ty key, pattern_ty pattern)
397
12.8k
{
398
12.8k
    KeyPatternPair *a = _PyArena_Malloc(p->arena, sizeof(KeyPatternPair));
399
12.8k
    if (!a) {
400
0
        return NULL;
401
0
    }
402
12.8k
    a->key = key;
403
12.8k
    a->pattern = pattern;
404
12.8k
    return a;
405
12.8k
}
406
407
/* Extracts all keys from an asdl_seq* of KeyPatternPair*'s */
408
asdl_expr_seq *
409
_PyPegen_get_pattern_keys(Parser *p, asdl_seq *seq)
410
1.48k
{
411
1.48k
    Py_ssize_t len = asdl_seq_LEN(seq);
412
1.48k
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
413
1.48k
    if (!new_seq) {
414
0
        return NULL;
415
0
    }
416
3.62k
    for (Py_ssize_t i = 0; i < len; i++) {
417
2.13k
        KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i);
418
2.13k
        asdl_seq_SET(new_seq, i, pair->key);
419
2.13k
    }
420
1.48k
    return new_seq;
421
1.48k
}
422
423
/* Extracts all patterns from an asdl_seq* of KeyPatternPair*'s */
424
asdl_pattern_seq *
425
_PyPegen_get_patterns(Parser *p, asdl_seq *seq)
426
1.48k
{
427
1.48k
    Py_ssize_t len = asdl_seq_LEN(seq);
428
1.48k
    asdl_pattern_seq *new_seq = _Py_asdl_pattern_seq_new(len, p->arena);
429
1.48k
    if (!new_seq) {
430
0
        return NULL;
431
0
    }
432
3.62k
    for (Py_ssize_t i = 0; i < len; i++) {
433
2.13k
        KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i);
434
2.13k
        asdl_seq_SET(new_seq, i, pair->pattern);
435
2.13k
    }
436
1.48k
    return new_seq;
437
1.48k
}
438
439
/* Constructs a NameDefaultPair */
440
NameDefaultPair *
441
_PyPegen_name_default_pair(Parser *p, arg_ty arg, expr_ty value, Token *tc)
442
553k
{
443
553k
    NameDefaultPair *a = _PyArena_Malloc(p->arena, sizeof(NameDefaultPair));
444
553k
    if (!a) {
445
0
        return NULL;
446
0
    }
447
553k
    a->arg = _PyPegen_add_type_comment_to_arg(p, arg, tc);
448
553k
    if (!a->arg) {
449
0
        return NULL;
450
0
    }
451
553k
    a->value = value;
452
553k
    return a;
453
553k
}
454
455
/* Constructs a SlashWithDefault */
456
SlashWithDefault *
457
_PyPegen_slash_with_default(Parser *p, asdl_arg_seq *plain_names, asdl_seq *names_with_defaults)
458
6.16k
{
459
6.16k
    SlashWithDefault *a = _PyArena_Malloc(p->arena, sizeof(SlashWithDefault));
460
6.16k
    if (!a) {
461
0
        return NULL;
462
0
    }
463
6.16k
    a->plain_names = plain_names;
464
6.16k
    a->names_with_defaults = names_with_defaults;
465
6.16k
    return a;
466
6.16k
}
467
468
/* Constructs a StarEtc */
469
StarEtc *
470
_PyPegen_star_etc(Parser *p, arg_ty vararg, asdl_seq *kwonlyargs, arg_ty kwarg)
471
5.19k
{
472
5.19k
    StarEtc *a = _PyArena_Malloc(p->arena, sizeof(StarEtc));
473
5.19k
    if (!a) {
474
0
        return NULL;
475
0
    }
476
5.19k
    a->vararg = vararg;
477
5.19k
    a->kwonlyargs = kwonlyargs;
478
5.19k
    a->kwarg = kwarg;
479
5.19k
    return a;
480
5.19k
}
481
482
asdl_seq *
483
_PyPegen_join_sequences(Parser *p, asdl_seq *a, asdl_seq *b)
484
332k
{
485
332k
    Py_ssize_t first_len = asdl_seq_LEN(a);
486
332k
    Py_ssize_t second_len = asdl_seq_LEN(b);
487
332k
    asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(first_len + second_len, p->arena);
488
332k
    if (!new_seq) {
489
0
        return NULL;
490
0
    }
491
492
332k
    int k = 0;
493
680k
    for (Py_ssize_t i = 0; i < first_len; i++) {
494
347k
        asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(a, i));
495
347k
    }
496
347k
    for (Py_ssize_t i = 0; i < second_len; i++) {
497
14.6k
        asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(b, i));
498
14.6k
    }
499
500
332k
    return new_seq;
501
332k
}
502
503
static asdl_arg_seq*
504
_get_names(Parser *p, asdl_seq *names_with_defaults)
505
338k
{
506
338k
    Py_ssize_t len = asdl_seq_LEN(names_with_defaults);
507
338k
    asdl_arg_seq *seq = _Py_asdl_arg_seq_new(len, p->arena);
508
338k
    if (!seq) {
509
0
        return NULL;
510
0
    }
511
351k
    for (Py_ssize_t i = 0; i < len; i++) {
512
13.4k
        NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i);
513
13.4k
        asdl_seq_SET(seq, i, pair->arg);
514
13.4k
    }
515
338k
    return seq;
516
338k
}
517
518
static asdl_expr_seq *
519
_get_defaults(Parser *p, asdl_seq *names_with_defaults)
520
338k
{
521
338k
    Py_ssize_t len = asdl_seq_LEN(names_with_defaults);
522
338k
    asdl_expr_seq *seq = _Py_asdl_expr_seq_new(len, p->arena);
523
338k
    if (!seq) {
524
0
        return NULL;
525
0
    }
526
351k
    for (Py_ssize_t i = 0; i < len; i++) {
527
13.4k
        NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i);
528
13.4k
        asdl_seq_SET(seq, i, pair->value);
529
13.4k
    }
530
338k
    return seq;
531
338k
}
532
533
static int
534
_make_posonlyargs(Parser *p,
535
                  asdl_arg_seq *slash_without_default,
536
                  SlashWithDefault *slash_with_default,
537
336k
                  asdl_arg_seq **posonlyargs) {
538
336k
    if (slash_without_default != NULL) {
539
1.09k
        *posonlyargs = slash_without_default;
540
1.09k
    }
541
335k
    else if (slash_with_default != NULL) {
542
1.92k
        asdl_arg_seq *slash_with_default_names =
543
1.92k
                _get_names(p, slash_with_default->names_with_defaults);
544
1.92k
        if (!slash_with_default_names) {
545
0
            return -1;
546
0
        }
547
1.92k
        *posonlyargs = (asdl_arg_seq*)_PyPegen_join_sequences(
548
1.92k
                p,
549
1.92k
                (asdl_seq*)slash_with_default->plain_names,
550
1.92k
                (asdl_seq*)slash_with_default_names);
551
1.92k
    }
552
333k
    else {
553
333k
        *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
554
333k
    }
555
336k
    return *posonlyargs == NULL ? -1 : 0;
556
336k
}
557
558
static int
559
_make_posargs(Parser *p,
560
              asdl_arg_seq *plain_names,
561
              asdl_seq *names_with_default,
562
336k
              asdl_arg_seq **posargs) {
563
564
336k
    if (names_with_default != NULL) {
565
332k
        if (plain_names != NULL) {
566
328k
            asdl_arg_seq *names_with_default_names = _get_names(p, names_with_default);
567
328k
            if (!names_with_default_names) {
568
0
                return -1;
569
0
            }
570
328k
            *posargs = (asdl_arg_seq*)_PyPegen_join_sequences(
571
328k
                    p,(asdl_seq*)plain_names, (asdl_seq*)names_with_default_names);
572
328k
        }
573
4.00k
        else {
574
4.00k
            *posargs = _get_names(p, names_with_default);
575
4.00k
        }
576
332k
    }
577
4.45k
    else {
578
4.45k
        if (plain_names != NULL) {
579
            // With the current grammar, we never get here.
580
            // If that has changed, remove the assert, and test thoroughly.
581
0
            assert(0);
582
0
            *posargs = plain_names;
583
0
        }
584
4.45k
        else {
585
4.45k
            *posargs = _Py_asdl_arg_seq_new(0, p->arena);
586
4.45k
        }
587
4.45k
    }
588
336k
    return *posargs == NULL ? -1 : 0;
589
336k
}
590
591
static int
592
_make_posdefaults(Parser *p,
593
                  SlashWithDefault *slash_with_default,
594
                  asdl_seq *names_with_default,
595
336k
                  asdl_expr_seq **posdefaults) {
596
336k
    if (slash_with_default != NULL && names_with_default != NULL) {
597
1.92k
        asdl_expr_seq *slash_with_default_values =
598
1.92k
                _get_defaults(p, slash_with_default->names_with_defaults);
599
1.92k
        if (!slash_with_default_values) {
600
0
            return -1;
601
0
        }
602
1.92k
        asdl_expr_seq *names_with_default_values = _get_defaults(p, names_with_default);
603
1.92k
        if (!names_with_default_values) {
604
0
            return -1;
605
0
        }
606
1.92k
        *posdefaults = (asdl_expr_seq*)_PyPegen_join_sequences(
607
1.92k
                p,
608
1.92k
                (asdl_seq*)slash_with_default_values,
609
1.92k
                (asdl_seq*)names_with_default_values);
610
1.92k
    }
611
334k
    else if (slash_with_default == NULL && names_with_default != NULL) {
612
330k
        *posdefaults = _get_defaults(p, names_with_default);
613
330k
    }
614
4.45k
    else if (slash_with_default != NULL && names_with_default == NULL) {
615
0
        *posdefaults = _get_defaults(p, slash_with_default->names_with_defaults);
616
0
    }
617
4.45k
    else {
618
4.45k
        *posdefaults = _Py_asdl_expr_seq_new(0, p->arena);
619
4.45k
    }
620
336k
    return *posdefaults == NULL ? -1 : 0;
621
336k
}
622
623
static int
624
_make_kwargs(Parser *p, StarEtc *star_etc,
625
             asdl_arg_seq **kwonlyargs,
626
336k
             asdl_expr_seq **kwdefaults) {
627
336k
    if (star_etc != NULL && star_etc->kwonlyargs != NULL) {
628
3.99k
        *kwonlyargs = _get_names(p, star_etc->kwonlyargs);
629
3.99k
    }
630
332k
    else {
631
332k
        *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
632
332k
    }
633
634
336k
    if (*kwonlyargs == NULL) {
635
0
        return -1;
636
0
    }
637
638
336k
    if (star_etc != NULL && star_etc->kwonlyargs != NULL) {
639
3.99k
        *kwdefaults = _get_defaults(p, star_etc->kwonlyargs);
640
3.99k
    }
641
332k
    else {
642
332k
        *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena);
643
332k
    }
644
645
336k
    if (*kwdefaults == NULL) {
646
0
        return -1;
647
0
    }
648
649
336k
    return 0;
650
336k
}
651
652
/* Constructs an arguments_ty object out of all the parsed constructs in the parameters rule */
653
arguments_ty
654
_PyPegen_make_arguments(Parser *p, asdl_arg_seq *slash_without_default,
655
                        SlashWithDefault *slash_with_default, asdl_arg_seq *plain_names,
656
                        asdl_seq *names_with_default, StarEtc *star_etc)
657
336k
{
658
336k
    asdl_arg_seq *posonlyargs;
659
336k
    if (_make_posonlyargs(p, slash_without_default, slash_with_default, &posonlyargs) == -1) {
660
0
        return NULL;
661
0
    }
662
663
336k
    asdl_arg_seq *posargs;
664
336k
    if (_make_posargs(p, plain_names, names_with_default, &posargs) == -1) {
665
0
        return NULL;
666
0
    }
667
668
336k
    asdl_expr_seq *posdefaults;
669
336k
    if (_make_posdefaults(p,slash_with_default, names_with_default, &posdefaults) == -1) {
670
0
        return NULL;
671
0
    }
672
673
336k
    arg_ty vararg = NULL;
674
336k
    if (star_etc != NULL && star_etc->vararg != NULL) {
675
2.60k
        vararg = star_etc->vararg;
676
2.60k
    }
677
678
336k
    asdl_arg_seq *kwonlyargs;
679
336k
    asdl_expr_seq *kwdefaults;
680
336k
    if (_make_kwargs(p, star_etc, &kwonlyargs, &kwdefaults) == -1) {
681
0
        return NULL;
682
0
    }
683
684
336k
    arg_ty kwarg = NULL;
685
336k
    if (star_etc != NULL && star_etc->kwarg != NULL) {
686
1.27k
        kwarg = star_etc->kwarg;
687
1.27k
    }
688
689
336k
    return _PyAST_arguments(posonlyargs, posargs, vararg, kwonlyargs,
690
336k
                            kwdefaults, kwarg, posdefaults, p->arena);
691
336k
}
692
693
694
/* Constructs an empty arguments_ty object, that gets used when a function accepts no
695
 * arguments. */
696
arguments_ty
697
_PyPegen_empty_arguments(Parser *p)
698
2.24k
{
699
2.24k
    asdl_arg_seq *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
700
2.24k
    if (!posonlyargs) {
701
0
        return NULL;
702
0
    }
703
2.24k
    asdl_arg_seq *posargs = _Py_asdl_arg_seq_new(0, p->arena);
704
2.24k
    if (!posargs) {
705
0
        return NULL;
706
0
    }
707
2.24k
    asdl_expr_seq *posdefaults = _Py_asdl_expr_seq_new(0, p->arena);
708
2.24k
    if (!posdefaults) {
709
0
        return NULL;
710
0
    }
711
2.24k
    asdl_arg_seq *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
712
2.24k
    if (!kwonlyargs) {
713
0
        return NULL;
714
0
    }
715
2.24k
    asdl_expr_seq *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena);
716
2.24k
    if (!kwdefaults) {
717
0
        return NULL;
718
0
    }
719
720
2.24k
    return _PyAST_arguments(posonlyargs, posargs, NULL, kwonlyargs,
721
2.24k
                            kwdefaults, NULL, posdefaults, p->arena);
722
2.24k
}
723
724
/* Encapsulates the value of an operator_ty into an AugOperator struct */
725
AugOperator *
726
_PyPegen_augoperator(Parser *p, operator_ty kind)
727
2.63k
{
728
2.63k
    AugOperator *a = _PyArena_Malloc(p->arena, sizeof(AugOperator));
729
2.63k
    if (!a) {
730
0
        return NULL;
731
0
    }
732
2.63k
    a->kind = kind;
733
2.63k
    return a;
734
2.63k
}
735
736
/* Construct a FunctionDef equivalent to function_def, but with decorators */
737
stmt_ty
738
_PyPegen_function_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty function_def)
739
432
{
740
432
    assert(function_def != NULL);
741
432
    if (function_def->kind == AsyncFunctionDef_kind) {
742
119
        return _PyAST_AsyncFunctionDef(
743
119
            function_def->v.AsyncFunctionDef.name,
744
119
            function_def->v.AsyncFunctionDef.args,
745
119
            function_def->v.AsyncFunctionDef.body, decorators,
746
119
            function_def->v.AsyncFunctionDef.returns,
747
119
            function_def->v.AsyncFunctionDef.type_comment,
748
119
            function_def->v.AsyncFunctionDef.type_params,
749
119
            function_def->lineno, function_def->col_offset,
750
119
            function_def->end_lineno, function_def->end_col_offset, p->arena);
751
119
    }
752
753
313
    return _PyAST_FunctionDef(
754
313
        function_def->v.FunctionDef.name,
755
313
        function_def->v.FunctionDef.args,
756
313
        function_def->v.FunctionDef.body, decorators,
757
313
        function_def->v.FunctionDef.returns,
758
313
        function_def->v.FunctionDef.type_comment,
759
313
        function_def->v.FunctionDef.type_params,
760
313
        function_def->lineno, function_def->col_offset,
761
313
        function_def->end_lineno, function_def->end_col_offset, p->arena);
762
432
}
763
764
/* Construct a ClassDef equivalent to class_def, but with decorators */
765
stmt_ty
766
_PyPegen_class_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty class_def)
767
179
{
768
179
    assert(class_def != NULL);
769
179
    return _PyAST_ClassDef(
770
179
        class_def->v.ClassDef.name,
771
179
        class_def->v.ClassDef.bases, class_def->v.ClassDef.keywords,
772
179
        class_def->v.ClassDef.body, decorators,
773
179
        class_def->v.ClassDef.type_params,
774
179
        class_def->lineno, class_def->col_offset, class_def->end_lineno,
775
179
        class_def->end_col_offset, p->arena);
776
179
}
777
778
/* Construct a KeywordOrStarred */
779
KeywordOrStarred *
780
_PyPegen_keyword_or_starred(Parser *p, void *element, int is_keyword)
781
40.6k
{
782
40.6k
    KeywordOrStarred *a = _PyArena_Malloc(p->arena, sizeof(KeywordOrStarred));
783
40.6k
    if (!a) {
784
0
        return NULL;
785
0
    }
786
40.6k
    a->element = element;
787
40.6k
    a->is_keyword = is_keyword;
788
40.6k
    return a;
789
40.6k
}
790
791
/* Get the number of starred expressions in an asdl_seq* of KeywordOrStarred*s */
792
static int
793
_seq_number_of_starred_exprs(asdl_seq *seq)
794
19.6k
{
795
19.6k
    int n = 0;
796
65.7k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) {
797
46.0k
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(seq, i);
798
46.0k
        if (!k->is_keyword) {
799
4.03k
            n++;
800
4.03k
        }
801
46.0k
    }
802
19.6k
    return n;
803
19.6k
}
804
805
/* Extract the starred expressions of an asdl_seq* of KeywordOrStarred*s */
806
asdl_expr_seq *
807
_PyPegen_seq_extract_starred_exprs(Parser *p, asdl_seq *kwargs)
808
9.82k
{
809
9.82k
    int new_len = _seq_number_of_starred_exprs(kwargs);
810
9.82k
    if (new_len == 0) {
811
9.19k
        return NULL;
812
9.19k
    }
813
633
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(new_len, p->arena);
814
633
    if (!new_seq) {
815
0
        return NULL;
816
0
    }
817
818
633
    int idx = 0;
819
3.86k
    for (Py_ssize_t i = 0, len = asdl_seq_LEN(kwargs); i < len; i++) {
820
3.23k
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i);
821
3.23k
        if (!k->is_keyword) {
822
2.01k
            asdl_seq_SET(new_seq, idx++, k->element);
823
2.01k
        }
824
3.23k
    }
825
633
    return new_seq;
826
633
}
827
828
/* Return a new asdl_seq* with only the keywords in kwargs */
829
asdl_keyword_seq*
830
_PyPegen_seq_delete_starred_exprs(Parser *p, asdl_seq *kwargs)
831
9.82k
{
832
9.82k
    Py_ssize_t len = asdl_seq_LEN(kwargs);
833
9.82k
    Py_ssize_t new_len = len - _seq_number_of_starred_exprs(kwargs);
834
9.82k
    if (new_len == 0) {
835
0
        return NULL;
836
0
    }
837
9.82k
    asdl_keyword_seq *new_seq = _Py_asdl_keyword_seq_new(new_len, p->arena);
838
9.82k
    if (!new_seq) {
839
0
        return NULL;
840
0
    }
841
842
9.82k
    int idx = 0;
843
32.8k
    for (Py_ssize_t i = 0; i < len; i++) {
844
23.0k
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i);
845
23.0k
        if (k->is_keyword) {
846
21.0k
            asdl_seq_SET(new_seq, idx++, k->element);
847
21.0k
        }
848
23.0k
    }
849
9.82k
    return new_seq;
850
9.82k
}
851
852
expr_ty
853
_PyPegen_ensure_imaginary(Parser *p, expr_ty exp)
854
1.69k
{
855
1.69k
    if (exp->kind != Constant_kind || !PyComplex_CheckExact(exp->v.Constant.value)) {
856
9
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(exp, "imaginary number required in complex literal");
857
9
        return NULL;
858
9
    }
859
1.68k
    return exp;
860
1.69k
}
861
862
expr_ty
863
_PyPegen_ensure_real(Parser *p, expr_ty exp)
864
3.44k
{
865
3.44k
    if (exp->kind != Constant_kind || PyComplex_CheckExact(exp->v.Constant.value)) {
866
6
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(exp, "real number required in complex literal");
867
6
        return NULL;
868
6
    }
869
3.43k
    return exp;
870
3.44k
}
871
872
mod_ty
873
7.56k
_PyPegen_make_module(Parser *p, asdl_stmt_seq *a) {
874
7.56k
    asdl_type_ignore_seq *type_ignores = NULL;
875
7.56k
    Py_ssize_t num = p->type_ignore_comments.num_items;
876
7.56k
    if (num > 0) {
877
        // Turn the raw (comment, lineno) pairs into TypeIgnore objects in the arena
878
0
        type_ignores = _Py_asdl_type_ignore_seq_new(num, p->arena);
879
0
        if (type_ignores == NULL) {
880
0
            return NULL;
881
0
        }
882
0
        for (Py_ssize_t i = 0; i < num; i++) {
883
0
            PyObject *tag = _PyPegen_new_type_comment(p, p->type_ignore_comments.items[i].comment);
884
0
            if (tag == NULL) {
885
0
                return NULL;
886
0
            }
887
0
            type_ignore_ty ti = _PyAST_TypeIgnore(p->type_ignore_comments.items[i].lineno,
888
0
                                                  tag, p->arena);
889
0
            if (ti == NULL) {
890
0
                return NULL;
891
0
            }
892
0
            asdl_seq_SET(type_ignores, i, ti);
893
0
        }
894
0
    }
895
7.56k
    return _PyAST_Module(a, type_ignores, p->arena);
896
7.56k
}
897
898
PyObject *
899
_PyPegen_new_type_comment(Parser *p, const char *s)
900
0
{
901
0
    PyObject *res = PyUnicode_DecodeUTF8(s, strlen(s), NULL);
902
0
    if (res == NULL) {
903
0
        return NULL;
904
0
    }
905
0
    if (_PyArena_AddPyObject(p->arena, res) < 0) {
906
0
        Py_DECREF(res);
907
0
        return NULL;
908
0
    }
909
0
    return res;
910
0
}
911
912
arg_ty
913
_PyPegen_add_type_comment_to_arg(Parser *p, arg_ty a, Token *tc)
914
603k
{
915
603k
    if (tc == NULL) {
916
603k
        return a;
917
603k
    }
918
0
    const char *bytes = PyBytes_AsString(tc->bytes);
919
0
    if (bytes == NULL) {
920
0
        return NULL;
921
0
    }
922
0
    PyObject *tco = _PyPegen_new_type_comment(p, bytes);
923
0
    if (tco == NULL) {
924
0
        return NULL;
925
0
    }
926
0
    return _PyAST_arg(a->arg, a->annotation, tco,
927
0
                      a->lineno, a->col_offset, a->end_lineno, a->end_col_offset,
928
0
                      p->arena);
929
0
}
930
931
/* Checks if the NOTEQUAL token is valid given the current parser flags
932
0 indicates success and nonzero indicates failure (an exception may be set) */
933
int
934
953
_PyPegen_check_barry_as_flufl(Parser *p, Token* t) {
935
953
    assert(t->bytes != NULL);
936
953
    assert(t->type == NOTEQUAL);
937
938
953
    const char* tok_str = PyBytes_AS_STRING(t->bytes);
939
953
    if (p->flags & PyPARSE_BARRY_AS_BDFL && strcmp(tok_str, "<>") != 0) {
940
1
        RAISE_SYNTAX_ERROR("with Barry as BDFL, use '<>' instead of '!='");
941
1
        return -1;
942
1
    }
943
952
    if (!(p->flags & PyPARSE_BARRY_AS_BDFL)) {
944
886
        return strcmp(tok_str, "!=");
945
886
    }
946
66
    return 0;
947
952
}
948
949
int
950
11.5k
_PyPegen_check_legacy_stmt(Parser *p, expr_ty name) {
951
11.5k
    if (name->kind != Name_kind) {
952
2.79k
        return 0;
953
2.79k
    }
954
8.74k
    const char* candidates[2] = {"print", "exec"};
955
25.9k
    for (int i=0; i<2; i++) {
956
17.4k
        if (PyUnicode_CompareWithASCIIString(name->v.Name.id, candidates[i]) == 0) {
957
245
            return 1;
958
245
        }
959
17.4k
    }
960
8.49k
    return 0;
961
8.74k
}
962
963
void *
964
_PyPegen_raise_error_for_missing_comma(Parser *p, expr_ty a, expr_ty b)
965
5.72k
{
966
    // Don't raise for legacy statements like "print x" or "exec x"
967
5.72k
    if (_PyPegen_check_legacy_stmt(p, a)) {
968
234
        return NULL;
969
234
    }
970
    // Only raise inside parentheses/brackets (level > 0)
971
5.48k
    if (p->tokens[p->mark - 1]->level == 0) {
972
5.32k
        return NULL;
973
5.32k
    }
974
    // For multi-line expressions (like string concatenations), point to the
975
    // last line instead of the first for a more helpful error message.
976
    // Use a->col_offset as the starting column since all strings in the
977
    // concatenation typically share the same indentation.
978
168
    if (a->end_lineno > a->lineno) {
979
9
        return RAISE_ERROR_KNOWN_LOCATION(
980
9
            p, PyExc_SyntaxError, a->end_lineno, a->col_offset,
981
9
            a->end_lineno, a->end_col_offset,
982
9
            "invalid syntax. Perhaps you forgot a comma?"
983
9
        );
984
9
    }
985
159
    return RAISE_ERROR_KNOWN_LOCATION(
986
159
        p, PyExc_SyntaxError, a->lineno, a->col_offset,
987
159
        b->end_lineno, b->end_col_offset,
988
159
        "invalid syntax. Perhaps you forgot a comma?"
989
159
    );
990
168
}
991
992
static ResultTokenWithMetadata *
993
result_token_with_metadata(Parser *p, void *result, PyObject *metadata)
994
9.11k
{
995
9.11k
    ResultTokenWithMetadata *res = _PyArena_Malloc(p->arena, sizeof(ResultTokenWithMetadata));
996
9.11k
    if (res == NULL) {
997
0
        return NULL;
998
0
    }
999
9.11k
    res->metadata = metadata;
1000
9.11k
    res->result = result;
1001
9.11k
    return res;
1002
9.11k
}
1003
1004
ResultTokenWithMetadata *
1005
_PyPegen_check_fstring_conversion(Parser *p, Token* conv_token, expr_ty conv)
1006
2.32k
{
1007
2.32k
    if (conv_token->lineno != conv->lineno || conv_token->end_col_offset != conv->col_offset) {
1008
3
        return RAISE_SYNTAX_ERROR_KNOWN_RANGE(
1009
3
            conv_token, conv,
1010
3
            "%c-string: conversion type must come right after the exclamation mark",
1011
3
            TOK_GET_STRING_PREFIX(p->tok)
1012
3
        );
1013
3
    }
1014
1015
2.32k
    Py_UCS4 first = PyUnicode_READ_CHAR(conv->v.Name.id, 0);
1016
2.32k
    if (PyUnicode_GET_LENGTH(conv->v.Name.id) > 1 ||
1017
2.31k
            !(first == 's' || first == 'r' || first == 'a')) {
1018
19
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(conv,
1019
19
                                            "%c-string: invalid conversion character %R: expected 's', 'r', or 'a'",
1020
19
                                            TOK_GET_STRING_PREFIX(p->tok),
1021
19
                                            conv->v.Name.id);
1022
19
        return NULL;
1023
19
    }
1024
1025
2.30k
    return result_token_with_metadata(p, conv, conv_token->metadata);
1026
2.32k
}
1027
1028
ResultTokenWithMetadata *
1029
_PyPegen_setup_full_format_spec(Parser *p, Token *colon, asdl_expr_seq *spec, int lineno, int col_offset,
1030
                                int end_lineno, int end_col_offset, PyArena *arena)
1031
6.81k
{
1032
6.81k
    if (!spec) {
1033
0
        return NULL;
1034
0
    }
1035
1036
    // This is needed to keep compatibility with 3.11, where an empty format
1037
    // spec is parsed as an *empty* JoinedStr node, instead of having an empty
1038
    // constant in it.
1039
6.81k
    Py_ssize_t n_items = asdl_seq_LEN(spec);
1040
6.81k
    Py_ssize_t non_empty_count = 0;
1041
17.3k
    for (Py_ssize_t i = 0; i < n_items; i++) {
1042
10.5k
        expr_ty item = asdl_seq_GET(spec, i);
1043
10.5k
        non_empty_count += !(item->kind == Constant_kind &&
1044
10.5k
                             PyUnicode_CheckExact(item->v.Constant.value) &&
1045
7.49k
                             PyUnicode_GET_LENGTH(item->v.Constant.value) == 0);
1046
10.5k
    }
1047
6.81k
    if (non_empty_count != n_items) {
1048
2.31k
        asdl_expr_seq *resized_spec =
1049
2.31k
            _Py_asdl_expr_seq_new(non_empty_count, p->arena);
1050
2.31k
        if (resized_spec == NULL) {
1051
0
            return NULL;
1052
0
        }
1053
2.31k
        Py_ssize_t j = 0;
1054
5.67k
        for (Py_ssize_t i = 0; i < n_items; i++) {
1055
3.35k
            expr_ty item = asdl_seq_GET(spec, i);
1056
3.35k
            if (item->kind == Constant_kind &&
1057
3.35k
                PyUnicode_CheckExact(item->v.Constant.value) &&
1058
2.63k
                PyUnicode_GET_LENGTH(item->v.Constant.value) == 0) {
1059
2.31k
                continue;
1060
2.31k
            }
1061
1.04k
            asdl_seq_SET(resized_spec, j++, item);
1062
1.04k
        }
1063
2.31k
        assert(j == non_empty_count);
1064
2.31k
        spec = resized_spec;
1065
2.31k
    }
1066
6.81k
    expr_ty res;
1067
6.81k
    Py_ssize_t n = asdl_seq_LEN(spec);
1068
6.81k
    if (n == 0 || (n == 1 && asdl_seq_GET(spec, 0)->kind == Constant_kind)) {
1069
6.16k
        res = _PyAST_JoinedStr(spec, lineno, col_offset, end_lineno,
1070
6.16k
                                    end_col_offset, p->arena);
1071
6.16k
    } else {
1072
652
        res = _PyPegen_concatenate_strings(p, spec,
1073
652
                             lineno, col_offset, end_lineno,
1074
652
                             end_col_offset, arena);
1075
652
    }
1076
6.81k
    if (!res) {
1077
0
        return NULL;
1078
0
    }
1079
6.81k
    return result_token_with_metadata(p, res, colon->metadata);
1080
6.81k
}
1081
1082
const char *
1083
_PyPegen_get_expr_name(expr_ty e)
1084
205
{
1085
205
    assert(e != NULL);
1086
205
    switch (e->kind) {
1087
2
        case Attribute_kind:
1088
2
            return "attribute";
1089
1
        case Subscript_kind:
1090
1
            return "subscript";
1091
4
        case Starred_kind:
1092
4
            return "starred";
1093
8
        case Name_kind:
1094
8
            return "name";
1095
1
        case List_kind:
1096
1
            return "list";
1097
4
        case Tuple_kind:
1098
4
            return "tuple";
1099
2
        case Lambda_kind:
1100
2
            return "lambda";
1101
11
        case Call_kind:
1102
11
            return "function call";
1103
7
        case BoolOp_kind:
1104
31
        case BinOp_kind:
1105
47
        case UnaryOp_kind:
1106
47
            return "expression";
1107
1
        case GeneratorExp_kind:
1108
1
            return "generator expression";
1109
1
        case Yield_kind:
1110
1
        case YieldFrom_kind:
1111
1
            return "yield expression";
1112
1
        case Await_kind:
1113
1
            return "await expression";
1114
1
        case ListComp_kind:
1115
1
            return "list comprehension";
1116
1
        case SetComp_kind:
1117
1
            return "set comprehension";
1118
2
        case DictComp_kind:
1119
2
            return "dict comprehension";
1120
2
        case Dict_kind:
1121
2
            return "dict literal";
1122
1
        case Set_kind:
1123
1
            return "set display";
1124
12
        case JoinedStr_kind:
1125
12
        case FormattedValue_kind:
1126
12
            return "f-string expression";
1127
3
        case TemplateStr_kind:
1128
3
        case Interpolation_kind:
1129
3
            return "t-string expression";
1130
84
        case Constant_kind: {
1131
84
            PyObject *value = e->v.Constant.value;
1132
84
            if (value == Py_None) {
1133
1
                return "None";
1134
1
            }
1135
83
            if (value == Py_False) {
1136
1
                return "False";
1137
1
            }
1138
82
            if (value == Py_True) {
1139
1
                return "True";
1140
1
            }
1141
81
            if (value == Py_Ellipsis) {
1142
1
                return "ellipsis";
1143
1
            }
1144
80
            return "literal";
1145
81
        }
1146
14
        case Compare_kind:
1147
14
            return "comparison";
1148
1
        case IfExp_kind:
1149
1
            return "conditional expression";
1150
1
        case NamedExpr_kind:
1151
1
            return "named expression";
1152
0
        default:
1153
0
            PyErr_Format(PyExc_SystemError,
1154
0
                         "unexpected expression in assignment %d (line %d)",
1155
0
                         e->kind, e->lineno);
1156
0
            return NULL;
1157
205
    }
1158
205
}
1159
1160
expr_ty
1161
12
_PyPegen_get_last_comprehension_item(comprehension_ty comprehension) {
1162
12
    if (comprehension->ifs == NULL || asdl_seq_LEN(comprehension->ifs) == 0) {
1163
8
        return comprehension->iter;
1164
8
    }
1165
4
    return PyPegen_last_item(comprehension->ifs, expr_ty);
1166
12
}
1167
1168
expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_expr_seq *a, asdl_seq *b,
1169
                     int lineno, int col_offset, int end_lineno,
1170
24.4k
                     int end_col_offset, PyArena *arena) {
1171
24.4k
    Py_ssize_t args_len = asdl_seq_LEN(a);
1172
24.4k
    Py_ssize_t total_len = args_len;
1173
1174
24.4k
    if (b == NULL) {
1175
22.3k
        return _PyAST_Call(_PyPegen_dummy_name(p), a, NULL, lineno, col_offset,
1176
22.3k
                        end_lineno, end_col_offset, arena);
1177
1178
22.3k
    }
1179
1180
2.17k
    asdl_expr_seq *starreds = _PyPegen_seq_extract_starred_exprs(p, b);
1181
2.17k
    if (!starreds && PyErr_Occurred()) {
1182
0
        return NULL;
1183
0
    }
1184
1185
2.17k
    asdl_keyword_seq *keywords = _PyPegen_seq_delete_starred_exprs(p, b);
1186
2.17k
    if (!keywords && PyErr_Occurred()) {
1187
0
        return NULL;
1188
0
    }
1189
1190
2.17k
    if (starreds) {
1191
359
        total_len += asdl_seq_LEN(starreds);
1192
359
    }
1193
1194
2.17k
    asdl_expr_seq *args = _Py_asdl_expr_seq_new(total_len, arena);
1195
2.17k
    if (args == NULL) {
1196
0
        return NULL;
1197
0
    }
1198
1199
2.17k
    Py_ssize_t i = 0;
1200
4.72k
    for (i = 0; i < args_len; i++) {
1201
2.55k
        asdl_seq_SET(args, i, asdl_seq_GET(a, i));
1202
2.55k
    }
1203
3.07k
    for (; i < total_len; i++) {
1204
905
        asdl_seq_SET(args, i, asdl_seq_GET(starreds, i - args_len));
1205
905
    }
1206
1207
2.17k
    return _PyAST_Call(_PyPegen_dummy_name(p), args, keywords, lineno,
1208
2.17k
                       col_offset, end_lineno, end_col_offset, arena);
1209
2.17k
}
1210
1211
// AST Error reporting helpers
1212
1213
expr_ty
1214
_PyPegen_get_invalid_target(expr_ty e, TARGETS_TYPE targets_type)
1215
8.56k
{
1216
8.56k
    if (e == NULL) {
1217
0
        return NULL;
1218
0
    }
1219
1220
8.56k
#define VISIT_CONTAINER(CONTAINER, TYPE) do { \
1221
2.33k
        Py_ssize_t len = asdl_seq_LEN((CONTAINER)->v.TYPE.elts);\
1222
7.03k
        for (Py_ssize_t i = 0; i < len; i++) {\
1223
4.98k
            expr_ty other = asdl_seq_GET((CONTAINER)->v.TYPE.elts, i);\
1224
4.98k
            expr_ty child = _PyPegen_get_invalid_target(other, targets_type);\
1225
4.98k
            if (child != NULL) {\
1226
285
                return child;\
1227
285
            }\
1228
4.98k
        }\
1229
2.33k
    } while (0)
1230
1231
    // We only need to visit List and Tuple nodes recursively as those
1232
    // are the only ones that can contain valid names in targets when
1233
    // they are parsed as expressions. Any other kind of expression
1234
    // that is a container (like Sets or Dicts) is directly invalid and
1235
    // we don't need to visit it recursively.
1236
1237
8.56k
    switch (e->kind) {
1238
753
        case List_kind:
1239
753
            VISIT_CONTAINER(e, List);
1240
668
            return NULL;
1241
1.58k
        case Tuple_kind:
1242
1.58k
            VISIT_CONTAINER(e, Tuple);
1243
1.38k
            return NULL;
1244
1.38k
        case Starred_kind:
1245
1.38k
            if (targets_type == DEL_TARGETS) {
1246
3
                return e;
1247
3
            }
1248
1.37k
            return _PyPegen_get_invalid_target(e->v.Starred.value, targets_type);
1249
1.07k
        case Compare_kind:
1250
            // This is needed, because the `a in b` in `for a in b` gets parsed
1251
            // as a comparison, and so we need to search the left side of the comparison
1252
            // for invalid targets.
1253
1.07k
            if (targets_type == FOR_TARGETS) {
1254
1.06k
                cmpop_ty cmpop = (cmpop_ty) asdl_seq_GET(e->v.Compare.ops, 0);
1255
1.06k
                if (cmpop == In) {
1256
251
                    return _PyPegen_get_invalid_target(e->v.Compare.left, targets_type);
1257
251
                }
1258
810
                return NULL;
1259
1.06k
            }
1260
12
            return e;
1261
2.67k
        case Name_kind:
1262
3.36k
        case Subscript_kind:
1263
3.64k
        case Attribute_kind:
1264
3.64k
            return NULL;
1265
130
        default:
1266
130
            return e;
1267
8.56k
    }
1268
8.56k
}
1269
1270
34
void *_PyPegen_arguments_parsing_error(Parser *p, expr_ty e) {
1271
34
    int kwarg_unpacking = 0;
1272
1.02k
    for (Py_ssize_t i = 0, l = asdl_seq_LEN(e->v.Call.keywords); i < l; i++) {
1273
988
        keyword_ty keyword = asdl_seq_GET(e->v.Call.keywords, i);
1274
988
        if (!keyword->arg) {
1275
610
            kwarg_unpacking = 1;
1276
610
        }
1277
988
    }
1278
1279
34
    const char *msg = NULL;
1280
34
    if (kwarg_unpacking) {
1281
20
        msg = "positional argument follows keyword argument unpacking";
1282
20
    } else {
1283
14
        msg = "positional argument follows keyword argument";
1284
14
    }
1285
1286
34
    return RAISE_SYNTAX_ERROR(msg);
1287
34
}
1288
1289
void *
1290
_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq *comprehensions)
1291
253
{
1292
    /* The rule that calls this function is 'args for_if_clauses'.
1293
       For the input f(L, x for x in y), L and x are in args and
1294
       the for is parsed as a for_if_clause. We have to check if
1295
       len <= 1, so that input like dict((a, b) for a, b in x)
1296
       gets successfully parsed and then we pass the last
1297
       argument (x in the above example) as the location of the
1298
       error */
1299
253
    Py_ssize_t len = asdl_seq_LEN(args->v.Call.args);
1300
253
    if (len <= 1) {
1301
251
        return NULL;
1302
251
    }
1303
1304
2
    comprehension_ty last_comprehension = PyPegen_last_item(comprehensions, comprehension_ty);
1305
1306
2
    return RAISE_SYNTAX_ERROR_KNOWN_RANGE(
1307
253
        (expr_ty) asdl_seq_GET(args->v.Call.args, len - 1),
1308
253
        _PyPegen_get_last_comprehension_item(last_comprehension),
1309
253
        "Generator expression must be parenthesized"
1310
253
    );
1311
253
}
1312
1313
// Fstring stuff
1314
1315
static expr_ty
1316
26.4k
_PyPegen_decode_fstring_part(Parser* p, int is_raw, expr_ty constant, Token* token) {
1317
26.4k
    assert(PyUnicode_CheckExact(constant->v.Constant.value));
1318
1319
26.4k
    const char* bstr = PyUnicode_AsUTF8(constant->v.Constant.value);
1320
26.4k
    if (bstr == NULL) {
1321
0
        return NULL;
1322
0
    }
1323
1324
26.4k
    size_t len;
1325
26.4k
    if (strcmp(bstr, "{{") == 0 || strcmp(bstr, "}}") == 0) {
1326
0
        len = 1;
1327
26.4k
    } else {
1328
26.4k
        len = strlen(bstr);
1329
26.4k
    }
1330
1331
26.4k
    is_raw = is_raw || strchr(bstr, '\\') == NULL;
1332
26.4k
    PyObject *str = _PyPegen_decode_string(p, is_raw, bstr, len, token);
1333
26.4k
    if (str == NULL) {
1334
12
        _Pypegen_raise_decode_error(p);
1335
12
        return NULL;
1336
12
    }
1337
26.3k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
1338
0
        Py_DECREF(str);
1339
0
        return NULL;
1340
0
    }
1341
26.3k
    return _PyAST_Constant(str, NULL, constant->lineno, constant->col_offset,
1342
26.3k
                           constant->end_lineno, constant->end_col_offset,
1343
26.3k
                           p->arena);
1344
26.3k
}
1345
1346
static asdl_expr_seq *
1347
_get_resized_exprs(Parser *p, Token *a, asdl_expr_seq *raw_expressions, Token *b, enum string_kind_t string_kind)
1348
20.5k
{
1349
20.5k
    Py_ssize_t n_items = asdl_seq_LEN(raw_expressions);
1350
20.5k
    Py_ssize_t total_items = n_items;
1351
68.6k
    for (Py_ssize_t i = 0; i < n_items; i++) {
1352
48.1k
        expr_ty item = asdl_seq_GET(raw_expressions, i);
1353
48.1k
        if (item->kind == JoinedStr_kind) {
1354
7.24k
            total_items += asdl_seq_LEN(item->v.JoinedStr.values) - 1;
1355
7.24k
        }
1356
48.1k
    }
1357
1358
20.5k
    const char* quote_str = PyBytes_AsString(a->bytes);
1359
20.5k
    if (quote_str == NULL) {
1360
0
        return NULL;
1361
0
    }
1362
20.5k
    int is_raw = strpbrk(quote_str, "rR") != NULL;
1363
1364
20.5k
    asdl_expr_seq *seq = _Py_asdl_expr_seq_new(total_items, p->arena);
1365
20.5k
    if (seq == NULL) {
1366
0
        return NULL;
1367
0
    }
1368
1369
20.5k
    Py_ssize_t index = 0;
1370
68.6k
    for (Py_ssize_t i = 0; i < n_items; i++) {
1371
48.1k
        expr_ty item = asdl_seq_GET(raw_expressions, i);
1372
1373
        // This should correspond to a JoinedStr node of two elements
1374
        // created _PyPegen_formatted_value. This situation can only be the result of
1375
        // a (f|t)-string debug expression where the first element is a constant with the text and the second
1376
        // a formatted value with the expression.
1377
48.1k
        if (item->kind == JoinedStr_kind) {
1378
7.24k
            asdl_expr_seq *values = item->v.JoinedStr.values;
1379
7.24k
            if (asdl_seq_LEN(values) != 2) {
1380
0
                PyErr_Format(PyExc_SystemError,
1381
0
                             string_kind == TSTRING
1382
0
                             ? "unexpected TemplateStr node without debug data in t-string at line %d"
1383
0
                             : "unexpected JoinedStr node without debug data in f-string at line %d",
1384
0
                             item->lineno);
1385
0
                return NULL;
1386
0
            }
1387
1388
7.24k
            expr_ty first = asdl_seq_GET(values, 0);
1389
7.24k
            assert(first->kind == Constant_kind);
1390
7.24k
            asdl_seq_SET(seq, index++, first);
1391
1392
7.24k
            expr_ty second = asdl_seq_GET(values, 1);
1393
7.24k
            assert((string_kind == TSTRING && second->kind == Interpolation_kind) || second->kind == FormattedValue_kind);
1394
7.24k
            asdl_seq_SET(seq, index++, second);
1395
1396
7.24k
            continue;
1397
7.24k
        }
1398
1399
40.8k
        if (item->kind == Constant_kind) {
1400
26.4k
            item = _PyPegen_decode_fstring_part(p, is_raw, item, b);
1401
26.4k
            if (item == NULL) {
1402
12
                return NULL;
1403
12
            }
1404
1405
            /* Tokenizer emits string parts even when the underlying string
1406
            might become an empty value (e.g. FSTRING_MIDDLE with the value \\n)
1407
            so we need to check for them and simplify it here. */
1408
26.3k
            if (PyUnicode_CheckExact(item->v.Constant.value)
1409
26.3k
                && PyUnicode_GET_LENGTH(item->v.Constant.value) == 0) {
1410
435
                continue;
1411
435
            }
1412
26.3k
        }
1413
40.4k
        asdl_seq_SET(seq, index++, item);
1414
40.4k
    }
1415
1416
20.5k
    asdl_expr_seq *resized_exprs;
1417
20.5k
    if (index != total_items) {
1418
435
        resized_exprs = _Py_asdl_expr_seq_new(index, p->arena);
1419
435
        if (resized_exprs == NULL) {
1420
0
            return NULL;
1421
0
        }
1422
1.56k
        for (Py_ssize_t i = 0; i < index; i++) {
1423
1.13k
            asdl_seq_SET(resized_exprs, i, asdl_seq_GET(seq, i));
1424
1.13k
        }
1425
435
    }
1426
20.1k
    else {
1427
20.1k
        resized_exprs = seq;
1428
20.1k
    }
1429
20.5k
    return resized_exprs;
1430
20.5k
}
1431
1432
expr_ty
1433
5.29k
_PyPegen_template_str(Parser *p, Token *a, asdl_expr_seq *raw_expressions, Token *b) {
1434
1435
5.29k
    asdl_expr_seq *resized_exprs = _get_resized_exprs(p, a, raw_expressions, b, TSTRING);
1436
5.29k
    if (resized_exprs == NULL) {
1437
2
        return NULL;
1438
2
    }
1439
5.29k
    return _PyAST_TemplateStr(resized_exprs, a->lineno, a->col_offset,
1440
5.29k
                              b->end_lineno, b->end_col_offset,
1441
5.29k
                              p->arena);
1442
5.29k
}
1443
1444
expr_ty
1445
15.2k
_PyPegen_joined_str(Parser *p, Token* a, asdl_expr_seq* raw_expressions, Token*b) {
1446
1447
15.2k
    asdl_expr_seq *resized_exprs = _get_resized_exprs(p, a, raw_expressions, b, FSTRING);
1448
15.2k
    if (resized_exprs == NULL) {
1449
10
        return NULL;
1450
10
    }
1451
15.2k
    return _PyAST_JoinedStr(resized_exprs, a->lineno, a->col_offset,
1452
15.2k
                            b->end_lineno, b->end_col_offset,
1453
15.2k
                            p->arena);
1454
15.2k
}
1455
1456
7.83k
expr_ty _PyPegen_decoded_constant_from_token(Parser* p, Token* tok) {
1457
7.83k
    Py_ssize_t bsize;
1458
7.83k
    char* bstr;
1459
7.83k
    if (PyBytes_AsStringAndSize(tok->bytes, &bstr, &bsize) == -1) {
1460
0
        return NULL;
1461
0
    }
1462
1463
    // Check if we're inside a raw f-string for format spec decoding
1464
7.83k
    int is_raw = 0;
1465
7.83k
    if (INSIDE_FSTRING(p->tok)) {
1466
5.74k
        tokenizer_mode *mode = TOK_GET_MODE(p->tok);
1467
5.74k
        is_raw = mode->raw;
1468
5.74k
    }
1469
1470
7.83k
    PyObject* str = _PyPegen_decode_string(p, is_raw, bstr, bsize, tok);
1471
7.83k
    if (str == NULL) {
1472
5
        return NULL;
1473
5
    }
1474
7.83k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
1475
0
        Py_DECREF(str);
1476
0
        return NULL;
1477
0
    }
1478
7.83k
    return _PyAST_Constant(str, NULL, tok->lineno, tok->col_offset,
1479
7.83k
                           tok->end_lineno, tok->end_col_offset,
1480
7.83k
                           p->arena);
1481
7.83k
}
1482
1483
30.8k
expr_ty _PyPegen_constant_from_token(Parser* p, Token* tok) {
1484
30.8k
    char* bstr = PyBytes_AsString(tok->bytes);
1485
30.8k
    if (bstr == NULL) {
1486
0
        return NULL;
1487
0
    }
1488
30.8k
    PyObject* str = PyUnicode_FromString(bstr);
1489
30.8k
    if (str == NULL) {
1490
0
        return NULL;
1491
0
    }
1492
30.8k
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
1493
0
        Py_DECREF(str);
1494
0
        return NULL;
1495
0
    }
1496
30.8k
    return _PyAST_Constant(str, NULL, tok->lineno, tok->col_offset,
1497
30.8k
                           tok->end_lineno, tok->end_col_offset,
1498
30.8k
                           p->arena);
1499
30.8k
}
1500
1501
52.8k
expr_ty _PyPegen_constant_from_string(Parser* p, Token* tok) {
1502
52.8k
    char* the_str = PyBytes_AsString(tok->bytes);
1503
52.8k
    if (the_str == NULL) {
1504
0
        return NULL;
1505
0
    }
1506
52.8k
    PyObject *s = _PyPegen_parse_string(p, tok);
1507
52.8k
    if (s == NULL) {
1508
116
        _Pypegen_raise_decode_error(p);
1509
116
        return NULL;
1510
116
    }
1511
52.7k
    if (_PyArena_AddPyObject(p->arena, s) < 0) {
1512
0
        Py_DECREF(s);
1513
0
        return NULL;
1514
0
    }
1515
52.7k
    PyObject *kind = NULL;
1516
52.7k
    if (the_str && the_str[0] == 'u') {
1517
1.43k
        kind = _PyPegen_new_identifier(p, "u");
1518
1.43k
        if (kind == NULL) {
1519
0
            return NULL;
1520
0
        }
1521
1.43k
    }
1522
52.7k
    return _PyAST_Constant(s, kind, tok->lineno, tok->col_offset, tok->end_lineno, tok->end_col_offset, p->arena);
1523
52.7k
}
1524
1525
static int
1526
_get_interpolation_conversion(Parser *p, Token *debug, ResultTokenWithMetadata *conversion,
1527
                              ResultTokenWithMetadata *format)
1528
28.0k
{
1529
28.0k
    if (conversion != NULL) {
1530
2.27k
        expr_ty conversion_expr = (expr_ty) conversion->result;
1531
2.27k
        assert(conversion_expr->kind == Name_kind);
1532
2.27k
        Py_UCS4 first = PyUnicode_READ_CHAR(conversion_expr->v.Name.id, 0);
1533
2.27k
        return Py_SAFE_DOWNCAST(first, Py_UCS4, int);
1534
2.27k
    }
1535
25.7k
    else if (debug && !format) {
1536
        /* If no conversion is specified, use !r for debug expressions */
1537
7.59k
        return (int)'r';
1538
7.59k
    }
1539
18.1k
    return -1;
1540
28.0k
}
1541
1542
static PyObject *
1543
_strip_interpolation_expr(PyObject *exprstr)
1544
7.48k
{
1545
7.48k
    Py_ssize_t len = PyUnicode_GET_LENGTH(exprstr);
1546
1547
14.8k
    for (Py_ssize_t i = len - 1; i >= 0; i--) {
1548
14.8k
        Py_UCS4 c = PyUnicode_READ_CHAR(exprstr, i);
1549
14.8k
        if (_PyUnicode_IsWhitespace(c) || c == '=') {
1550
7.40k
            len--;
1551
7.40k
        }
1552
7.48k
        else {
1553
7.48k
            break;
1554
7.48k
        }
1555
14.8k
    }
1556
1557
7.48k
    return PyUnicode_Substring(exprstr, 0, len);
1558
7.48k
}
1559
1560
expr_ty _PyPegen_interpolation(Parser *p, expr_ty expression, Token *debug, ResultTokenWithMetadata *conversion,
1561
                                 ResultTokenWithMetadata *format, Token *closing_brace, int lineno, int col_offset,
1562
7.48k
                                 int end_lineno, int end_col_offset, PyArena *arena) {
1563
1564
7.48k
    int conversion_val = _get_interpolation_conversion(p, debug, conversion, format);
1565
1566
    /* Find the non whitespace token after the "=" */
1567
7.48k
    int debug_end_line, debug_end_offset;
1568
7.48k
    PyObject *debug_metadata;
1569
7.48k
    constant exprstr;
1570
1571
7.48k
    if (conversion) {
1572
492
        debug_end_line = ((expr_ty) conversion->result)->lineno;
1573
492
        debug_end_offset = ((expr_ty) conversion->result)->col_offset;
1574
492
        debug_metadata = exprstr = conversion->metadata;
1575
492
    }
1576
6.98k
    else if (format) {
1577
1.23k
        debug_end_line = ((expr_ty) format->result)->lineno;
1578
1.23k
        debug_end_offset = ((expr_ty) format->result)->col_offset + 1;
1579
1.23k
        debug_metadata = exprstr = format->metadata;
1580
1.23k
    }
1581
5.75k
    else {
1582
5.75k
        debug_end_line = end_lineno;
1583
5.75k
        debug_end_offset = end_col_offset;
1584
5.75k
        debug_metadata = exprstr = closing_brace->metadata;
1585
5.75k
    }
1586
1587
7.48k
    assert(exprstr != NULL);
1588
7.48k
    PyObject *final_exprstr = _strip_interpolation_expr(exprstr);
1589
7.48k
    if (!final_exprstr || _PyArena_AddPyObject(arena, final_exprstr) < 0) {
1590
0
        Py_XDECREF(final_exprstr);
1591
0
        return NULL;
1592
0
    }
1593
1594
7.48k
    expr_ty interpolation = _PyAST_Interpolation(
1595
7.48k
        expression, final_exprstr, conversion_val, format ? (expr_ty) format->result : NULL,
1596
7.48k
        lineno, col_offset, end_lineno,
1597
7.48k
        end_col_offset, arena
1598
7.48k
    );
1599
1600
7.48k
    if (!interpolation || !debug) {
1601
6.63k
        return interpolation;
1602
6.63k
    }
1603
1604
844
    expr_ty debug_text = _PyAST_Constant(debug_metadata, NULL, lineno, col_offset + 1, debug_end_line,
1605
844
                                            debug_end_offset - 1, p->arena);
1606
844
    if (!debug_text) {
1607
0
        return NULL;
1608
0
    }
1609
1610
844
    asdl_expr_seq *values = _Py_asdl_expr_seq_new(2, arena);
1611
844
    if (!values) {
1612
0
        return NULL;
1613
0
    }
1614
844
    asdl_seq_SET(values, 0, debug_text);
1615
844
    asdl_seq_SET(values, 1, interpolation);
1616
844
    return _PyAST_JoinedStr(values, lineno, col_offset, debug_end_line, debug_end_offset, p->arena);
1617
844
}
1618
1619
expr_ty _PyPegen_formatted_value(Parser *p, expr_ty expression, Token *debug, ResultTokenWithMetadata *conversion,
1620
                                 ResultTokenWithMetadata *format, Token *closing_brace, int lineno, int col_offset,
1621
20.5k
                                 int end_lineno, int end_col_offset, PyArena *arena) {
1622
20.5k
    int conversion_val = _get_interpolation_conversion(p, debug, conversion, format);
1623
1624
20.5k
    expr_ty formatted_value = _PyAST_FormattedValue(
1625
20.5k
        expression, conversion_val, format ? (expr_ty) format->result : NULL,
1626
20.5k
        lineno, col_offset, end_lineno,
1627
20.5k
        end_col_offset, arena
1628
20.5k
    );
1629
1630
20.5k
    if (!formatted_value || !debug) {
1631
13.3k
        return formatted_value;
1632
13.3k
    }
1633
1634
    /* Find the non whitespace token after the "=" */
1635
7.25k
    int debug_end_line, debug_end_offset;
1636
7.25k
    PyObject *debug_metadata;
1637
1638
7.25k
    if (conversion) {
1639
205
        debug_end_line = ((expr_ty) conversion->result)->lineno;
1640
205
        debug_end_offset = ((expr_ty) conversion->result)->col_offset;
1641
205
        debug_metadata = conversion->metadata;
1642
205
    }
1643
7.04k
    else if (format) {
1644
211
        debug_end_line = ((expr_ty) format->result)->lineno;
1645
211
        debug_end_offset = ((expr_ty) format->result)->col_offset + 1;
1646
211
        debug_metadata = format->metadata;
1647
211
    }
1648
6.83k
    else {
1649
6.83k
        debug_end_line = end_lineno;
1650
6.83k
        debug_end_offset = end_col_offset;
1651
6.83k
        debug_metadata = closing_brace->metadata;
1652
6.83k
    }
1653
7.25k
    expr_ty debug_text = _PyAST_Constant(debug_metadata, NULL, lineno, col_offset + 1, debug_end_line,
1654
7.25k
                                            debug_end_offset - 1, p->arena);
1655
7.25k
    if (!debug_text) {
1656
3
        return NULL;
1657
3
    }
1658
1659
7.25k
    asdl_expr_seq *values = _Py_asdl_expr_seq_new(2, arena);
1660
7.25k
    if (!values) {
1661
0
        return NULL;
1662
0
    }
1663
7.25k
    asdl_seq_SET(values, 0, debug_text);
1664
7.25k
    asdl_seq_SET(values, 1, formatted_value);
1665
7.25k
    return _PyAST_JoinedStr(values, lineno, col_offset, debug_end_line, debug_end_offset, p->arena);
1666
7.25k
}
1667
1668
static expr_ty
1669
_build_concatenated_bytes(Parser *p, asdl_expr_seq *strings, int lineno,
1670
                        int col_offset, int end_lineno, int end_col_offset,
1671
                        PyArena *arena)
1672
701
{
1673
701
    Py_ssize_t len = asdl_seq_LEN(strings);
1674
701
    assert(len > 0);
1675
1676
    /* Bytes literals never get a kind, but just for consistency
1677
        since they are represented as Constant nodes, we'll mirror
1678
        the same behavior as unicode strings for determining the
1679
        kind. */
1680
701
    PyObject *kind = asdl_seq_GET(strings, 0)->v.Constant.kind;
1681
1682
701
    Py_ssize_t total = 0;
1683
3.37k
    for (Py_ssize_t i = 0; i < len; i++) {
1684
2.67k
        expr_ty elem = asdl_seq_GET(strings, i);
1685
2.67k
        PyObject *bytes = elem->v.Constant.value;
1686
2.67k
        Py_ssize_t part = PyBytes_GET_SIZE(bytes);
1687
2.67k
        if (part > PY_SSIZE_T_MAX - total) {
1688
0
            PyErr_NoMemory();
1689
0
            return NULL;
1690
0
        }
1691
2.67k
        total += part;
1692
2.67k
    }
1693
1694
701
    PyBytesWriter *writer = PyBytesWriter_Create(total);
1695
701
    if (writer == NULL) {
1696
0
        return NULL;
1697
0
    }
1698
701
    char *out = PyBytesWriter_GetData(writer);
1699
1700
3.37k
    for (Py_ssize_t i = 0; i < len; i++) {
1701
2.67k
        expr_ty elem = asdl_seq_GET(strings, i);
1702
2.67k
        PyObject *bytes = elem->v.Constant.value;
1703
2.67k
        Py_ssize_t part = PyBytes_GET_SIZE(bytes);
1704
2.67k
        if (part > 0) {
1705
1.10k
            memcpy(out, PyBytes_AS_STRING(bytes), part);
1706
1.10k
            out += part;
1707
1.10k
        }
1708
2.67k
    }
1709
1710
701
    PyObject *res = PyBytesWriter_Finish(writer);
1711
701
    if (res == NULL) {
1712
0
        return NULL;
1713
0
    }
1714
701
    if (_PyArena_AddPyObject(arena, res) < 0) {
1715
0
        Py_DECREF(res);
1716
0
        return NULL;
1717
0
    }
1718
701
    return _PyAST_Constant(res, kind, lineno, col_offset, end_lineno, end_col_offset, p->arena);
1719
701
}
1720
1721
static expr_ty
1722
_build_concatenated_unicode(Parser *p, asdl_expr_seq *strings, int lineno,
1723
                        int col_offset, int end_lineno, int end_col_offset,
1724
                        PyArena *arena)
1725
1.66k
{
1726
1.66k
    Py_ssize_t len = asdl_seq_LEN(strings);
1727
1.66k
    assert(len > 1);
1728
1729
1.66k
    expr_ty first = asdl_seq_GET(strings, 0);
1730
1731
    /* When a string is getting concatenated, the kind of the string
1732
        is determined by the first string in the concatenation
1733
        sequence.
1734
1735
        u"abc" "def" -> u"abcdef"
1736
        "abc" u"abc" ->  "abcabc" */
1737
1.66k
    PyObject *kind = first->v.Constant.kind;
1738
1739
1.66k
    PyUnicodeWriter *writer = PyUnicodeWriter_Create(0);
1740
1.66k
    if (writer == NULL) {
1741
0
        return NULL;
1742
0
    }
1743
1744
23.3k
    for (Py_ssize_t i = 0; i < len; i++) {
1745
21.6k
        expr_ty current_elem = asdl_seq_GET(strings, i);
1746
21.6k
        assert(current_elem->kind == Constant_kind);
1747
1748
21.6k
        if (PyUnicodeWriter_WriteStr(writer,
1749
21.6k
                                     current_elem->v.Constant.value)) {
1750
0
            PyUnicodeWriter_Discard(writer);
1751
0
            return NULL;
1752
0
        }
1753
21.6k
    }
1754
1755
1.66k
    PyObject *final = PyUnicodeWriter_Finish(writer);
1756
1.66k
    if (final == NULL) {
1757
0
        return NULL;
1758
0
    }
1759
1.66k
    if (_PyArena_AddPyObject(p->arena, final) < 0) {
1760
0
        Py_DECREF(final);
1761
0
        return NULL;
1762
0
    }
1763
1.66k
    return _PyAST_Constant(final, kind, lineno, col_offset,
1764
1.66k
                           end_lineno, end_col_offset, arena);
1765
1.66k
}
1766
1767
static asdl_expr_seq *
1768
_build_concatenated_str(Parser *p, asdl_expr_seq *strings,
1769
                               int lineno, int col_offset, int end_lineno,
1770
                               int end_col_offset, PyArena *arena)
1771
14.7k
{
1772
14.7k
    Py_ssize_t len = asdl_seq_LEN(strings);
1773
14.7k
    assert(len > 0);
1774
1775
14.7k
    Py_ssize_t n_flattened_elements = 0;
1776
41.7k
    for (Py_ssize_t i = 0; i < len; i++) {
1777
27.0k
        expr_ty elem = asdl_seq_GET(strings, i);
1778
27.0k
        switch(elem->kind) {
1779
13.2k
            case JoinedStr_kind:
1780
13.2k
                n_flattened_elements += asdl_seq_LEN(elem->v.JoinedStr.values);
1781
13.2k
                break;
1782
4.88k
            case TemplateStr_kind:
1783
4.88k
                n_flattened_elements += asdl_seq_LEN(elem->v.TemplateStr.values);
1784
4.88k
                break;
1785
8.82k
            default:
1786
8.82k
                n_flattened_elements++;
1787
8.82k
                break;
1788
27.0k
        }
1789
27.0k
    }
1790
1791
1792
14.7k
    asdl_expr_seq* flattened = _Py_asdl_expr_seq_new(n_flattened_elements, p->arena);
1793
14.7k
    if (flattened == NULL) {
1794
0
        return NULL;
1795
0
    }
1796
1797
    /* build flattened list */
1798
14.7k
    Py_ssize_t current_pos = 0;
1799
41.7k
    for (Py_ssize_t i = 0; i < len; i++) {
1800
27.0k
        expr_ty elem = asdl_seq_GET(strings, i);
1801
27.0k
        switch(elem->kind) {
1802
13.2k
            case JoinedStr_kind:
1803
54.2k
                for (Py_ssize_t j = 0; j < asdl_seq_LEN(elem->v.JoinedStr.values); j++) {
1804
40.9k
                    expr_ty subvalue = asdl_seq_GET(elem->v.JoinedStr.values, j);
1805
40.9k
                    if (subvalue == NULL) {
1806
0
                        return NULL;
1807
0
                    }
1808
40.9k
                    asdl_seq_SET(flattened, current_pos++, subvalue);
1809
40.9k
                }
1810
13.2k
                break;
1811
13.2k
            case TemplateStr_kind:
1812
14.6k
                for (Py_ssize_t j = 0; j < asdl_seq_LEN(elem->v.TemplateStr.values); j++) {
1813
9.77k
                    expr_ty subvalue = asdl_seq_GET(elem->v.TemplateStr.values, j);
1814
9.77k
                    if (subvalue == NULL) {
1815
0
                        return NULL;
1816
0
                    }
1817
9.77k
                    asdl_seq_SET(flattened, current_pos++, subvalue);
1818
9.77k
                }
1819
4.88k
                break;
1820
8.82k
            default:
1821
8.82k
                asdl_seq_SET(flattened, current_pos++, elem);
1822
8.82k
                break;
1823
27.0k
        }
1824
27.0k
    }
1825
1826
    /* calculate folded element count */
1827
14.7k
    Py_ssize_t n_elements = 0;
1828
14.7k
    int prev_is_constant = 0;
1829
74.3k
    for (Py_ssize_t i = 0; i < n_flattened_elements; i++) {
1830
59.5k
        expr_ty elem = asdl_seq_GET(flattened, i);
1831
1832
        /* The concatenation of a FormattedValue and an empty Constant should
1833
           lead to the FormattedValue itself. Thus, we will not take any empty
1834
           constants into account, just as in `_PyPegen_joined_str` */
1835
59.5k
        if (elem->kind == Constant_kind &&
1836
59.5k
            PyUnicode_CheckExact(elem->v.Constant.value) &&
1837
35.7k
            PyUnicode_GET_LENGTH(elem->v.Constant.value) == 0)
1838
1.14k
            continue;
1839
1840
58.3k
        if (!prev_is_constant || elem->kind != Constant_kind) {
1841
48.7k
            n_elements++;
1842
48.7k
        }
1843
58.3k
        prev_is_constant = elem->kind == Constant_kind;
1844
58.3k
    }
1845
1846
14.7k
    asdl_expr_seq* values = _Py_asdl_expr_seq_new(n_elements, p->arena);
1847
14.7k
    if (values == NULL) {
1848
0
        return NULL;
1849
0
    }
1850
1851
    /* build folded list */
1852
14.7k
    current_pos = 0;
1853
63.8k
    for (Py_ssize_t i = 0; i < n_flattened_elements; i++) {
1854
49.0k
        expr_ty elem = asdl_seq_GET(flattened, i);
1855
1856
        /* if the current elem and the following are constants,
1857
           fold them and all consequent constants */
1858
49.0k
        if (elem->kind == Constant_kind) {
1859
25.2k
            if (i + 1 < n_flattened_elements &&
1860
19.8k
                asdl_seq_GET(flattened, i + 1)->kind == Constant_kind) {
1861
3.58k
                expr_ty first_elem = elem;
1862
1863
                /* When a string is getting concatenated, the kind of the string
1864
                   is determined by the first string in the concatenation
1865
                   sequence.
1866
1867
                   u"abc" "def" -> u"abcdef"
1868
                   "abc" u"abc" ->  "abcabc" */
1869
3.58k
                PyObject *kind = elem->v.Constant.kind;
1870
1871
3.58k
                PyUnicodeWriter *writer = PyUnicodeWriter_Create(0);
1872
3.58k
                if (writer == NULL) {
1873
0
                    return NULL;
1874
0
                }
1875
3.58k
                expr_ty last_elem = elem;
1876
3.58k
                Py_ssize_t j;
1877
17.6k
                for (j = i; j < n_flattened_elements; j++) {
1878
15.8k
                    expr_ty current_elem = asdl_seq_GET(flattened, j);
1879
15.8k
                    if (current_elem->kind == Constant_kind) {
1880
14.0k
                        if (PyUnicodeWriter_WriteStr(writer,
1881
14.0k
                                                     current_elem->v.Constant.value)) {
1882
0
                            PyUnicodeWriter_Discard(writer);
1883
0
                            return NULL;
1884
0
                        }
1885
14.0k
                        last_elem = current_elem;
1886
14.0k
                    } else {
1887
1.81k
                        break;
1888
1.81k
                    }
1889
15.8k
                }
1890
3.58k
                i = j - 1;
1891
1892
3.58k
                PyObject *concat_str = PyUnicodeWriter_Finish(writer);
1893
3.58k
                if (concat_str == NULL) {
1894
0
                    return NULL;
1895
0
                }
1896
3.58k
                if (_PyArena_AddPyObject(p->arena, concat_str) < 0) {
1897
0
                    Py_DECREF(concat_str);
1898
0
                    return NULL;
1899
0
                }
1900
3.58k
                elem = _PyAST_Constant(concat_str, kind, first_elem->lineno,
1901
3.58k
                                       first_elem->col_offset,
1902
3.58k
                                       last_elem->end_lineno,
1903
3.58k
                                       last_elem->end_col_offset, p->arena);
1904
3.58k
                if (elem == NULL) {
1905
0
                    return NULL;
1906
0
                }
1907
3.58k
            }
1908
1909
            /* Drop all empty contanst strings */
1910
25.2k
            if (PyUnicode_CheckExact(elem->v.Constant.value) &&
1911
25.2k
                PyUnicode_GET_LENGTH(elem->v.Constant.value) == 0) {
1912
279
                continue;
1913
279
            }
1914
25.2k
        }
1915
1916
48.7k
        asdl_seq_SET(values, current_pos++, elem);
1917
48.7k
    }
1918
1919
14.7k
    assert(current_pos == n_elements);
1920
14.7k
    return values;
1921
14.7k
}
1922
1923
static expr_ty
1924
_build_concatenated_joined_str(Parser *p, asdl_expr_seq *strings,
1925
                               int lineno, int col_offset, int end_lineno,
1926
                               int end_col_offset, PyArena *arena)
1927
10.6k
{
1928
10.6k
    asdl_expr_seq *values = _build_concatenated_str(p, strings, lineno,
1929
10.6k
        col_offset, end_lineno, end_col_offset, arena);
1930
10.6k
    if (!values) {
1931
0
        return NULL;
1932
0
    }
1933
10.6k
    return _PyAST_JoinedStr(values, lineno, col_offset, end_lineno, end_col_offset, p->arena);
1934
10.6k
}
1935
1936
expr_ty
1937
_PyPegen_concatenate_tstrings(Parser *p, asdl_expr_seq *strings,
1938
                               int lineno, int col_offset, int end_lineno,
1939
                               int end_col_offset, PyArena *arena)
1940
4.17k
{
1941
4.17k
    asdl_expr_seq *values = _build_concatenated_str(p, strings, lineno,
1942
4.17k
        col_offset, end_lineno, end_col_offset, arena);
1943
4.17k
    if (!values) {
1944
0
        return NULL;
1945
0
    }
1946
4.17k
    return _PyAST_TemplateStr(values, lineno, col_offset, end_lineno,
1947
4.17k
        end_col_offset, arena);
1948
4.17k
}
1949
1950
expr_ty
1951
_PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings,
1952
                             int lineno, int col_offset, int end_lineno,
1953
                             int end_col_offset, PyArena *arena)
1954
29.2k
{
1955
29.2k
    Py_ssize_t len = asdl_seq_LEN(strings);
1956
29.2k
    assert(len > 0);
1957
1958
29.2k
    int f_string_found = 0;
1959
29.2k
    int unicode_string_found = 0;
1960
29.2k
    int bytes_found = 0;
1961
1962
29.2k
    Py_ssize_t i = 0;
1963
92.0k
    for (i = 0; i < len; i++) {
1964
62.7k
        expr_ty elem = asdl_seq_GET(strings, i);
1965
62.7k
        switch(elem->kind) {
1966
46.5k
            case Constant_kind:
1967
46.5k
                if (PyBytes_CheckExact(elem->v.Constant.value)) {
1968
4.64k
                    bytes_found = 1;
1969
41.9k
                } else {
1970
41.9k
                    unicode_string_found = 1;
1971
41.9k
                }
1972
46.5k
                break;
1973
13.2k
            case JoinedStr_kind:
1974
13.2k
                f_string_found = 1;
1975
13.2k
                break;
1976
0
            case TemplateStr_kind:
1977
                // python.gram handles this; we should never get here
1978
0
                assert(0);
1979
0
                break;
1980
2.94k
            default:
1981
2.94k
                f_string_found = 1;
1982
2.94k
                break;
1983
62.7k
        }
1984
62.7k
    }
1985
1986
    // Cannot mix unicode and bytes
1987
29.2k
    if ((unicode_string_found || f_string_found) && bytes_found) {
1988
4
        RAISE_SYNTAX_ERROR("cannot mix bytes and nonbytes literals");
1989
4
        return NULL;
1990
4
    }
1991
1992
    // If it's only bytes or only unicode string, do a simple concat
1993
29.2k
    if (!f_string_found) {
1994
18.6k
        if (len == 1) {
1995
16.2k
            return asdl_seq_GET(strings, 0);
1996
16.2k
        }
1997
2.37k
        else if (bytes_found) {
1998
701
            return _build_concatenated_bytes(p, strings, lineno, col_offset,
1999
701
                end_lineno, end_col_offset, arena);
2000
701
        }
2001
1.66k
        else {
2002
1.66k
            return _build_concatenated_unicode(p, strings, lineno, col_offset,
2003
1.66k
                end_lineno, end_col_offset, arena);
2004
1.66k
        }
2005
18.6k
    }
2006
2007
10.6k
    return _build_concatenated_joined_str(p, strings, lineno,
2008
10.6k
        col_offset, end_lineno, end_col_offset, arena);
2009
29.2k
}
2010
2011
static int
2012
_warn_relative_import_of_lazy(Parser *p, asdl_seq *dots, expr_ty module)
2013
20
{
2014
    // Warn about `from . lazy import x`: the whitespace between the dots and
2015
    // the module name is insignificant, so this is parsed exactly like
2016
    // `from .lazy import x` (an import of the relative module "lazy"), but it
2017
    // is most likely a transposition of `lazy from . import x` (PEP 810).
2018
20
    if (p->call_invalid_rules) {
2019
7
        return 0;
2020
7
    }
2021
2022
    // Only fire if there is whitespace between the last dot and the name,
2023
    // i.e. not for the common `from .lazy import x` spelling.
2024
13
    Token *last_dot = asdl_seq_GET_UNTYPED(dots, asdl_seq_LEN(dots) - 1);
2025
13
    if (
2026
13
        last_dot->end_lineno == module->lineno
2027
13
        && last_dot->end_col_offset == module->col_offset
2028
13
    ) {
2029
13
        return 0;
2030
13
    }
2031
2032
0
    int count = _PyPegen_seq_count_dots(dots);
2033
0
    char *buf = PyMem_RawMalloc(count + 1);
2034
0
    if (buf == NULL) {
2035
0
        PyErr_NoMemory();
2036
0
        return -1;
2037
0
    }
2038
0
    memset(buf, '.', count);
2039
0
    buf[count] = '\0';
2040
2041
0
    PyObject *msg = PyUnicode_FromFormat(
2042
0
        "'from %s lazy import' is the same as 'from %slazy import'; "
2043
0
        "did you mean 'lazy from %s import'?",
2044
0
        buf, buf, buf);
2045
0
    PyMem_RawFree(buf);
2046
0
    if (msg == NULL) {
2047
0
        return -1;
2048
0
    }
2049
2050
0
    int res = _PyErr_EmitSyntaxWarning(msg,
2051
0
                                       p->tok->filename,
2052
0
                                       module->lineno,
2053
0
                                       module->col_offset + 1,
2054
0
                                       module->end_lineno,
2055
0
                                       module->end_col_offset + 1,
2056
0
                                       p->tok->module);
2057
0
    Py_DECREF(msg);
2058
0
    return res;
2059
0
}
2060
2061
stmt_ty
2062
_PyPegen_checked_from_import(Parser *p, asdl_seq *dots, expr_ty module_name,
2063
                             asdl_alias_seq *names, expr_ty lazy_token, int lineno,
2064
                             int col_offset, int end_lineno, int end_col_offset,
2065
                             PyArena *arena)
2066
1.92k
{
2067
1.92k
    identifier module = module_name->v.Name.id;
2068
1.92k
    int level = _PyPegen_seq_count_dots(dots);
2069
1.92k
    if (level == 0 && PyUnicode_CompareWithASCIIString(module, "__future__") == 0) {
2070
699
        if (lazy_token) {
2071
1
            RAISE_SYNTAX_ERROR_KNOWN_LOCATION(lazy_token,
2072
1
                "lazy from __future__ import is not allowed");
2073
1
            return NULL;
2074
1
        }
2075
1.61k
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(names); i++) {
2076
915
            alias_ty alias = asdl_seq_GET(names, i);
2077
915
            if (PyUnicode_CompareWithASCIIString(alias->name, "barry_as_FLUFL") == 0) {
2078
291
                p->flags |= PyPARSE_BARRY_AS_BDFL;
2079
291
            }
2080
915
        }
2081
698
    }
2082
1.22k
    else if (
2083
1.22k
        level > 0
2084
475
        && lazy_token == NULL
2085
472
        && PyUnicode_CompareWithASCIIString(module, "lazy") == 0
2086
1.22k
    ) {
2087
20
        if (_warn_relative_import_of_lazy(p, dots, module_name) < 0) {
2088
0
            return NULL;
2089
0
        }
2090
20
    }
2091
1.91k
    return _PyAST_ImportFrom(module, names, level, lazy_token ? 1 : 0, lineno,
2092
1.91k
                             col_offset, end_lineno, end_col_offset, arena);
2093
1.92k
}
2094
2095
asdl_stmt_seq*
2096
24.3k
_PyPegen_register_stmts(Parser *p, asdl_stmt_seq* stmts) {
2097
24.3k
    if (!p->call_invalid_rules) {
2098
17.3k
        return stmts;
2099
17.3k
    }
2100
7.05k
    Py_ssize_t len = asdl_seq_LEN(stmts);
2101
7.05k
    if (len == 0) {
2102
0
        return stmts;
2103
0
    }
2104
7.05k
    stmt_ty last_stmt = asdl_seq_GET(stmts, len - 1);
2105
7.05k
    if (p->last_stmt_location.lineno > last_stmt->lineno) {
2106
110
        return stmts;
2107
110
    }
2108
6.94k
    p->last_stmt_location.lineno = last_stmt->lineno;
2109
6.94k
    p->last_stmt_location.col_offset = last_stmt->col_offset;
2110
6.94k
    p->last_stmt_location.end_lineno = last_stmt->end_lineno;
2111
6.94k
    p->last_stmt_location.end_col_offset = last_stmt->end_col_offset;
2112
6.94k
    return stmts;
2113
7.05k
}