Coverage Report

Created: 2022-07-08 09:39

/home/mdboom/Work/builds/cpython/Parser/action_helpers.c
Line
Count
Source (jump to first uncovered line)
1
#include <Python.h>
2
3
#include "pegen.h"
4
#include "string_parser.h"
5
6
static PyObject *
7
_create_dummy_identifier(Parser *p)
8
{
9
    return _PyPegen_new_identifier(p, "");
10
}
11
12
void *
13
_PyPegen_dummy_name(Parser *p, ...)
14
{
15
    static void *cache = NULL;
16
17
    if (cache != NULL) {
  Branch (17:9): [True: 93.0k, False: 60]
18
        return cache;
19
    }
20
21
    PyObject *id = _create_dummy_identifier(p);
22
    if (!id) {
  Branch (22:9): [True: 0, False: 60]
23
        return NULL;
24
    }
25
    cache = _PyAST_Name(id, Load, 1, 0, 1, 0, p->arena);
26
    return cache;
27
}
28
29
/* Creates a single-element asdl_seq* that contains a */
30
asdl_seq *
31
_PyPegen_singleton_seq(Parser *p, void *a)
32
{
33
    assert(a != NULL);
34
    asdl_seq *seq = (asdl_seq*)_Py_asdl_generic_seq_new(1, p->arena);
35
    if (!seq) {
  Branch (35:9): [True: 0, False: 705k]
36
        return NULL;
37
    }
38
    asdl_seq_SET_UNTYPED(seq, 0, a);
39
    return seq;
40
}
41
42
/* Creates a copy of seq and prepends a to it */
43
asdl_seq *
44
_PyPegen_seq_insert_in_front(Parser *p, void *a, asdl_seq *seq)
45
{
46
    assert(a != NULL);
47
    if (!seq) {
  Branch (47:9): [True: 50.6k, False: 210k]
48
        return _PyPegen_singleton_seq(p, a);
49
    }
50
51
    asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena);
52
    if (!new_seq) {
  Branch (52:9): [True: 0, False: 210k]
53
        return NULL;
54
    }
55
56
    asdl_seq_SET_UNTYPED(new_seq, 0, a);
57
    for (Py_ssize_t i = 1, l = 
asdl_seq_LEN210k
(new_seq); i < l;
i++957k
) {
  Branch (57:55): [True: 957k, False: 210k]
58
        asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i - 1));
59
    }
60
    return new_seq;
61
}
62
63
/* Creates a copy of seq and appends a to it */
64
asdl_seq *
65
_PyPegen_seq_append_to_end(Parser *p, asdl_seq *seq, void *a)
66
{
67
    assert(a != NULL);
68
    if (!seq) {
  Branch (68:9): [True: 0, False: 7]
69
        return _PyPegen_singleton_seq(p, a);
70
    }
71
72
    asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena);
73
    if (!new_seq) {
  Branch (73:9): [True: 0, False: 7]
74
        return NULL;
75
    }
76
77
    
for (Py_ssize_t i = 0, l = 7
asdl_seq_LEN7
(new_seq); i + 1 < l;
i++8
) {
  Branch (77:55): [True: 8, False: 7]
78
        asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i));
79
    }
80
    asdl_seq_SET_UNTYPED(new_seq, asdl_seq_LEN(new_seq) - 1, a);
81
    return new_seq;
82
}
83
84
static Py_ssize_t
85
_get_flattened_seq_size(asdl_seq *seqs)
86
{
87
    Py_ssize_t size = 0;
88
    for (Py_ssize_t i = 0, l = 
asdl_seq_LEN97.1k
(seqs); i < l;
i++442k
) {
  Branch (88:52): [True: 442k, False: 97.1k]
89
        asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i);
90
        size += asdl_seq_LEN(inner_seq);
91
    }
92
    return size;
93
}
94
95
/* Flattens an asdl_seq* of asdl_seq*s */
96
asdl_seq *
97
_PyPegen_seq_flatten(Parser *p, asdl_seq *seqs)
98
{
99
    Py_ssize_t flattened_seq_size = _get_flattened_seq_size(seqs);
100
    assert(flattened_seq_size > 0);
101
102
    asdl_seq *flattened_seq = (asdl_seq*)_Py_asdl_generic_seq_new(flattened_seq_size, p->arena);
103
    if (!flattened_seq) {
  Branch (103:9): [True: 0, False: 97.1k]
104
        return NULL;
105
    }
106
107
    int flattened_seq_idx = 0;
108
    for (Py_ssize_t i = 0, l = 
asdl_seq_LEN97.1k
(seqs); i < l;
i++442k
) {
  Branch (108:52): [True: 442k, False: 97.1k]
109
        asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i);
110
        for (Py_ssize_t j = 0, li = 
asdl_seq_LEN442k
(inner_seq); j < li;
j++446k
) {
  Branch (110:62): [True: 446k, False: 442k]
111
            asdl_seq_SET_UNTYPED(flattened_seq, flattened_seq_idx++, asdl_seq_GET_UNTYPED(inner_seq, j));
112
        }
113
    }
114
    assert(flattened_seq_idx == flattened_seq_size);
115
116
    return flattened_seq;
117
}
118
119
void *
120
_PyPegen_seq_last_item(asdl_seq *seq)
121
{
122
    Py_ssize_t len = asdl_seq_LEN(seq);
123
    return asdl_seq_GET_UNTYPED(seq, len - 1);
124
}
125
126
void *
127
_PyPegen_seq_first_item(asdl_seq *seq)
128
{
129
    return asdl_seq_GET_UNTYPED(seq, 0);
130
}
131
132
/* Creates a new name of the form <first_name>.<second_name> */
133
expr_ty
134
_PyPegen_join_names_with_dot(Parser *p, expr_ty first_name, expr_ty second_name)
135
{
136
    assert(first_name != NULL && second_name != NULL);
137
    PyObject *first_identifier = first_name->v.Name.id;
138
    PyObject *second_identifier = second_name->v.Name.id;
139
140
    if (PyUnicode_READY(first_identifier) == -1) {
  Branch (140:9): [True: 0, False: 1.01k]
141
        return NULL;
142
    }
143
    if (PyUnicode_READY(second_identifier) == -1) {
  Branch (143:9): [True: 0, False: 1.01k]
144
        return NULL;
145
    }
146
    const char *first_str = PyUnicode_AsUTF8(first_identifier);
147
    if (!first_str) {
  Branch (147:9): [True: 0, False: 1.01k]
148
        return NULL;
149
    }
150
    const char *second_str = PyUnicode_AsUTF8(second_identifier);
151
    if (!second_str) {
  Branch (151:9): [True: 0, False: 1.01k]
152
        return NULL;
153
    }
154
    Py_ssize_t len = strlen(first_str) + strlen(second_str) + 1;  // +1 for the dot
155
156
    PyObject *str = PyBytes_FromStringAndSize(NULL, len);
157
    if (!str) {
  Branch (157:9): [True: 0, False: 1.01k]
158
        return NULL;
159
    }
160
161
    char *s = PyBytes_AS_STRING(str);
162
    if (!s) {
  Branch (162:9): [True: 0, False: 1.01k]
163
        return NULL;
164
    }
165
166
    strcpy(s, first_str);
167
    s += strlen(first_str);
168
    *s++ = '.';
169
    strcpy(s, second_str);
170
    s += strlen(second_str);
171
    *s = '\0';
172
173
    PyObject *uni = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(str), PyBytes_GET_SIZE(str), NULL);
174
    Py_DECREF(str);
175
    if (!uni) {
  Branch (175:9): [True: 0, False: 1.01k]
176
        return NULL;
177
    }
