1 #include <Python.h>
2 
3 #include "pegen.h"
4 #include "string_parser.h"
5 
6 static PyObject *
_create_dummy_identifier(Parser * p)7 _create_dummy_identifier(Parser *p)
8 {
9     return _PyPegen_new_identifier(p, "");
10 }
11 
12 void *
_PyPegen_dummy_name(Parser * p,...)13 _PyPegen_dummy_name(Parser *p, ...)
14 {
15     static void *cache = NULL;
16 
17     if (cache != NULL) {
18         return cache;
19     }
20 
21     PyObject *id = _create_dummy_identifier(p);
22     if (!id) {
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 *
_PyPegen_singleton_seq(Parser * p,void * a)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) {
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 *
_PyPegen_seq_insert_in_front(Parser * p,void * a,asdl_seq * seq)44 _PyPegen_seq_insert_in_front(Parser *p, void *a, asdl_seq *seq)
45 {
46     assert(a != NULL);
47     if (!seq) {
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) {
53         return NULL;
54     }
55 
56     asdl_seq_SET_UNTYPED(new_seq, 0, a);
57     for (Py_ssize_t i = 1, l = asdl_seq_LEN(new_seq); i < l; i++) {
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 *
_PyPegen_seq_append_to_end(Parser * p,asdl_seq * seq,void * a)65 _PyPegen_seq_append_to_end(Parser *p, asdl_seq *seq, void *a)
66 {
67     assert(a != NULL);
68     if (!seq) {
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) {
74         return NULL;
75     }
76 
77     for (Py_ssize_t i = 0, l = asdl_seq_LEN(new_seq); i + 1 < l; i++) {
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
_get_flattened_seq_size(asdl_seq * seqs)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_LEN(seqs); i < l; i++) {
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 *
_PyPegen_seq_flatten(Parser * p,asdl_seq * seqs)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) {
104         return NULL;
105     }
106 
107     int flattened_seq_idx = 0;
108     for (Py_ssize_t i = 0, l = asdl_seq_LEN(seqs); i < l; i++) {
109         asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i);
110         for (Py_ssize_t j = 0, li = asdl_seq_LEN(inner_seq); j < li; j++) {
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 *
_PyPegen_seq_last_item(asdl_seq * seq)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 *
_PyPegen_seq_first_item(asdl_seq * seq)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
_PyPegen_join_names_with_dot(Parser * p,expr_ty first_name,expr_ty second_name)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) {
141         return NULL;
142     }
143     if (PyUnicode_READY(second_identifier) == -1) {
144         return NULL;
145     }
146     const char *first_str = PyUnicode_AsUTF8(first_identifier);
147     if (!first_str) {
148         return NULL;
149     }
150     const char *second_str = PyUnicode_AsUTF8(second_identifier);
151     if (!second_str) {
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) {
158         return NULL;
159     }
160 
161     char *s = PyBytes_AS_STRING(str);
162     if (!s) {
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) {
176         return NULL;
177     }
178     PyUnicode_InternInPlace(&uni);
179     if (_PyArena_AddPyObject(p->arena, uni) < 0) {
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
_PyPegen_seq_count_dots(asdl_seq * seq)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_LEN(seq); i < l; i++) {
193         Token *current_expr = asdl_seq_GET_UNTYPED(seq, i);
194         switch (current_expr->type) {
195             case ELLIPSIS:
196                 number_of_dots += 3;
197                 break;
198             case DOT:
199                 number_of_dots += 1;
200                 break;
201             default:
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
_PyPegen_alias_for_star(Parser * p,int lineno,int col_offset,int end_lineno,int end_col_offset,PyArena * arena)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) {
215         return NULL;
216     }
217     if (_PyArena_AddPyObject(p->arena, str) < 0) {
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 *
_PyPegen_map_names_to_ids(Parser * p,asdl_expr_seq * 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) {
233         return NULL;
234     }
235     for (Py_ssize_t i = 0; i < len; i++) {
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 *
_PyPegen_cmpop_expr_pair(Parser * p,cmpop_ty cmpop,expr_ty expr)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) {
249         return NULL;
250     }
251     a->cmpop = cmpop;
252     a->expr = expr;
253     return a;
254 }
255 
256 asdl_int_seq *
_PyPegen_get_cmpops(Parser * p,asdl_seq * 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) {
264         return NULL;
265     }
266     for (Py_ssize_t i = 0; i < len; i++) {
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 *
_PyPegen_get_exprs(Parser * p,asdl_seq * 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) {
281         return NULL;
282     }
283     for (Py_ssize_t i = 0; i < len; i++) {
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 *
_set_seq_context(Parser * p,asdl_expr_seq * seq,expr_context_ty ctx)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) {
296         return NULL;
297     }
298 
299     asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena);
300     if (!new_seq) {
301         return NULL;
302     }
303     for (Py_ssize_t i = 0; i < len; i++) {
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
_set_name_context(Parser * p,expr_ty e,expr_context_ty ctx)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
_set_tuple_context(Parser * p,expr_ty e,expr_context_ty ctx)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
_set_list_context(Parser * p,expr_ty e,expr_context_ty ctx)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
_set_subscript_context(Parser * p,expr_ty e,expr_context_ty ctx)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
_set_attribute_context(Parser * p,expr_ty e,expr_context_ty ctx)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
_set_starred_context(Parser * p,expr_ty e,expr_context_ty ctx)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
_PyPegen_set_expr_context(Parser * p,expr_ty expr,expr_context_ty ctx)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:
364             new = _set_name_context(p, expr, ctx);
365             break;
366         case Tuple_kind:
367             new = _set_tuple_context(p, expr, ctx);
368             break;
369         case List_kind:
370             new = _set_list_context(p, expr, ctx);
371             break;
372         case Subscript_kind:
373             new = _set_subscript_context(p, expr, ctx);
374             break;
375         case Attribute_kind:
376             new = _set_attribute_context(p, expr, ctx);
377             break;
378         case Starred_kind:
379             new = _set_starred_context(p, expr, ctx);
380             break;
381         default:
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 *
_PyPegen_key_value_pair(Parser * p,expr_ty key,expr_ty value)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) {
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 *
_PyPegen_get_keys(Parser * p,asdl_seq * 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) {
407         return NULL;
408     }
409     for (Py_ssize_t i = 0; i < len; i++) {
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 *
_PyPegen_get_values(Parser * p,asdl_seq * 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) {
423         return NULL;
424     }
425     for (Py_ssize_t i = 0; i < len; i++) {
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 *
_PyPegen_key_pattern_pair(Parser * p,expr_ty key,pattern_ty pattern)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) {
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 *
_PyPegen_get_pattern_keys(Parser * p,asdl_seq * 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) {
452         return NULL;
453     }
454     for (Py_ssize_t i = 0; i < len; i++) {
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 *
_PyPegen_get_patterns(Parser * p,asdl_seq * 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) {
468         return NULL;
469     }
470     for (Py_ssize_t i = 0; i < len; i++) {
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 *
_PyPegen_name_default_pair(Parser * p,arg_ty arg,expr_ty value,Token * tc)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) {
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 *
_PyPegen_slash_with_default(Parser * p,asdl_arg_seq * plain_names,asdl_seq * names_with_defaults)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) {
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 *
_PyPegen_star_etc(Parser * p,arg_ty vararg,asdl_seq * kwonlyargs,arg_ty kwarg)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) {
509         return NULL;
510     }
511     a->vararg = vararg;
512     a->kwonlyargs = kwonlyargs;
513     a->kwarg = kwarg;
514     return a;
515 }
516 
517 asdl_seq *
_PyPegen_join_sequences(Parser * p,asdl_seq * a,asdl_seq * b)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) {
524         return NULL;
525     }
526 
527     int k = 0;
528     for (Py_ssize_t i = 0; i < first_len; i++) {
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++) {
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*
_get_names(Parser * p,asdl_seq * names_with_defaults)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) {
544         return NULL;
545     }
546     for (Py_ssize_t i = 0; i < len; i++) {
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 *
_get_defaults(Parser * p,asdl_seq * names_with_defaults)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) {
559         return NULL;
560     }
561     for (Py_ssize_t i = 0; i < len; i++) {
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
_make_posonlyargs(Parser * p,asdl_arg_seq * slash_without_default,SlashWithDefault * slash_with_default,asdl_arg_seq ** posonlyargs)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) {
574         *posonlyargs = slash_without_default;
575     }
576     else if (slash_with_default != NULL) {
577         asdl_arg_seq *slash_with_default_names =
578                 _get_names(p, slash_with_default->names_with_defaults);
579         if (!slash_with_default_names) {
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 ? -1 : 0;
591 }
592 
593 static int
_make_posargs(Parser * p,asdl_arg_seq * plain_names,asdl_seq * names_with_default,asdl_arg_seq ** posargs)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 != NULL) {
599         asdl_arg_seq *names_with_default_names = _get_names(p, names_with_default);
600         if (!names_with_default_names) {
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) {
607         *posargs = _get_names(p, names_with_default);
608     }
609     else if (plain_names != NULL && names_with_default == NULL) {
610         *posargs = plain_names;
611     }
612     else {
613         *posargs = _Py_asdl_arg_seq_new(0, p->arena);
614     }
615     return *posargs == NULL ? -1 : 0;
616 }
617 
618 static int
_make_posdefaults(Parser * p,SlashWithDefault * slash_with_default,asdl_seq * names_with_default,asdl_expr_seq ** posdefaults)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 != NULL) {
624         asdl_expr_seq *slash_with_default_values =
625                 _get_defaults(p, slash_with_default->names_with_defaults);
626         if (!slash_with_default_values) {
627             return -1;
628         }
629         asdl_expr_seq *names_with_default_values = _get_defaults(p, names_with_default);
630         if (!names_with_default_values) {
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) {
639         *posdefaults = _get_defaults(p, names_with_default);
640     }
641     else if (slash_with_default != NULL && names_with_default == NULL) {
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 ? -1 : 0;
648 }
649 
650 static int
_make_kwargs(Parser * p,StarEtc * star_etc,asdl_arg_seq ** kwonlyargs,asdl_expr_seq ** kwdefaults)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 != NULL) {
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) {
662         return -1;
663     }
664 
665     if (star_etc != NULL && star_etc->kwonlyargs != NULL) {
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) {
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
_PyPegen_make_arguments(Parser * p,asdl_arg_seq * slash_without_default,SlashWithDefault * slash_with_default,asdl_arg_seq * plain_names,asdl_seq * names_with_default,StarEtc * star_etc)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) {
687         return NULL;
688     }
689 
690     asdl_arg_seq *posargs;
691     if (_make_posargs(p, plain_names, names_with_default, &posargs) == -1) {
692         return NULL;
693     }
694 
695     asdl_expr_seq *posdefaults;
696     if (_make_posdefaults(p,slash_with_default, names_with_default, &posdefaults) == -1) {
697         return NULL;
698     }
699 
700     arg_ty vararg = NULL;
701     if (star_etc != NULL && star_etc->vararg != NULL) {
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) {
708         return NULL;
709     }
710 
711     arg_ty kwarg = NULL;
712     if (star_etc != NULL && star_etc->kwarg != NULL) {
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
_PyPegen_empty_arguments(Parser * p)724 _PyPegen_empty_arguments(Parser *p)
725 {
726     asdl_arg_seq *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
727     if (!posonlyargs) {
728         return NULL;
729     }
730     asdl_arg_seq *posargs = _Py_asdl_arg_seq_new(0, p->arena);
731     if (!posargs) {
732         return NULL;
733     }
734     asdl_expr_seq *posdefaults = _Py_asdl_expr_seq_new(0, p->arena);
735     if (!posdefaults) {
736         return NULL;
737     }
738     asdl_arg_seq *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena);
739     if (!kwonlyargs) {
740         return NULL;
741     }
742     asdl_expr_seq *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena);
743     if (!kwdefaults) {
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 *
_PyPegen_augoperator(Parser * p,operator_ty kind)753 _PyPegen_augoperator(Parser *p, operator_ty kind)
754 {
755     AugOperator *a = _PyArena_Malloc(p->arena, sizeof(AugOperator));
756     if (!a) {
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
_PyPegen_function_def_decorators(Parser * p,asdl_expr_seq * decorators,stmt_ty function_def)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) {
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
_PyPegen_class_def_decorators(Parser * p,asdl_expr_seq * decorators,stmt_ty class_def)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 *
_PyPegen_keyword_or_starred(Parser * p,void * element,int is_keyword)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) {
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
_seq_number_of_starred_exprs(asdl_seq * seq)813 _seq_number_of_starred_exprs(asdl_seq *seq)
814 {
815     int n = 0;
816     for (Py_ssize_t i = 0, l = asdl_seq_LEN(seq); i < l; i++) {
817         KeywordOrStarred *k = asdl_seq_GET_UNTYPED(seq, i);
818         if (!k->is_keyword) {
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 *
_PyPegen_seq_extract_starred_exprs(Parser * p,asdl_seq * kwargs)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) {
831         return NULL;
832     }
833     asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(new_len, p->arena);
834     if (!new_seq) {
835         return NULL;
836     }
837 
838     int idx = 0;
839     for (Py_ssize_t i = 0, len = asdl_seq_LEN(kwargs); i < len; i++) {
840         KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i);
841         if (!k->is_keyword) {
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*
_PyPegen_seq_delete_starred_exprs(Parser * p,asdl_seq * kwargs)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) {
855         return NULL;
856     }
857     asdl_keyword_seq *new_seq = _Py_asdl_keyword_seq_new(new_len, p->arena);
858     if (!new_seq) {
859         return NULL;
860     }
861 
862     int idx = 0;
863     for (Py_ssize_t i = 0; i < len; i++) {
864         KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i);
865         if (k->is_keyword) {
866             asdl_seq_SET(new_seq, idx++, k->element);
867         }
868     }
869     return new_seq;
870 }
871 
872 expr_ty
_PyPegen_concatenate_strings(Parser * p,asdl_seq * strings)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++) {
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) {
897             goto error;
898         }
899 
900         /* Check that we are not mixing bytes with unicode. */
901         if (i != 0 && bytesmode != this_bytesmode) {
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) {
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) {
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) {
923                 if (i == 0) {
924                     bytes_str = s;
925                 }
926                 else {
927                     PyBytes_ConcatAndDel(&bytes_str, s);
928                     if (!bytes_str) {
929                         goto error;
930                     }
931                 }
932             }
933             else {
934                 /* This is a regular string. Concatenate it. */
935                 if (_PyPegen_FstringParser_ConcatAndDel(&state, s) < 0) {
936                     goto error;
937                 }
938             }
939         }
940     }
941 
942     if (bytesmode) {
943         if (_PyArena_AddPyObject(p->arena, bytes_str) < 0) {
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()) {
957         _Pypegen_raise_decode_error(p);
958     }
959     return NULL;
960 }
961 
962 expr_ty
_PyPegen_ensure_imaginary(Parser * p,expr_ty exp)963 _PyPegen_ensure_imaginary(Parser *p, expr_ty exp)
964 {
965     if (exp->kind != Constant_kind || !PyComplex_CheckExact(exp->v.Constant.value)) {
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
_PyPegen_ensure_real(Parser * p,expr_ty exp)973 _PyPegen_ensure_real(Parser *p, expr_ty exp)
974 {
975     if (exp->kind != Constant_kind || PyComplex_CheckExact(exp->v.Constant.value)) {
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
_PyPegen_make_module(Parser * p,asdl_stmt_seq * a)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) {
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) {
990             return NULL;
991         }
992         for (int i = 0; i < num; i++) {
993             PyObject *tag = _PyPegen_new_type_comment(p, p->type_ignore_comments.items[i].comment);
994             if (tag == NULL) {
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) {
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 *
_PyPegen_new_type_comment(Parser * p,const char * s)1009 _PyPegen_new_type_comment(Parser *p, const char *s)
1010 {
1011     PyObject *res = PyUnicode_DecodeUTF8(s, strlen(s), NULL);
1012     if (res == NULL) {
1013         return NULL;
1014     }
1015     if (_PyArena_AddPyObject(p->arena, res) < 0) {
1016         Py_DECREF(res);
1017         return NULL;
1018     }
1019     return res;
1020 }
1021 
1022 arg_ty
_PyPegen_add_type_comment_to_arg(Parser * p,arg_ty a,Token * tc)1023 _PyPegen_add_type_comment_to_arg(Parser *p, arg_ty a, Token *tc)
1024 {
1025     if (tc == NULL) {
1026         return a;
1027     }
1028     const char *bytes = PyBytes_AsString(tc->bytes);
1029     if (bytes == NULL) {
1030         return NULL;
1031     }
1032     PyObject *tco = _PyPegen_new_type_comment(p, bytes);
1033     if (tco == NULL) {
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
_PyPegen_check_barry_as_flufl(Parser * p,Token * t)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, "<>") != 0) {
1050         RAISE_SYNTAX_ERROR("with Barry as BDFL, use '<>' instead of '!='");
1051         return -1;
1052     }
1053     if (!(p->flags & PyPARSE_BARRY_AS_BDFL)) {
1054         return strcmp(tok_str, "!=");
1055     }
1056     return 0;
1057 }
1058 
1059 int
_PyPegen_check_legacy_stmt(Parser * p,expr_ty name)1060 _PyPegen_check_legacy_stmt(Parser *p, expr_ty name) {
1061     if (name->kind != Name_kind) {
1062         return 0;
1063     }
1064     const char* candidates[2] = {"print", "exec"};
1065     for (int i=0; i<2; i++) {
1066         if (PyUnicode_CompareWithASCIIString(name->v.Name.id, candidates[i]) == 0) {
1067             return 1;
1068         }
1069     }
1070     return 0;
1071 }
1072 
1073 const char *
_PyPegen_get_expr_name(expr_ty e)1074 _PyPegen_get_expr_name(expr_ty e)
1075 {
1076     assert(e != NULL);
1077     switch (e->kind) {
1078         case Attribute_kind:
1079             return "attribute";
1080         case Subscript_kind:
1081             return "subscript";
1082         case Starred_kind:
1083             return "starred";
1084         case Name_kind:
1085             return "name";
1086         case List_kind:
1087             return "list";
1088         case Tuple_kind:
1089             return "tuple";
1090         case Lambda_kind:
1091             return "lambda";
1092         case Call_kind:
1093             return "function call";
1094         case BoolOp_kind:
1095         case BinOp_kind:
1096         case UnaryOp_kind:
1097             return "expression";
1098         case GeneratorExp_kind:
1099             return "generator expression";
1100         case Yield_kind:
1101         case YieldFrom_kind:
1102             return "yield expression";
1103         case Await_kind:
1104             return "await expression";
1105         case ListComp_kind:
1106             return "list comprehension";
1107         case SetComp_kind:
1108             return "set comprehension";
1109         case DictComp_kind:
1110             return "dict comprehension";
1111         case Dict_kind:
1112             return "dict literal";
1113         case Set_kind:
1114             return "set display";
1115         case JoinedStr_kind:
1116         case FormattedValue_kind:
1117             return "f-string expression";
1118         case Constant_kind: {
1119             PyObject *value = e->v.Constant.value;
1120             if (value == Py_None) {
1121                 return "None";
1122             }
1123             if (value == Py_False) {
1124                 return "False";
1125             }
1126             if (value == Py_True) {
1127                 return "True";
1128             }
1129             if (value == Py_Ellipsis) {
1130                 return "ellipsis";
1131             }
1132             return "literal";
1133         }
1134         case Compare_kind:
1135             return "comparison";
1136         case IfExp_kind:
1137             return "conditional expression";
1138         case NamedExpr_kind:
1139             return "named expression";
1140         default:
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
_PyPegen_get_last_comprehension_item(comprehension_ty comprehension)1149 _PyPegen_get_last_comprehension_item(comprehension_ty comprehension) {
1150     if (comprehension->ifs == NULL || asdl_seq_LEN(comprehension->ifs) == 0) {
1151         return comprehension->iter;
1152     }
1153     return PyPegen_last_item(comprehension->ifs, expr_ty);
1154 }
1155 
_PyPegen_collect_call_seqs(Parser * p,asdl_expr_seq * a,asdl_seq * b,int lineno,int col_offset,int end_lineno,int end_col_offset,PyArena * arena)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) {
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) {
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++) {
1179         asdl_seq_SET(args, i, asdl_seq_GET(a, i));
1180     }
1181     for (; i < total_len; i++) {
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
_PyPegen_get_invalid_target(expr_ty e,TARGETS_TYPE targets_type)1192 _PyPegen_get_invalid_target(expr_ty e, TARGETS_TYPE targets_type)
1193 {
1194     if (e == NULL) {
1195         return NULL;
1196     }
1197 
1198 #define VISIT_CONTAINER(CONTAINER, TYPE) do { \
1199         Py_ssize_t len = asdl_seq_LEN((CONTAINER)->v.TYPE.elts);\
1200         for (Py_ssize_t i = 0; i < len; i++) {\
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 (0)
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:
1217             VISIT_CONTAINER(e, List);
1218             return NULL;
1219         case Tuple_kind:
1220             VISIT_CONTAINER(e, Tuple);
1221             return NULL;
1222         case Starred_kind:
1223             if (targets_type == DEL_TARGETS) {
1224                 return e;
1225             }
1226             return _PyPegen_get_invalid_target(e->v.Starred.value, targets_type);
1227         case Compare_kind:
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) {
1232                 cmpop_ty cmpop = (cmpop_ty) asdl_seq_GET(e->v.Compare.ops, 0);
1233                 if (cmpop == In) {
1234                     return _PyPegen_get_invalid_target(e->v.Compare.left, targets_type);
1235                 }
1236                 return NULL;
1237             }
1238             return e;
1239         case Name_kind:
1240         case Subscript_kind:
1241         case Attribute_kind:
1242             return NULL;
1243         default:
1244             return e;
1245     }
1246 }
1247 
_PyPegen_arguments_parsing_error(Parser * p,expr_ty e)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_LEN(e->v.Call.keywords); i < l; i++) {
1251         keyword_ty keyword = asdl_seq_GET(e->v.Call.keywords, i);
1252         if (!keyword->arg) {
1253             kwarg_unpacking = 1;
1254         }
1255     }
1256 
1257     const char *msg = NULL;
1258     if (kwarg_unpacking) {
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 *
_PyPegen_nonparen_genexp_in_call(Parser * p,expr_ty args,asdl_comprehension_seq * comprehensions)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) {
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 }