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