178
    PyUnicode_InternInPlace(&uni);
179
    if (_PyArena_AddPyObject(p->arena, uni) < 0) {
  Branch (179:9): [True: 0, False: 1.01k]
180
        Py_DECREF(uni);
181
        return NULL;
182
    }
183
184
    return _PyAST_Name(uni, Load, EXTRA_EXPR(first_name, second_name));
185
}
186
187
/* Counts the total number of dots in seq's tokens */
188
int
189
_PyPegen_seq_count_dots(asdl_seq *seq)
190
{
191
    int number_of_dots = 0;
192
    for (Py_ssize_t i = 0, l = 
asdl_seq_LEN2.04k
(seq); i < l;
i++147
) {
  Branch (192:51): [True: 147, False: 2.04k]
193
        Token *current_expr = asdl_seq_GET_UNTYPED(seq, i);
194
        switch (current_expr->type) {
195
            case ELLIPSIS:
  Branch (195:13): [True: 2, False: 145]
196
                number_of_dots += 3;
197
                break;
198
            case DOT:
  Branch (198:13): [True: 145, False: 2]
199
                number_of_dots += 1;
200
                break;
201
            default:
  Branch (201:13): [True: 0, False: 147]
202
                Py_UNREACHABLE();
203
        }
204
    }
205
206
    return number_of_dots;
207
}
208
209
/* Creates an alias with '*' as the identifier name */
210
alias_ty
211
_PyPegen_alias_for_star(Parser *p, int lineno, int col_offset, int end_lineno,
212
                        int end_col_offset, PyArena *arena) {
213
    PyObject *str = PyUnicode_InternFromString("*");
214
    if (!str) {
  Branch (214:9): [True: 0, False: 409]
215
        return NULL;
216
    }
217
    if (_PyArena_AddPyObject(p->arena, str) < 0) {
  Branch (217:9): [True: 0, False: 409]
218
        Py_DECREF(str);
219
        return NULL;
220
    }
221
    return _PyAST_alias(str, NULL, lineno, col_offset, end_lineno, end_col_offset, arena);
222
}
223
224
/* Creates a new asdl_seq* with the identifiers of all the names in seq */
225
asdl_identifier_seq *
226
_PyPegen_map_names_to_ids(Parser *p, asdl_expr_seq *seq)
227
{
228
    Py_ssize_t len = asdl_seq_LEN(seq);
229
    assert(len > 0);
230
231
    asdl_identifier_seq *new_seq = _Py_asdl_identifier_seq_new(len, p->arena);
232
    if (!new_seq) {
  Branch (232:9): [True: 0, False: 330]
233
        return NULL;
234
    }
235
    
for (Py_ssize_t i = 0; 330
i < len;
i++472
) {
  Branch (235:28): [True: 472, False: 330]
236
        expr_ty e = asdl_seq_GET(seq, i);
237
        asdl_seq_SET(new_seq, i, e->v.Name.id);
238
    }
239
    return new_seq;
240
}
241
242
/* Constructs a CmpopExprPair */
243
CmpopExprPair *
244
_PyPegen_cmpop_expr_pair(Parser *p, cmpop_ty cmpop, expr_ty expr)
245
{
246
    assert(expr != NULL);
247
    CmpopExprPair *a = _PyArena_Malloc(p->arena, sizeof(CmpopExprPair));
248
    if (!a) {
  Branch (248:9): [True: 0, False: 22.2k]
249
        return NULL;
250
    }
251
    a->cmpop = cmpop;
252
    a->expr = expr;
253
    return a;
254
}
255
256
asdl_int_seq *
257
_PyPegen_get_cmpops(Parser *p, asdl_seq *seq)
258
{
259
    Py_ssize_t len = asdl_seq_LEN(seq);
260
    assert(len > 0);
261
262
    asdl_int_seq *new_seq = _Py_asdl_int_seq_new(len, p->arena);
263
    if (!new_seq) {
  Branch (263:9): [True: 0, False: 21.9k]
264
        return NULL;
265
    }
266
    
for (Py_ssize_t i = 0; 21.9k
i < len;
i++22.2k
) {
  Branch (266:28): [True: 22.2k, False: 21.9k]
267
        CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i);
268
        asdl_seq_SET(new_seq, i, pair->cmpop);
269
    }
270
    return new_seq;
271
}
272
273
asdl_expr_seq *
274
_PyPegen_get_exprs(Parser *p, asdl_seq *seq)
275
{
276
    Py_ssize_t len = asdl_seq_LEN(seq);
277
    assert(len > 0);
278
279
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
280
    if (!new_seq) {
  Branch (280:9): [True: 0, False: 21.9k]
281
        return NULL;
282
    }
283
    
for (Py_ssize_t i = 0; 21.9k
i < len;
i++22.2k
) {
  Branch (283:28): [True: 22.2k, False: 21.9k]
284
        CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i);
285
        asdl_seq_SET(new_seq, i, pair->expr);
286
    }
287
    return new_seq;
288
}
289
290
/* Creates an asdl_seq* where all the elements have been changed to have ctx as context */
291
static asdl_expr_seq *
292
_set_seq_context(Parser *p, asdl_expr_seq *seq, expr_context_ty ctx)
293
{
294
    Py_ssize_t len = asdl_seq_LEN(seq);
295
    if (len == 0) {
  Branch (295:9): [True: 5, False: 2]
296
        return NULL;
297
    }
298
299
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
300
    if (!new_seq) {
  Branch (300:9): [True: 0, False: 2]
301
        return NULL;
302
    }
303
    
for (Py_ssize_t i = 0; 2
i < len;
i++4
) {
  Branch (303:28): [True: 4, False: 2]
304
        expr_ty e = asdl_seq_GET(seq, i);
305
        asdl_seq_SET(new_seq, i, _PyPegen_set_expr_context(p, e, ctx));
306
    }
307
    return new_seq;
308
}
309
310
static expr_ty
311
_set_name_context(Parser *p, expr_ty e, expr_context_ty ctx)
312
{
313
    return _PyAST_Name(e->v.Name.id, ctx, EXTRA_EXPR(e, e));
314
}
315
316
static expr_ty
317
_set_tuple_context(Parser *p, expr_ty e, expr_context_ty ctx)
318
{
319
    return _PyAST_Tuple(
320
            _set_seq_context(p, e->v.Tuple.elts, ctx),
321
            ctx,
322
            EXTRA_EXPR(e, e));
323
}
324
325
static expr_ty
326
_set_list_context(Parser *p, expr_ty e, expr_context_ty ctx)
327
{
328
    return _PyAST_List(
329
            _set_seq_context(p, e->v.List.elts, ctx),
330
            ctx,
331
            EXTRA_EXPR(e, e));
332
}
333
334
static expr_ty
335
_set_subscript_context(Parser *p, expr_ty e, expr_context_ty ctx)
336
{
337
    return _PyAST_Subscript(e->v.Subscript.value, e->v.Subscript.slice,
338
                            ctx, EXTRA_EXPR(e, e));
339
}
340
341
static expr_ty
342
_set_attribute_context(Parser *p, expr_ty e, expr_context_ty ctx)
343
{
344
    return _PyAST_Attribute(e->v.Attribute.value, e->v.Attribute.attr,
345
                            ctx, EXTRA_EXPR(e, e));
346
}
347
348
static expr_ty
349
_set_starred_context(Parser *p, expr_ty e, expr_context_ty ctx)
350
{
351
    return _PyAST_Starred(_PyPegen_set_expr_context(p, e->v.Starred.value, ctx),
352
                          ctx, EXTRA_EXPR(e, e));
353
}
354
355
/* Creates an `expr_ty` equivalent to `expr` but with `ctx` as context */
356
expr_ty
357
_PyPegen_set_expr_context(Parser *p, expr_ty expr, expr_context_ty ctx)
358
{
359
    assert(expr != NULL);
360
361
    expr_ty new = NULL;
362
    switch (expr->kind) {
363
        case Name_kind:
  Branch (363:9): [True: 637k, False: 24]
364
            new = _set_name_context(p, expr, ctx);
365
            break;
366
        case Tuple_kind:
  Branch (366:9): [True: 4, False: 637k]
367
            new = _set_tuple_context(p, expr, ctx);
368
            break;
369
        case List_kind:
  Branch (369:9): [True: 3, False: 637k]
370
            new = _set_list_context(p, expr, ctx);
371
            break;
372
        case Subscript_kind:
  Branch (372:9): [True: 7, False: 637k]
373
            new = _set_subscript_context(p, expr, ctx);
374
            break;
375
        case Attribute_kind:
  Branch (375:9): [True: 10, False: 637k]
376
            new = _set_attribute_context(p, expr, ctx);
377
            break;
378
        case Starred_kind:
  Branch (378:9): [True: 0, False: 637k]
379
            new = _set_starred_context(p, expr, ctx);
380
            break;
381
        default:
  Branch (381:9): [True: 0, False: 637k]
382
            new = expr;
383
    }
384
    return new;
385
}
386
387
/* Constructs a KeyValuePair that is used when parsing a dict's key value pairs */
388
KeyValuePair *
389
_PyPegen_key_value_pair(Parser *p, expr_ty key, expr_ty value)
390
{
391
    KeyValuePair *a = _PyArena_Malloc(p->arena, sizeof(KeyValuePair));
392
    if (!a) {
  Branch (392:9): [True: 0, False: 167k]
393
        return NULL;
394
    }
395
    a->key = key;
396
    a->value = value;
397
    return a;
398
}
399
400
/* Extracts all keys from an asdl_seq* of KeyValuePair*'s */
401
asdl_expr_seq *
402
_PyPegen_get_keys(Parser *p, asdl_seq *seq)
403
{
404
    Py_ssize_t len = asdl_seq_LEN(seq);
405
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
406
    if (!new_seq) {
  Branch (406:9): [True: 0, False: 8.57k]
407
        return NULL;
408
    }
409
    
for (Py_ssize_t i = 0; 8.57k
i < len;
i++166k
) {
  Branch (409:28): [True: 166k, False: 8.57k]
410
        KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i);
411
        asdl_seq_SET(new_seq, i, pair->key);
412
    }
