blob: 1ecb2c4a16df9fe6987eabb57eab0178f3398ad7 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* Parser-tokenizer link implementation */
3
Pablo Galindof2cf1e32019-04-13 17:05:14 +01004#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005#include "tokenizer.h"
6#include "node.h"
7#include "grammar.h"
8#include "parser.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +00009#include "parsetok.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010#include "errcode.h"
Martin v. Löwis00f1e3f2002-08-04 17:29:52 +000011#include "graminit.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012
Guido van Rossum3f5da241990-12-20 15:06:42 +000013
14/* Forward */
Christian Heimes4d6ec852008-03-26 22:34:47 +000015static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int *);
Victor Stinner14e461d2013-08-26 22:28:21 +020016static int initerr(perrdetail *err_ret, PyObject * filename);
Guido van Rossum3f5da241990-12-20 15:06:42 +000017
Guido van Rossumdcfcd142019-01-31 03:40:27 -080018typedef struct {
Michael J. Sullivan933e1502019-05-22 07:54:20 -070019 struct {
20 int lineno;
21 char *comment;
22 } *items;
Guido van Rossumdcfcd142019-01-31 03:40:27 -080023 size_t size;
24 size_t num_items;
Michael J. Sullivan933e1502019-05-22 07:54:20 -070025} growable_comment_array;
Guido van Rossumdcfcd142019-01-31 03:40:27 -080026
27static int
Michael J. Sullivan933e1502019-05-22 07:54:20 -070028growable_comment_array_init(growable_comment_array *arr, size_t initial_size) {
Guido van Rossumdcfcd142019-01-31 03:40:27 -080029 assert(initial_size > 0);
30 arr->items = malloc(initial_size * sizeof(*arr->items));
31 arr->size = initial_size;
32 arr->num_items = 0;
33
34 return arr->items != NULL;
35}
36
37static int
Michael J. Sullivan933e1502019-05-22 07:54:20 -070038growable_comment_array_add(growable_comment_array *arr, int lineno, char *comment) {
Guido van Rossumdcfcd142019-01-31 03:40:27 -080039 if (arr->num_items >= arr->size) {
Alexander Riccio51e3e452020-03-30 17:15:59 -040040 size_t new_size = arr->size * 2;
41 void *new_items_array = realloc(arr->items, new_size * sizeof(*arr->items));
42 if (!new_items_array) {
Guido van Rossumdcfcd142019-01-31 03:40:27 -080043 return 0;
44 }
Alexander Riccio51e3e452020-03-30 17:15:59 -040045 arr->items = new_items_array;
46 arr->size = new_size;
Guido van Rossumdcfcd142019-01-31 03:40:27 -080047 }
48
Michael J. Sullivan933e1502019-05-22 07:54:20 -070049 arr->items[arr->num_items].lineno = lineno;
50 arr->items[arr->num_items].comment = comment;
Guido van Rossumdcfcd142019-01-31 03:40:27 -080051 arr->num_items++;
52 return 1;
53}
54
55static void
Michael J. Sullivan933e1502019-05-22 07:54:20 -070056growable_comment_array_deallocate(growable_comment_array *arr) {
57 for (unsigned i = 0; i < arr->num_items; i++) {
58 PyObject_FREE(arr->items[i].comment);
59 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -080060 free(arr->items);
61}
62
Guido van Rossum3f5da241990-12-20 15:06:42 +000063/* Parse input coming from a string. Return error code, print some errors. */
Guido van Rossumbd0389d1994-08-29 12:25:45 +000064node *
Martin v. Löwis95292d62002-12-11 14:04:59 +000065PyParser_ParseString(const char *s, grammar *g, int start, perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000066{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000067 return PyParser_ParseStringFlagsFilename(s, NULL, g, start, err_ret, 0);
Tim Petersfe2127d2001-07-16 05:37:24 +000068}
69
70node *
Martin v. Löwis95292d62002-12-11 14:04:59 +000071PyParser_ParseStringFlags(const char *s, grammar *g, int start,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000072 perrdetail *err_ret, int flags)
Tim Petersfe2127d2001-07-16 05:37:24 +000073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 return PyParser_ParseStringFlagsFilename(s, NULL,
75 g, start, err_ret, flags);
Thomas Heller6b17abf2002-07-09 09:23:27 +000076}
77
78node *
Martin v. Löwis95292d62002-12-11 14:04:59 +000079PyParser_ParseStringFlagsFilename(const char *s, const char *filename,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080 grammar *g, int start,
81 perrdetail *err_ret, int flags)
Thomas Heller6b17abf2002-07-09 09:23:27 +000082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 int iflags = flags;
84 return PyParser_ParseStringFlagsFilenameEx(s, filename, g, start,
85 err_ret, &iflags);
Christian Heimes4d6ec852008-03-26 22:34:47 +000086}
87
88node *
Victor Stinner14e461d2013-08-26 22:28:21 +020089PyParser_ParseStringObject(const char *s, PyObject *filename,
90 grammar *g, int start,
91 perrdetail *err_ret, int *flags)
Christian Heimes4d6ec852008-03-26 22:34:47 +000092{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 struct tok_state *tok;
94 int exec_input = start == file_input;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000095
Victor Stinner7f2fee32011-04-05 00:39:01 +020096 if (initerr(err_ret, filename) < 0)
97 return NULL;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000098
Steve Dowerb82e17e2019-05-23 08:45:22 -070099 if (PySys_Audit("compile", "yO", s, err_ret->filename) < 0) {
100 err_ret->error = E_ERROR;
101 return NULL;
102 }
103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 if (*flags & PyPARSE_IGNORE_COOKIE)
105 tok = PyTokenizer_FromUTF8(s, exec_input);
106 else
107 tok = PyTokenizer_FromString(s, exec_input);
108 if (tok == NULL) {
109 err_ret->error = PyErr_Occurred() ? E_DECODE : E_NOMEM;
110 return NULL;
111 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800112 if (*flags & PyPARSE_TYPE_COMMENTS) {
113 tok->type_comments = 1;
114 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000115
Victor Stinner7f2fee32011-04-05 00:39:01 +0200116 Py_INCREF(err_ret->filename);
117 tok->filename = err_ret->filename;
Guido van Rossum495da292019-03-07 12:38:08 -0800118 if (*flags & PyPARSE_ASYNC_HACKS)
119 tok->async_hacks = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 return parsetok(tok, g, start, err_ret, flags);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000121}
122
Victor Stinner14e461d2013-08-26 22:28:21 +0200123node *
124PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename_str,
125 grammar *g, int start,
126 perrdetail *err_ret, int *flags)
127{
128 node *n;
129 PyObject *filename = NULL;
Victor Stinner14e461d2013-08-26 22:28:21 +0200130 if (filename_str != NULL) {
131 filename = PyUnicode_DecodeFSDefault(filename_str);
132 if (filename == NULL) {
133 err_ret->error = E_ERROR;
134 return NULL;
135 }
136 }
Victor Stinner14e461d2013-08-26 22:28:21 +0200137 n = PyParser_ParseStringObject(s, filename, g, start, err_ret, flags);
Victor Stinner14e461d2013-08-26 22:28:21 +0200138 Py_XDECREF(filename);
Victor Stinner14e461d2013-08-26 22:28:21 +0200139 return n;
140}
141
Guido van Rossum3f5da241990-12-20 15:06:42 +0000142/* Parse input coming from a file. Return error code, print some errors. */
143
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000144node *
Martin v. Löwis95292d62002-12-11 14:04:59 +0000145PyParser_ParseFile(FILE *fp, const char *filename, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300146 const char *ps1, const char *ps2,
147 perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 return PyParser_ParseFileFlags(fp, filename, NULL,
150 g, start, ps1, ps2, err_ret, 0);
Tim Petersfe2127d2001-07-16 05:37:24 +0000151}
152
153node *
Christian Heimes4d6ec852008-03-26 22:34:47 +0000154PyParser_ParseFileFlags(FILE *fp, const char *filename, const char *enc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300156 const char *ps1, const char *ps2,
157 perrdetail *err_ret, int flags)
Tim Petersfe2127d2001-07-16 05:37:24 +0000158{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 int iflags = flags;
160 return PyParser_ParseFileFlagsEx(fp, filename, enc, g, start, ps1,
161 ps2, err_ret, &iflags);
Christian Heimes4d6ec852008-03-26 22:34:47 +0000162}
163
164node *
Victor Stinner14e461d2013-08-26 22:28:21 +0200165PyParser_ParseFileObject(FILE *fp, PyObject *filename,
166 const char *enc, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300167 const char *ps1, const char *ps2,
168 perrdetail *err_ret, int *flags)
Christian Heimes4d6ec852008-03-26 22:34:47 +0000169{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000170 struct tok_state *tok;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000171
Victor Stinner7f2fee32011-04-05 00:39:01 +0200172 if (initerr(err_ret, filename) < 0)
173 return NULL;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000174
Steve Dowerb82e17e2019-05-23 08:45:22 -0700175 if (PySys_Audit("compile", "OO", Py_None, err_ret->filename) < 0) {
176 return NULL;
177 }
178
Serhiy Storchakac6792272013-10-19 21:03:34 +0300179 if ((tok = PyTokenizer_FromFile(fp, enc, ps1, ps2)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 err_ret->error = E_NOMEM;
181 return NULL;
182 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800183 if (*flags & PyPARSE_TYPE_COMMENTS) {
184 tok->type_comments = 1;
185 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200186 Py_INCREF(err_ret->filename);
187 tok->filename = err_ret->filename;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 return parsetok(tok, g, start, err_ret, flags);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000189}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000190
Victor Stinner14e461d2013-08-26 22:28:21 +0200191node *
192PyParser_ParseFileFlagsEx(FILE *fp, const char *filename,
193 const char *enc, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300194 const char *ps1, const char *ps2,
195 perrdetail *err_ret, int *flags)
Victor Stinner14e461d2013-08-26 22:28:21 +0200196{
197 node *n;
198 PyObject *fileobj = NULL;
Victor Stinner14e461d2013-08-26 22:28:21 +0200199 if (filename != NULL) {
200 fileobj = PyUnicode_DecodeFSDefault(filename);
201 if (fileobj == NULL) {
202 err_ret->error = E_ERROR;
203 return NULL;
204 }
205 }
Victor Stinner14e461d2013-08-26 22:28:21 +0200206 n = PyParser_ParseFileObject(fp, fileobj, enc, g,
207 start, ps1, ps2, err_ret, flags);
Victor Stinner14e461d2013-08-26 22:28:21 +0200208 Py_XDECREF(fileobj);
Victor Stinner14e461d2013-08-26 22:28:21 +0200209 return n;
210}
211
Thomas Wouters89f507f2006-12-13 04:49:30 +0000212/* Parse input coming from the given tokenizer structure.
213 Return error code. */
214
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000215static node *
Tim Petersfe2127d2001-07-16 05:37:24 +0000216parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 int *flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000219 parser_state *ps;
220 node *n;
Brett Cannonb94767f2011-02-22 20:15:44 +0000221 int started = 0;
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000222 int col_offset, end_col_offset;
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700223 growable_comment_array type_ignores;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800224
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700225 if (!growable_comment_array_init(&type_ignores, 10)) {
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800226 err_ret->error = E_NOMEM;
227 PyTokenizer_Free(tok);
228 return NULL;
229 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 if ((ps = PyParser_New(g, start)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232 err_ret->error = E_NOMEM;
Alex Henrie7ba6f182020-01-13 03:35:47 -0700233 growable_comment_array_deallocate(&type_ignores);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 PyTokenizer_Free(tok);
235 return NULL;
236 }
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000237#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 if (*flags & PyPARSE_BARRY_AS_BDFL)
239 ps->p_flags |= CO_FUTURE_BARRY_AS_BDFL;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800240 if (*flags & PyPARSE_TYPE_COMMENTS)
241 ps->p_flags |= PyCF_TYPE_COMMENTS;
Neil Schemenauerc24ea082002-03-22 23:53:36 +0000242#endif
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 for (;;) {
Andy Lester384f3c52020-02-27 20:44:52 -0600245 const char *a, *b;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 int type;
247 size_t len;
248 char *str;
Ammar Askar025eb982018-09-24 17:12:49 -0400249 col_offset = -1;
Anthony Sottile995d9b92019-01-12 20:05:13 -0800250 int lineno;
251 const char *line_start;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 type = PyTokenizer_Get(tok, &a, &b);
Pablo Galindo11a7f152020-04-21 01:53:04 +0100254
Zackery Spytz7c4ab2a2018-08-15 00:27:26 -0600255 len = (a != NULL && b != NULL) ? b - a : 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 str = (char *) PyObject_MALLOC(len + 1);
257 if (str == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 err_ret->error = E_NOMEM;
259 break;
260 }
261 if (len > 0)
262 strncpy(str, a, len);
263 str[len] = '\0';
Guido van Rossumda62ecc2001-07-17 16:53:11 +0000264
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000265#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 if (type == NOTEQUAL) {
267 if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
268 strcmp(str, "!=")) {
Antoine Pitrou9ec25932011-11-13 01:01:23 +0100269 PyObject_FREE(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 err_ret->error = E_SYNTAX;
271 break;
272 }
273 else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
274 strcmp(str, "<>")) {
Antoine Pitrou9ec25932011-11-13 01:01:23 +0100275 PyObject_FREE(str);
Serhiy Storchakaaba24ff2018-07-23 23:41:11 +0300276 err_ret->expected = NOTEQUAL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 err_ret->error = E_SYNTAX;
278 break;
279 }
280 }
Neil Schemenauerc24ea082002-03-22 23:53:36 +0000281#endif
Anthony Sottile995d9b92019-01-12 20:05:13 -0800282
283 /* Nodes of type STRING, especially multi line strings
284 must be handled differently in order to get both
285 the starting line number and the column offset right.
286 (cf. issue 16806) */
287 lineno = type == STRING ? tok->first_lineno : tok->lineno;
288 line_start = type == STRING ? tok->multi_line_start : tok->line_start;
289 if (a != NULL && a >= line_start) {
290 col_offset = Py_SAFE_DOWNCAST(a - line_start,
Benjamin Petersonca470632016-09-06 13:47:26 -0700291 intptr_t, int);
Zackery Spytz3e26e422018-08-20 21:11:40 -0600292 }
293 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 col_offset = -1;
Zackery Spytz3e26e422018-08-20 21:11:40 -0600295 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000296
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000297 if (b != NULL && b >= tok->line_start) {
298 end_col_offset = Py_SAFE_DOWNCAST(b - tok->line_start,
299 intptr_t, int);
300 }
301 else {
302 end_col_offset = -1;
303 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800304
305 if (type == TYPE_IGNORE) {
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700306 if (!growable_comment_array_add(&type_ignores, tok->lineno, str)) {
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800307 err_ret->error = E_NOMEM;
308 break;
309 }
310 continue;
311 }
312
Pablo Galindo11a7f152020-04-21 01:53:04 +0100313 if (type == ERRORTOKEN) {
314 err_ret->error = tok->done;
315 break;
316 }
317 if (type == ENDMARKER && started) {
318 type = NEWLINE; /* Add an extra newline */
319 started = 0;
320 /* Add the right number of dedent tokens,
321 except if a certain flag is given --
322 codeop.py uses this. */
323 if (tok->indent &&
324 !(*flags & PyPARSE_DONT_IMPLY_DEDENT))
325 {
326 tok->pendin = -tok->indent;
327 tok->indent = 0;
328 }
329 }
330 else {
331 started = 1;
332 }
333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334 if ((err_ret->error =
335 PyParser_AddToken(ps, (int)type, str,
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000336 lineno, col_offset, tok->lineno, end_col_offset,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 &(err_ret->expected))) != E_OK) {
Lysandros Nikolaou9a4b38f2020-04-15 21:22:10 +0300338 if (tok->done == E_EOF && !ISWHITESPACE(type)) {
339 tok->done = E_SYNTAX;
340 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 if (err_ret->error != E_DONE) {
342 PyObject_FREE(str);
343 err_ret->token = type;
344 }
345 break;
346 }
347 }
348
349 if (err_ret->error == E_DONE) {
350 n = ps->p_tree;
351 ps->p_tree = NULL;
Meador Ingefa21bf02012-01-19 01:08:41 -0600352
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800353 if (n->n_type == file_input) {
354 /* Put type_ignore nodes in the ENDMARKER of file_input. */
355 int num;
356 node *ch;
357 size_t i;
358
359 num = NCH(n);
360 ch = CHILD(n, num - 1);
361 REQ(ch, ENDMARKER);
362
363 for (i = 0; i < type_ignores.num_items; i++) {
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700364 int res = PyNode_AddChild(ch, TYPE_IGNORE, type_ignores.items[i].comment,
365 type_ignores.items[i].lineno, 0,
366 type_ignores.items[i].lineno, 0);
367 if (res != 0) {
368 err_ret->error = res;
369 PyNode_Free(n);
370 n = NULL;
371 break;
372 }
373 type_ignores.items[i].comment = NULL;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800374 }
375 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800376
Meador Ingefa21bf02012-01-19 01:08:41 -0600377 /* Check that the source for a single input statement really
378 is a single statement by looking at what is left in the
379 buffer after parsing. Trailing whitespace and comments
380 are OK. */
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700381 if (err_ret->error == E_DONE && start == single_input) {
Andy Lester384f3c52020-02-27 20:44:52 -0600382 const char *cur = tok->cur;
Meador Ingefa21bf02012-01-19 01:08:41 -0600383 char c = *tok->cur;
384
Benjamin Petersoncff92372012-01-19 17:46:13 -0500385 for (;;) {
386 while (c == ' ' || c == '\t' || c == '\n' || c == '\014')
387 c = *++cur;
Meador Ingefa21bf02012-01-19 01:08:41 -0600388
Benjamin Petersoncff92372012-01-19 17:46:13 -0500389 if (!c)
390 break;
391
392 if (c != '#') {
393 err_ret->error = E_BADSINGLE;
394 PyNode_Free(n);
395 n = NULL;
396 break;
397 }
398
399 /* Suck up comment. */
400 while (c && c != '\n')
401 c = *++cur;
Meador Ingefa21bf02012-01-19 01:08:41 -0600402 }
403 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 }
405 else
406 n = NULL;
Christian Heimesb1b3efc2008-03-26 23:24:27 +0000407
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700408 growable_comment_array_deallocate(&type_ignores);
Pablo Galindob9d2e972019-02-13 00:45:53 +0000409
Christian Heimes4d6ec852008-03-26 22:34:47 +0000410#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 *flags = ps->p_flags;
Christian Heimes4d6ec852008-03-26 22:34:47 +0000412#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 PyParser_Delete(ps);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 if (n == NULL) {
Benjamin Peterson758888d2011-05-30 11:12:38 -0500416 if (tok->done == E_EOF)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 err_ret->error = E_EOF;
418 err_ret->lineno = tok->lineno;
419 if (tok->buf != NULL) {
420 size_t len;
421 assert(tok->cur - tok->buf < INT_MAX);
Ammar Askar025eb982018-09-24 17:12:49 -0400422 /* if we've managed to parse a token, point the offset to its start,
423 * else use the current reading position of the tokenizer
424 */
425 err_ret->offset = col_offset != -1 ? col_offset + 1 : ((int)(tok->cur - tok->buf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 len = tok->inp - tok->buf;
427 err_ret->text = (char *) PyObject_MALLOC(len + 1);
428 if (err_ret->text != NULL) {
429 if (len > 0)
430 strncpy(err_ret->text, tok->buf, len);
431 err_ret->text[len] = '\0';
432 }
433 }
434 } else if (tok->encoding != NULL) {
435 /* 'nodes->n_str' uses PyObject_*, while 'tok->encoding' was
436 * allocated using PyMem_
437 */
438 node* r = PyNode_New(encoding_decl);
439 if (r)
440 r->n_str = PyObject_MALLOC(strlen(tok->encoding)+1);
441 if (!r || !r->n_str) {
442 err_ret->error = E_NOMEM;
443 if (r)
444 PyObject_FREE(r);
445 n = NULL;
446 goto done;
447 }
448 strcpy(r->n_str, tok->encoding);
449 PyMem_FREE(tok->encoding);
450 tok->encoding = NULL;
451 r->n_nchildren = 1;
452 r->n_child = n;
453 n = r;
454 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000455
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000456done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 PyTokenizer_Free(tok);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000458
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000459 if (n != NULL) {
460 _PyNode_FinalizeEndPos(n);
461 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 return n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000463}
Guido van Rossum0c156a52001-10-20 14:27:56 +0000464
Victor Stinner7f2fee32011-04-05 00:39:01 +0200465static int
Victor Stinner14e461d2013-08-26 22:28:21 +0200466initerr(perrdetail *err_ret, PyObject *filename)
Guido van Rossum0c156a52001-10-20 14:27:56 +0000467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 err_ret->error = E_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 err_ret->lineno = 0;
470 err_ret->offset = 0;
471 err_ret->text = NULL;
472 err_ret->token = -1;
473 err_ret->expected = -1;
Victor Stinner14e461d2013-08-26 22:28:21 +0200474 if (filename) {
475 Py_INCREF(filename);
476 err_ret->filename = filename;
477 }
478 else {
Victor Stinner7f2fee32011-04-05 00:39:01 +0200479 err_ret->filename = PyUnicode_FromString("<string>");
Victor Stinner14e461d2013-08-26 22:28:21 +0200480 if (err_ret->filename == NULL) {
481 err_ret->error = E_ERROR;
482 return -1;
483 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200484 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200485 return 0;
Guido van Rossum0c156a52001-10-20 14:27:56 +0000486}