413
    return new_seq;
414
}
415
416
/* Extracts all values from an asdl_seq* of KeyValuePair*'s */
417
asdl_expr_seq *
418
_PyPegen_get_values(Parser *p, asdl_seq *seq)
419
{
420
    Py_ssize_t len = asdl_seq_LEN(seq);
421
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
422
    if (!new_seq) {
  Branch (422:9): [True: 0, False: 8.57k]
423
        return NULL;
424
    }
425
    
for (Py_ssize_t i = 0; 8.57k
i < len;
i++166k
) {
  Branch (425:28): [True: 166k, False: 8.57k]
426
        KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i);
427
        asdl_seq_SET(new_seq, i, pair->value);
428
    }
429
    return new_seq;
430
}
431
432
/* Constructs a KeyPatternPair that is used when parsing mapping & class patterns */
433
KeyPatternPair *
434
_PyPegen_key_pattern_pair(Parser *p, expr_ty key, pattern_ty pattern)
435
{
436
    KeyPatternPair *a = _PyArena_Malloc(p->arena, sizeof(KeyPatternPair));
437
    if (!a) {
  Branch (437:9): [True: 0, False: 748]
438
        return NULL;
439
    }
440
    a->key = key;
441
    a->pattern = pattern;
442
    return a;
443
}
444
445
/* Extracts all keys from an asdl_seq* of KeyPatternPair*'s */
446
asdl_expr_seq *
447
_PyPegen_get_pattern_keys(Parser *p, asdl_seq *seq)
448
{
449
    Py_ssize_t len = asdl_seq_LEN(seq);
450
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
451
    if (!new_seq) {
  Branch (451:9): [True: 0, False: 322]
452
        return NULL;
453
    }
454
    
for (Py_ssize_t i = 0; 322
i < len;
i++418
) {
  Branch (454:28): [True: 418, False: 322]
455
        KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i);
456
        asdl_seq_SET(new_seq, i, pair->key);
457
    }
458
    return new_seq;
459
}
460
461
/* Extracts all patterns from an asdl_seq* of KeyPatternPair*'s */
462
asdl_pattern_seq *
463
_PyPegen_get_patterns(Parser *p, asdl_seq *seq)
464
{
465
    Py_ssize_t len = asdl_seq_LEN(seq);
466
    asdl_pattern_seq *new_seq = _Py_asdl_pattern_seq_new(len, p->arena);
467
    if (!new_seq) {
  Branch (467:9): [True: 0, False: 322]
468
        return NULL;
469
    }
470
    
for (Py_ssize_t i = 0; 322
i < len;
i++418
) {
  Branch (470:28): [True: 418, False: 322]
471
        KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i);
472
        asdl_seq_SET(new_seq, i, pair->pattern);
473
    }
474
    return new_seq;
475
}
476
477
/* Constructs a NameDefaultPair */
478
NameDefaultPair *
479
_PyPegen_name_default_pair(Parser *p, arg_ty arg, expr_ty value, Token *tc)
480
{
481
    NameDefaultPair *a = _PyArena_Malloc(p->arena, sizeof(NameDefaultPair));
482
    if (!a) {
  Branch (482:9): [True: 0, False: 20.1k]
483
        return NULL;
484
    }
485
    a->arg = _PyPegen_add_type_comment_to_arg(p, arg, tc);
486
    a->value = value;
487
    return a;
488
}
489
490
/* Constructs a SlashWithDefault */
491
SlashWithDefault *
492
_PyPegen_slash_with_default(Parser *p, asdl_arg_seq *plain_names, asdl_seq *names_with_defaults)
493
{
494
    SlashWithDefault *a = _PyArena_Malloc(p->arena, sizeof(SlashWithDefault));
495
    if (!a) {
  Branch (495:9): [True: 0, False: 198]
496
        return NULL;
497
    }
498
    a->plain_names = plain_names;
499
    a->names_with_defaults = names_with_defaults;
500
    return a;
501
}
502
503
/* Constructs a StarEtc */
504
StarEtc *
505
_PyPegen_star_etc(Parser *p, arg_ty vararg, asdl_seq *kwonlyargs, arg_ty kwarg)
506
{
507
    StarEtc *a = _PyArena_Malloc(p->arena, sizeof(StarEtc));
508
    if (!a) {
  Branch (508:9): [True: 0, False: 3.56k]
509
        return NULL;
510
    }
511
    a->vararg = vararg;
512
    a->kwonlyargs = kwonlyargs;
513
    a->kwarg = kwarg;
514
    return a;
515
}
516
517
asdl_seq *
518
_PyPegen_join_sequences(Parser *p, asdl_seq *a, asdl_seq *b)
519
{
520
    Py_ssize_t first_len = asdl_seq_LEN(a);
521
    Py_ssize_t second_len = asdl_seq_LEN(b);
522
    asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(first_len + second_len, p->arena);
523
    if (!new_seq) {
  Branch (523:9): [True: 0, False: 28.0k]
524
        return NULL;
525
    }
526
527
    int k = 0;
528
    for (Py_ssize_t i = 0; i < first_len; 
i++50.6k
) {
  Branch (528:28): [True: 50.6k, False: 28.0k]
529
        asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(a, i));
530
    }
531
    for (Py_ssize_t i = 0; i < second_len; 
i++5.02k
) {
  Branch (531:28): [True: 5.02k, False: 28.0k]
532
        asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(b, i));
533
    }
534
535
    return new_seq;
536
}
537
538
static asdl_arg_seq*
539
_get_names(Parser *p, asdl_seq *names_with_defaults)
540
{
541
    Py_ssize_t len = asdl_seq_LEN(names_with_defaults);
542
    asdl_arg_seq *seq = _Py_asdl_arg_seq_new(len, p->arena);
543
    if (!seq) {
  Branch (543:9): [True: 0, False: 31.6k]
544
        return NULL;
545
    }
546
    
for (Py_ssize_t i = 0; 31.6k
i < len;
i++9.60k
) {
  Branch (546:28): [True: 9.60k, False: 31.6k]
547
        NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i);
548
        asdl_seq_SET(seq, i, pair->arg);
549
    }
550
    return seq;
551
}
552
553
static asdl_expr_seq *
554
_get_defaults(Parser *p, asdl_seq *names_with_defaults)
555
{
556
    Py_ssize_t len = asdl_seq_LEN(names_with_defaults);
557
    asdl_expr_seq *seq = _Py_asdl_expr_seq_new(len, p->arena);
558
    if (!seq) {
  Branch (558:9): [True: 0, False: 31.6k]
559
        return NULL;
560
    }
561
    
for (Py_ssize_t i = 0; 31.6k
i < len;
i++9.60k
) {
  Branch (561:28): [True: 9.60k, False: 31.6k]
562
        NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i);
563
        asdl_seq_SET(seq, i, pair->value);
564
    }
565
    return seq;
566
}
567
568
static int
569
_make_posonlyargs(Parser *p,
570
                  asdl_arg_seq *slash_without_default,
571
                  SlashWithDefault *slash_with_default,
572
                  asdl_arg_seq **posonlyargs) {
573
    if (slash_without_default != NULL) {
  Branch (573:9): [True: 443, False: 28.6k]
574
        *posonlyargs = slash_without_default;
575
    }
576
    else if (slash_with_default != NULL) {
  Branch (576:14): [True: 181, False: 28.4k]
577
        asdl_arg_seq *slash_with_default_names =
578
                _get_names(p, slash_with_default->names_with_defaults);
579
        if (!slash_with_default_names) {
  Branch (579:13): [True: 0, False: 181]
580
            return -1;
581
        }
582
        *posonlyargs = (asdl_arg_seq*)_PyPegen_join_sequences(
583
                p,
584
                (asdl_seq*)slash_with_default->plain_names,
585
                (asdl_seq*)slash_with_default_names);
586
    }
587
    else {
588
        *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
589
    }
590
    return *posonlyargs == NULL ? 
-10
: 0;
  Branch (590:12): [True: 0, False: 29.0k]
591
}
592
593
static int
594
_make_posargs(Parser *p,
595
              asdl_arg_seq *plain_names,
596
              asdl_seq *names_with_default,
597
              asdl_arg_seq **posargs) {
598
    if (plain_names != NULL && 
names_with_default != NULL27.5k
) {
  Branch (598:9): [True: 27.5k, False: 1.51k]
  Branch (598:32): [True: 27.5k, False: 0]
599
        asdl_arg_seq *names_with_default_names = _get_names(p, names_with_default);
600
        if (!names_with_default_names) {
  Branch (600:13): [True: 0, False: 27.5k]
601
            return -1;
602
        }
603
        *posargs = (asdl_arg_seq*)_PyPegen_join_sequences(
604
                p,(asdl_seq*)plain_names, (asdl_seq*)names_with_default_names);
605
    }
606
    else if (plain_names == NULL && names_with_default != NULL) {
  Branch (606:14): [True: 1.51k, False: 0]
  Branch (606:37): [True: 558, False: 954]
607
        *posargs = _get_names(p, names_with_default);
608
    }
609
    else if (plain_names != NULL && 
names_with_default == NULL0
) {
  Branch (609:14): [True: 0, False: 954]
  Branch (609:37): [True: 0, False: 0]
610
        *posargs = plain_names;
611
    }
612
    else {
613
        *posargs = _Py_asdl_arg_seq_new(0, p->arena);
614
    }
615
    return *posargs == NULL ? 
-10
: 0;
  Branch (615:12): [True: 0, False: 29.0k]
616
}
617
618
static int
619
_make_posdefaults(Parser *p,
620
                  SlashWithDefault *slash_with_default,
621
                  asdl_seq *names_with_default,
622
                  asdl_expr_seq **posdefaults) {
623
    if (slash_with_default != NULL && 
names_with_default != NULL181
) {
  Branch (623:9): [True: 181, False: 28.9k]
  Branch (623:39): [True: 181, False: 0]
624
        asdl_expr_seq *slash_with_default_values =
625
                _get_defaults(p, slash_with_default->names_with_defaults);
626
        if (!slash_with_default_values) {
  Branch (626:13): [True: 0, False: 181]
627
            return -1;
628
        }
629
        asdl_expr_seq *names_with_default_values = _get_defaults(p, names_with_default);
630
        if (!names_with_default_values) {
  Branch (630:13): [True: 0, False: 181]
631
            return -1;
632
        }
633
        *posdefaults = (asdl_expr_seq*)_PyPegen_join_sequences(
634
                p,
635
                (asdl_seq*)slash_with_default_values,
636
                (asdl_seq*)names_with_default_values);
637
    }
638
    else if (slash_with_default == NULL && names_with_default != NULL) {
  Branch (638:14): [True: 28.9k, False: 0]
  Branch (638:44): [True: 27.9k, False: 954]
639
        *posdefaults = _get_defaults(p, names_with_default);
640
    }
641
    else if (slash_with_default != NULL && 
names_with_default == NULL0
) {
  Branch (641:14): [True: 0, False: 954]
  Branch (641:44): [True: 0, False: 0]
642
        *posdefaults = _get_defaults(p, slash_with_default->names_with_defaults);
643
    }
644
    else {
645
        *posdefaults = _Py_asdl_expr_seq_new(0, p->arena);
646
    }
647
    return *posdefaults == NULL ? 
-10
: 0;
  Branch (647:12): [True: 0, False: 29.0k]
648
}
649
650
static int
651
_make_kwargs(Parser *p, StarEtc *star_etc,
652
             asdl_arg_seq **kwonlyargs,
653
             asdl_expr_seq **kwdefaults) {
654
    if (star_etc != NULL && 
star_etc->kwonlyargs != NULL3.56k
) {
  Branch (654:9): [True: 3.56k, False: 25.5k]
  Branch (654:29): [True: 3.31k, False: 247]
655
        *kwonlyargs = _get_names(p, star_etc->kwonlyargs);
656
    }
657
    else {
658
        *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
659
    }
660
661
    if (*kwonlyargs == NULL) {
  Branch (661:9): [True: 0, False: 29.0k]
662
        return -1;
663
    }
664
665
    if (star_etc != NULL && 
star_etc->kwonlyargs != NULL3.56k
) {
  Branch (665:9): [True: 3.56k, False: 25.5k]
  Branch (665:29): [True: 3.31k, False: 247]
666
        *kwdefaults = _get_defaults(p, star_etc->kwonlyargs);
667
    }
668
    else {
669
        *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena);
670
    }
671
672
    if (*kwdefaults == NULL) {
  Branch (672:9): [True: 0, False: 29.0k]
673
        return -1;
674
    }
675
676
    return 0;
677
}
678
679
/* Constructs an arguments_ty object out of all the parsed constructs in the parameters rule */
680
arguments_ty
681
_PyPegen_make_arguments(Parser *p, asdl_arg_seq *slash_without_default,
682
                        SlashWithDefault *slash_with_default, asdl_arg_seq *plain_names,
683
                        asdl_seq *names_with_default, StarEtc *star_etc)
684
{
685
    asdl_arg_seq *posonlyargs;
686
    if (_make_posonlyargs(p, slash_without_default, slash_with_default, &posonlyargs) == -1) {
  Branch (686:9): [True: 0, False: 29.0k]
687
        return NULL;
688
    }
689
690
    asdl_arg_seq *posargs;
691
    if (_make_posargs(p, plain_names, names_with_default, &posargs) == -1) {
  Branch (691:9): [True: 0, False: 29.0k]
692
        return NULL;
693
    }
694
695
    asdl_expr_seq *posdefaults;
696
    if (_make_posdefaults(p,slash_with_default, names_with_default, &posdefaults) == -1) {
  Branch (696:9): [True: 0, False: 29.0k]
697
        return NULL;
698
    }
699
700
    arg_ty vararg = NULL;
701
    if (star_etc != NULL && 
star_etc->vararg != NULL3.56k
) {
  Branch (701:9): [True: 3.56k, False: 25.5k]
  Branch (701:29): [True: 2.15k, False: 1.40k]
702
        vararg = star_etc->vararg;
703
    }
704
705
    asdl_arg_seq *kwonlyargs;
706
    asdl_expr_seq *kwdefaults;
707
    if (_make_kwargs(p, star_etc, &kwonlyargs, &kwdefaults) == -1) {
  Branch (707:9): [True: 0, False: 29.0k]
708
        return NULL;
709
    }
710
711
    arg_ty kwarg = NULL;
712
    if (star_etc != NULL && 
star_etc->kwarg != NULL3.56k
) {
  Branch (712:9): [True: 3.56k, False: 25.5k]
  Branch (712:29): [True: 1.85k, False: 1.70k]
713
        kwarg = star_etc->kwarg;
714
    }
715
716
    return _PyAST_arguments(posonlyargs, posargs, vararg, kwonlyargs,
717
                            kwdefaults, kwarg, posdefaults, p->arena);
718
}
719
720
721
/* Constructs an empty arguments_ty object, that gets used when a function accepts no
722
 * arguments. */
723
arguments_ty
724
_PyPegen_empty_arguments(Parser *p)
725
{
726
    asdl_arg_seq *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
727
    if (!posonlyargs) {
  Branch (727:9): [True: 0, False: 5.48k]
728
        return NULL;
729
    }
730
    asdl_arg_seq *posargs = _Py_asdl_arg_seq_new(0, p->arena);
731
    if (!posargs) {
  Branch (731:9): [True: 0, False: 5.48k]
732
        return NULL;
733
    }
734
    asdl_expr_seq *posdefaults = _Py_asdl_expr_seq_new(0, p->arena);
735
    if (!posdefaults) {
  Branch (735:9): [True: 0, False: 5.48k]
736
        return NULL;
737
    }
738
    asdl_arg_seq *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
739
    if (!kwonlyargs) {
  Branch (739:9): [True: 0, False: 5.48k]
740
        return NULL;
741
    }
742
    asdl_expr_seq *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena);
743
    if (!kwdefaults) {
  Branch (743:9): [True: 0, False: 5.48k]
744
        return NULL;
745
    }
746
747
    return _PyAST_arguments(posonlyargs, posargs, NULL, kwonlyargs,
748
                            kwdefaults, NULL, posdefaults, p->arena);
749
}
750
751
/* Encapsulates the value of an operator_ty into an AugOperator struct */
752
AugOperator *
753
_PyPegen_augoperator(Parser *p, operator_ty kind)
754
{
755
    AugOperator *a = _PyArena_Malloc(p->arena, sizeof(AugOperator));
756
    if (!a) {
  Branch (756:9): [True: 0, False: 2.16k]
757
        return NULL;
758
    }
759
    a->kind = kind;
760
    return a;
761
}
762
763
/* Construct a FunctionDef equivalent to function_def, but with decorators */
764
stmt_ty
765
_PyPegen_function_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty function_def)
766
{
767
    assert(function_def != NULL);
768
    if (function_def->kind == AsyncFunctionDef_kind) {
  Branch (768:9): [True: 17, False: 2.14k]
769
        return _PyAST_AsyncFunctionDef(
770
            function_def->v.FunctionDef.name, function_def->v.FunctionDef.args,
771
            function_def->v.FunctionDef.body, decorators, function_def->v.FunctionDef.returns,
772
            function_def->v.FunctionDef.type_comment, function_def->lineno,
773
            function_def->col_offset, function_def->end_lineno, function_def->end_col_offset,
774
            p->arena);
775
    }
776
777
    return _PyAST_FunctionDef(
778
        function_def->v.FunctionDef.name, function_def->v.FunctionDef.args,
779
        function_def->v.FunctionDef.body, decorators,
780
        function_def->v.FunctionDef.returns,
781
        function_def->v.FunctionDef.type_comment, function_def->lineno,
782
        function_def->col_offset, function_def->end_lineno,
783
        function_def->end_col_offset, p->arena);
784
}
785
786
/* Construct a ClassDef equivalent to class_def, but with decorators */
787
stmt_ty
788
_PyPegen_class_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty class_def)
789
{
790
    assert(class_def != NULL);
791
    return _PyAST_ClassDef(
792
        class_def->v.ClassDef.name, class_def->v.ClassDef.bases,
793
        class_def->v.ClassDef.keywords, class_def->v.ClassDef.body, decorators,
794
        class_def->lineno, class_def->col_offset, class_def->end_lineno,
795
        class_def->end_col_offset, p->arena);
796
}
797
798
/* Construct a KeywordOrStarred */
799
KeywordOrStarred *
800
_PyPegen_keyword_or_starred(Parser *p, void *element, int is_keyword)
801
{
802
    KeywordOrStarred *a = _PyArena_Malloc(p->arena, sizeof(KeywordOrStarred));
803
    if (!a) {
  Branch (803:9): [True: 0, False: 19.0k]
804
        return NULL;
805
    }
806
    a->element = element;
807
    a->is_keyword = is_keyword;
808
    return a;
809
}
810
811
/* Get the number of starred expressions in an asdl_seq* of KeywordOrStarred*s */
812
static int
813
_seq_number_of_starred_exprs(asdl_seq *seq)
814
{
815
    int n = 0;
816
    for (Py_ssize_t i = 0, l = 
asdl_seq_LEN11.9k
(seq); i < l;
i++20.2k
) {
  Branch (816:51): [True: 20.2k, False: 11.9k]
817
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(seq, i);
818
        if (!k->is_keyword) {
  Branch (818:13): [True: 144, False: 20.0k]
819
            n++;
820
        }
821
    }
822
    return n;
823
}
824
825
/* Extract the starred expressions of an asdl_seq* of KeywordOrStarred*s */
826
asdl_expr_seq *
827
_PyPegen_seq_extract_starred_exprs(Parser *p, asdl_seq *kwargs)
828
{
829
    int new_len = _seq_number_of_starred_exprs(kwargs);
830
    if (new_len == 0) {
  Branch (830:9): [True: 5.92k, False: 72]
831
        return NULL;
832
    }
833
    asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(new_len, p->arena);
834
    if (!new_seq) {
  Branch (834:9): [True: 0, False: 72]
835
        return NULL;
836
    }
837
838
    int idx = 0;
839
    for (Py_ssize_t i = 0, len = 
asdl_seq_LEN72
(kwargs); i < len;
i++228
) {
  Branch (839:56): [True: 228, False: 72]
840
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i);
841
        if (!k->is_keyword) {
  Branch (841:13): [True: 72, False: 156]
842
            asdl_seq_SET(new_seq, idx++, k->element);
843
        }
844
    }
845
    return new_seq;
846
}
847
848
/* Return a new asdl_seq* with only the keywords in kwargs */
849
asdl_keyword_seq*
850
_PyPegen_seq_delete_starred_exprs(Parser *p, asdl_seq *kwargs)
851
{
852
    Py_ssize_t len = asdl_seq_LEN(kwargs);
853
    Py_ssize_t new_len = len - _seq_number_of_starred_exprs(kwargs);
854
    if (new_len == 0) {
  Branch (854:9): [True: 0, False: 5.99k]
855
        return NULL;
856
    }
857
    asdl_keyword_seq *new_seq = _Py_asdl_keyword_seq_new(new_len, p->arena);
858
    if (!new_seq) {
  Branch (858:9): [True: 0, False: 5.99k]
859
        return NULL;
860
    }
861
862
    int idx = 0;
863
    for (Py_ssize_t i = 0; i < len; 
i++10.1k
) {
  Branch (863:28): [True: 10.1k, False: 5.99k]
864
        KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i);
865
        if (k->is_keyword) {
  Branch (865:13): [True: 10.0k, False: 72]
866
            asdl_seq_SET(new_seq, idx++, k->element);
867
        }
868
    }
869
    return new_seq;
870
}
871
872
expr_ty
873
_PyPegen_concatenate_strings(Parser *p, asdl_seq *strings)
874
{
875
    Py_ssize_t len = asdl_seq_LEN(strings);
876
    assert(len > 0);
877
878
    Token *first = asdl_seq_GET_UNTYPED(strings, 0);
879
    Token *last = asdl_seq_GET_UNTYPED(strings, len - 1);
880
881
    int bytesmode = 0;
882
    PyObject *bytes_str = NULL;
883
884
    FstringParser state;
885
    _PyPegen_FstringParser_Init(&state);
886
887
    for (Py_ssize_t i = 0; i < len; 
i++205k
) {
  Branch (887:28): [True: 205k, False: 180k]
888
        Token *t = asdl_seq_GET_UNTYPED(strings, i);
889
890
        int this_bytesmode;
891
        int this_rawmode;
892
        PyObject *s;
893
        const char *fstr;
894
        Py_ssize_t fstrlen = -1;
895
896
        if (_PyPegen_parsestr(p, &this_bytesmode, &this_rawmode, &s, &fstr, &fstrlen, t) != 0) {
  Branch (896:13): [True: 177, False: 205k]
897
            goto error;
898
        }
899
900
        /* Check that we are not mixing bytes with unicode. */
901
        if (i != 0 && 
bytesmode != this_bytesmode24.7k
) {
  Branch (901:13): [True: 24.7k, False: 180k]
  Branch (901:23): [True: 2, False: 24.7k]
902
            RAISE_SYNTAX_ERROR("cannot mix bytes and nonbytes literals");
903
            Py_XDECREF(s);
904
            goto error;
905
        }
906
        bytesmode = this_bytesmode;
907
908
        if (fstr != NULL) {
  Branch (908:13): [True: 4.43k, False: 201k]
909
            assert(s == NULL && !bytesmode);
910
911
            int result = _PyPegen_FstringParser_ConcatFstring(p, &state, &fstr, fstr + fstrlen,
912
                                                     this_rawmode, 0, first, t, last);
913
            if (result < 0) {
  Branch (913:17): [True: 122, False: 4.30k]
914
                goto error;
915
            }
916
        }
917
        else {
918
            /* String or byte string. */
919
            assert(s != NULL && fstr == NULL);
920
            assert(bytesmode ? PyBytes_CheckExact(s) : PyUnicode_CheckExact(s));
921
922
            if (bytesmode) {
  Branch (922:17): [True: 4.25k, False: 196k]
923
                if (i == 0) {
  Branch (923:21): [True: 3.10k, False: 1.14k]
924
                    bytes_str = s;
925
                }
926
                else {
927
                    PyBytes_ConcatAndDel(&bytes_str, s);
928
                    if (!bytes_str) {
  Branch (928:25): [True: 0, False: 1.14k]
929
                        goto error;
930
                    }
931
                }
932
            }
933
            else {
934
                /* This is a regular string. Concatenate it. */
935
                if (_PyPegen_FstringParser_ConcatAndDel(&state, s) < 0) {
  Branch (935:21): [True: 0, False: 196k]
936
                    goto error;
937
                }
938
            }
939
        }
940
    }
941
942
    if (bytesmode) {
  Branch (942:9): [True: 3.10k, False: 177k]
943
        if (_PyArena_AddPyObject(p->arena, bytes_str) < 0) {
  Branch (943:13): [True: 0, False: 3.10k]
944
            goto error;
945
        }
946
        return _PyAST_Constant(bytes_str, NULL, first->lineno,
947
                               first->col_offset, last->end_lineno,
948
                               last->end_col_offset, p->arena);
949
    }
950
951
    return _PyPegen_FstringParser_Finish(p, &state, first, last);
952
953
error:
954
    Py_XDECREF(bytes_str);
955
    _PyPegen_FstringParser_Dealloc(&state);
956
    if (PyErr_Occurred()) {
  Branch (956:9): [True: 301, False: 0]
957
        _Pypegen_raise_decode_error(p);
958
    }
959
    return NULL;
960
}
961
962
expr_ty
963
_PyPegen_ensure_imaginary(Parser *p, expr_ty exp)
964
{
965
    if (exp->kind != Constant_kind || !PyComplex_CheckExact(exp->v.Constant.value)) {
  Branch (965:9): [True: 0, False: 38]
  Branch (965:39): [True: 2, False: 36]
966
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(exp, "imaginary number required in complex literal");
967
        return NULL;
968
    }
969
    return exp;
970
}
971
972
expr_ty
973
_PyPegen_ensure_real(Parser *p, expr_ty exp)
974
{
975
    if (exp->kind != Constant_kind || PyComplex_CheckExact(exp->v.Constant.value)) {
  Branch (975:9): [True: 0, False: 63]
976
        RAISE_SYNTAX_ERROR_KNOWN_LOCATION(exp, "real number required in complex literal");
977
        return NULL;
978
    }
979
    return exp;
980
}
981
982
mod_ty
983
_PyPegen_make_module(Parser *p, asdl_stmt_seq *a) {
984
    asdl_type_ignore_seq *type_ignores = NULL;
985
    Py_ssize_t num = p->type_ignore_comments.num_items;
986
    if (num > 0) {
  Branch (986:9): [True: 29, False: 16.8k]
987
        // Turn the raw (comment, lineno) pairs into TypeIgnore objects in the arena
988
        type_ignores = _Py_asdl_type_ignore_seq_new(num, p->arena);
989
        if (type_ignores == NULL) {
  Branch (989:13): [True: 0, False: 29]
990
            return NULL;
991
        }
992
        
for (int i = 0; 29
i < num;
i++74
) {
  Branch (992:25): [True: 74, False: 29]
993
            PyObject *tag = _PyPegen_new_type_comment(p, p->type_ignore_comments.items[i].comment);
994
            if (tag == NULL) {
  Branch (994:17): [True: 0, False: 74]
995
                return NULL;
996
            }
997
            type_ignore_ty ti = _PyAST_TypeIgnore(p->type_ignore_comments.items[i].lineno,
998
                                                  tag, p->arena);
999
            if (ti == NULL) {
  Branch (999:17): [True: 0, False: 74]
1000
                return NULL;
1001
            }
1002
            asdl_seq_SET(type_ignores, i, ti);
1003
        }
1004
    }
1005
    return _PyAST_Module(a, type_ignores, p->arena);
1006
}
1007
1008
PyObject *
1009
_PyPegen_new_type_comment(Parser *p, const char *s)
1010
{
1011
    PyObject *res = PyUnicode_DecodeUTF8(s, strlen(s), NULL);
1012
    if (res == NULL) {
  Branch (1012:9): [True: 0, False: 913]
1013
        return NULL;
1014
    }
1015
    if (_PyArena_AddPyObject(p->arena, res) < 0) {
  Branch (1015:9): [True: 0, False: 913]
1016
        Py_DECREF(res);
1017
        return NULL;
1018
    }
1019
    return res;
1020
}
1021
1022
arg_ty
1023
_PyPegen_add_type_comment_to_arg(Parser *p, arg_ty a, Token *tc)
1024
{
1025
    if (tc == NULL) {
  Branch (1025:9): [True: 235k, False: 747]
1026
        return a;
1027
    }
1028
    const char *bytes = PyBytes_AsString(tc->bytes);
1029
    if (bytes == NULL) {
  Branch (1029:9): [True: 0, False: 747]
1030
        return NULL;
1031
    }
1032
    PyObject *tco = _PyPegen_new_type_comment(p, bytes);
1033
    if (tco == NULL) {
  Branch (1033:9): [True: 0, False: 747]
1034
        return NULL;
1035
    }
1036
    return _PyAST_arg(a->arg, a->annotation, tco,
1037
                      a->lineno, a->col_offset, a->end_lineno, a->end_col_offset,
1038
                      p->arena);
1039
}
1040
1041
/* Checks if the NOTEQUAL token is valid given the current parser flags
1042
0 indicates success and nonzero indicates failure (an exception may be set) */
1043
int
1044
_PyPegen_check_barry_as_flufl(Parser *p, Token* t) {
1045
    assert(t->bytes != NULL);
1046
    assert(t->type == NOTEQUAL);
1047
1048
    const char* tok_str = PyBytes_AS_STRING(t->bytes);
1049
    if (p->flags & PyPARSE_BARRY_AS_BDFL && 
strcmp(tok_str, "<>") != 02
) {
  Branch (1049:9): [True: 2, False: 1.72k]
  Branch (1049:45): [True: 1, False: 1]
1050
        RAISE_SYNTAX_ERROR("with Barry as BDFL, use '<>' instead of '!='");
1051
        return -1;
1052
    }
1053
    if (!(p->flags & PyPARSE_BARRY_AS_BDFL)) {
  Branch (1053:9): [True: 1.72k, False: 1]
1054
        return strcmp(tok_str, "!=");
1055
    }
1056
    return 0;
1057
}
1058
1059
int
1060
_PyPegen_check_legacy_stmt(Parser *p, expr_ty name) {
1061
    if (name->kind != Name_kind) {
  Branch (1061:9): [True: 17, False: 161]
1062
        return 0;
1063
    }
1064
    const char* candidates[2] = {"print", "exec"};
1065
    for (int i=0; i<2; 
i++247
) {
  Branch (1065:19): [True: 292, False: 116]
1066
        if (PyUnicode_CompareWithASCIIString(name->v.Name.id, candidates[i]) == 0) {
  Branch (1066:13): [True: 45, False: 247]
1067
            return 1;
1068
        }
1069
    }
1070
    return 0;
1071
}
1072
1073
const char *
1074
_PyPegen_get_expr_name(expr_ty e)
1075
{
1076
    assert(e != NULL);
1077
    switch (e->kind) {
1078
        case Attribute_kind:
  Branch (1078:9): [True: 2, False: 125]
1079
            return "attribute";
1080
        case Subscript_kind:
  Branch (1080:9): [True: 0, False: 127]
1081
            return "subscript";
1082
        case Starred_kind:
  Branch (1082:9): [True: 3, False: 124]
1083
            return "starred";
1084
        case Name_kind:
  Branch (1084:9): [True: 0, False: 127]
1085
            return "name";
1086
        case List_kind:
  Branch (1086:9): [True: 4, False: 123]
1087
            return "list";
1088
        case Tuple_kind:
  Branch (1088:9): [True: 8, False: 119]
1089
            return "tuple";
1090
        case Lambda_kind:
  Branch (1090:9): [True: 3, False: 124]
1091
            return "lambda";
1092
        case Call_kind:
  Branch (1092:9): [True: 29, False: 98]
1093
            return "function call";
1094
        case BoolOp_kind:
  Branch (1094:9): [True: 0, False: 127]
1095
        case BinOp_kind:
  Branch (1095:9): [True: 16, False: 111]
1096
        case UnaryOp_kind:
  Branch (1096:9): [True: 2, False: 125]
1097
            return "expression";
1098
        case GeneratorExp_kind:
  Branch (1098:9): [True: 4, False: 123]
1099
            return "generator expression";
1100
        case Yield_kind:
  Branch (1100:9): [True: 3, False: 124]
1101
        case YieldFrom_kind:
  Branch (1101:9): [True: 0, False: 127]
1102
            return "yield expression";
1103
        case Await_kind:
  Branch (1103:9): [True: 0, False: 127]
1104
            return "await expression";
1105
        case ListComp_kind:
  Branch (1105:9): [True: 4, False: 123]
1106
            return "list comprehension";
1107
        case SetComp_kind:
  Branch (1107:9): [True: 2, False: 125]
1108
            return "set comprehension";
1109
        case DictComp_kind:
  Branch (1109:9): [True: 2, False: 125]
1110
            return "dict comprehension";
1111
        case Dict_kind:
  Branch (1111:9): [True: 1, False: 126]
1112
            return "dict literal";
1113
        case Set_kind:
  Branch (1113:9): [True: 1, False: 126]
1114
            return "set display";
1115
        case JoinedStr_kind:
  Branch (1115:9): [True: 2, False: 125]
1116
        case FormattedValue_kind:
  Branch (1116:9): [True: 0, False: 127]
1117
            return "f-string expression";
1118
        case Constant_kind: {
  Branch (1118:9): [True: 38, False: 89]
1119
            PyObject *value = e->v.Constant.value;
1120
            if (value == Py_None) {
  Branch (1120:17): [True: 17, False: 21]
1121
                return "None";
1122
            }
1123
            if (value == Py_False) {
  Branch (1123:17): [True: 1, False: 20]
1124
                return "False";
1125
            }
1126
            if (value == Py_True) {
  Branch (1126:17): [True: 7, False: 13]
1127
                return "True";
1128
            }
1129
            if (value == Py_Ellipsis) {
  Branch (1129:17): [True: 1, False: 12]
1130
                return "ellipsis";
1131
            }
1132
            return "literal";
1133
        }
1134
        case Compare_kind:
  Branch (1134:9): [True: 0, False: 127]
1135
            return "comparison";
1136
        case IfExp_kind:
  Branch (1136:9): [True: 2, False: 125]
1137
            return "conditional expression";
1138
        case NamedExpr_kind:
  Branch (1138:9): [True: 1, False: 126]
1139
            return "named expression";
1140
        default:
  Branch (1140:9): [True: 0, False: 127]
1141
            PyErr_Format(PyExc_SystemError,
1142
                         "unexpected expression in assignment %d (line %d)",
1143
                         e->kind, e->lineno);
1144
            return NULL;
1145
    }
1146
}
1147
1148
expr_ty
1149
_PyPegen_get_last_comprehension_item(comprehension_ty comprehension) {
1150
    if (comprehension->ifs == NULL || asdl_seq_LEN(comprehension->ifs) == 0) {
  Branch (1150:9): [True: 0, False: 36]
  Branch (1150:39): [True: 32, False: 4]
1151
        return comprehension->iter;
1152
    }
1153
    return PyPegen_last_item(comprehension->ifs, expr_ty);
1154
}
1155
1156
expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_expr_seq *a, asdl_seq *b,
1157
                     int lineno, int col_offset, int end_lineno,
1158
                     int end_col_offset, PyArena *arena) {
1159
    Py_ssize_t args_len = asdl_seq_LEN(a);
1160
    Py_ssize_t total_len = args_len;
1161
1162
    if (b == NULL) {
  Branch (1162:9): [True: 86.7k, False: 3.95k]
1163
        return _PyAST_Call(_PyPegen_dummy_name(p), a, NULL, lineno, col_offset,
1164
                        end_lineno, end_col_offset, arena);
1165
1166
    }
1167
1168
    asdl_expr_seq *starreds = _PyPegen_seq_extract_starred_exprs(p, b);
1169
    asdl_keyword_seq *keywords = _PyPegen_seq_delete_starred_exprs(p, b);
1170
1171
    if (starreds) {
  Branch (1171:9): [True: 61, False: 3.89k]
1172
        total_len += asdl_seq_LEN(starreds);
1173
    }
1174
1175
    asdl_expr_seq *args = _Py_asdl_expr_seq_new(total_len, arena);
1176
1177
    Py_ssize_t i = 0;
1178
    for (i = 0; i < args_len; 
i++6.23k
) {
  Branch (1178:17): [True: 6.23k, False: 3.95k]
1179
        asdl_seq_SET(args, i, asdl_seq_GET(a, i));
1180
    }
1181
    for (; i < total_len; 
i++61
) {
  Branch (1181:12): [True: 61, False: 3.95k]
1182
        asdl_seq_SET(args, i, asdl_seq_GET(starreds, i - args_len));
1183
    }
1184
1185
    return _PyAST_Call(_PyPegen_dummy_name(p), args, keywords, lineno,
1186
                       col_offset, end_lineno, end_col_offset, arena);
1187
}
1188
1189
// AST Error reporting helpers
1190
1191
expr_ty
1192
_PyPegen_get_invalid_target(expr_ty e, TARGETS_TYPE targets_type)
1193
{
1194
    if (e == NULL) {
  Branch (1194:9): [True: 0, False: 183]
1195
        return NULL;
1196
    }
1197
1198
#define VISIT_CONTAINER(CONTAINER, TYPE) 
do 41
{ \
1199
        Py_ssize_t len = asdl_seq_LEN((CONTAINER)->v.TYPE.elts);\
1200
        for (Py_ssize_t i = 0; i < len; 
i++43
) {\
1201
            expr_ty other = asdl_seq_GET((CONTAINER)->v.TYPE.elts, i);\
1202
            expr_ty child = _PyPegen_get_invalid_target(other, targets_type);\
1203
            if (child != NULL) {\
1204
                return child;\
1205
            }\
1206
        }\
1207
    } while (
02
)
1208
1209
    // We only need to visit List and Tuple nodes recursively as those
1210
    // are the only ones that can contain valid names in targets when
1211
    // they are parsed as expressions. Any other kind of expression
1212
    // that is a container (like Sets or Dicts) is directly invalid and
1213
    // we don't need to visit it recursively.
1214
1215
    switch (e->kind) {
1216
        case List_kind:
  Branch (1216:9): [True: 9, False: 174]
1217
            VISIT_CONTAINER(e, List);
1218
            return NULL;
1219
        case Tuple_kind:
  Branch (1219:9): [True: 32, False: 151]
1220
            VISIT_CONTAINER(e, Tuple);
1221
            return NULL;
1222
        case Starred_kind:
  Branch (1222:9): [True: 8, False: 175]
1223
            if (targets_type == DEL_TARGETS) {
  Branch (1223:17): [True: 3, False: 5]
1224
                return e;
1225
            }
1226
            return _PyPegen_get_invalid_target(e->v.Starred.value, targets_type);
1227
        case Compare_kind:
  Branch (1227:9): [True: 13, False: 170]
1228
            // This is needed, because the `a in b` in `for a in b` gets parsed
1229
            // as a comparison, and so we need to search the left side of the comparison
1230
            // for invalid targets.
1231
            if (targets_type == FOR_TARGETS) {
  Branch (1231:17): [True: 13, False: 0]
1232
                cmpop_ty cmpop = (cmpop_ty) asdl_seq_GET(e->v.Compare.ops, 0);
1233
                if (cmpop == In) {
  Branch (1233:21): [True: 12, False: 1]
1234
                    return _PyPegen_get_invalid_target(e->v.Compare.left, targets_type);
1235
                }
1236
                return NULL;
1237
            }
1238
            return e;
1239
        case Name_kind:
  Branch (1239:9): [True: 46, False: 137]
1240
        case Subscript_kind:
  Branch (1240:9): [True: 2, False: 181]
1241
        case Attribute_kind:
  Branch (1241:9): [True: 1, False: 182]
1242
            return NULL;
1243
        default:
  Branch (1243:9): [True: 72, False: 111]
1244
            return e;
1245
    }
1246
}
1247
1248
void *_PyPegen_arguments_parsing_error(Parser *p, expr_ty e) {
1249
    int kwarg_unpacking = 0;
1250
    for (Py_ssize_t i = 0, l = 
asdl_seq_LEN11
(e->v.Call.keywords); i < l;
i++12
) {
  Branch (1250:66): [True: 12, False: 11]
1251
        keyword_ty keyword = asdl_seq_GET(e->v.Call.keywords, i);
1252
        if (!keyword->arg) {
  Branch (1252:13): [True: 1, False: 11]
1253
            kwarg_unpacking = 1;
1254
        }
1255
    }
1256
1257
    const char *msg = NULL;
1258
    if (kwarg_unpacking) {
  Branch (1258:9): [True: 1, False: 10]
1259
        msg = "positional argument follows keyword argument unpacking";
1260
    } else {
1261
        msg = "positional argument follows keyword argument";
1262
    }
1263
1264
    return RAISE_SYNTAX_ERROR(msg);
1265
}
1266
1267
void *
1268
_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq *comprehensions)
1269
{
1270
    /* The rule that calls this function is 'args for_if_clauses'.
1271
       For the input f(L, x for x in y), L and x are in args and
1272
       the for is parsed as a for_if_clause. We have to check if
1273
       len <= 1, so that input like dict((a, b) for a, b in x)
1274
       gets successfully parsed and then we pass the last
1275
       argument (x in the above example) as the location of the
1276
       error */
1277
    Py_ssize_t len = asdl_seq_LEN(args->v.Call.args);
1278
    if (len <= 1) {
  Branch (1278:9): [True: 2, False: 8]
1279
        return NULL;
1280
    }
1281
1282
    comprehension_ty last_comprehension = PyPegen_last_item(comprehensions, comprehension_ty);
1283
1284
    return RAISE_SYNTAX_ERROR_KNOWN_RANGE(
1285
        (expr_ty) asdl_seq_GET(args->v.Call.args, len - 1),
1286
        _PyPegen_get_last_comprehension_item(last_comprehension),
1287
        "Generator expression must be parenthesized"
1288
    );
1289
}