blob: 7fddc5a0e8975e86bcbf3bee84e70a05490f8ec9 [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
Guido van Rossum3f5da241990-12-20 15:06:42 +00004#include "pgenheaders.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 {
19 int *items;
20 size_t size;
21 size_t num_items;
22} growable_int_array;
23
24static int
25growable_int_array_init(growable_int_array *arr, size_t initial_size) {
26 assert(initial_size > 0);
27 arr->items = malloc(initial_size * sizeof(*arr->items));
28 arr->size = initial_size;
29 arr->num_items = 0;
30
31 return arr->items != NULL;
32}
33
34static int
35growable_int_array_add(growable_int_array *arr, int item) {
36 if (arr->num_items >= arr->size) {
37 arr->size *= 2;
38 arr->items = realloc(arr->items, arr->size * sizeof(*arr->items));
39 if (!arr->items) {
40 return 0;
41 }
42 }
43
44 arr->items[arr->num_items] = item;
45 arr->num_items++;
46 return 1;
47}
48
49static void
50growable_int_array_deallocate(growable_int_array *arr) {
51 free(arr->items);
52}
53
Guido van Rossum3f5da241990-12-20 15:06:42 +000054/* Parse input coming from a string. Return error code, print some errors. */
Guido van Rossumbd0389d1994-08-29 12:25:45 +000055node *
Martin v. Löwis95292d62002-12-11 14:04:59 +000056PyParser_ParseString(const char *s, grammar *g, int start, perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000057{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058 return PyParser_ParseStringFlagsFilename(s, NULL, g, start, err_ret, 0);
Tim Petersfe2127d2001-07-16 05:37:24 +000059}
60
61node *
Martin v. Löwis95292d62002-12-11 14:04:59 +000062PyParser_ParseStringFlags(const char *s, grammar *g, int start,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 perrdetail *err_ret, int flags)
Tim Petersfe2127d2001-07-16 05:37:24 +000064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 return PyParser_ParseStringFlagsFilename(s, NULL,
66 g, start, err_ret, flags);
Thomas Heller6b17abf2002-07-09 09:23:27 +000067}
68
69node *
Martin v. Löwis95292d62002-12-11 14:04:59 +000070PyParser_ParseStringFlagsFilename(const char *s, const char *filename,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000071 grammar *g, int start,
72 perrdetail *err_ret, int flags)
Thomas Heller6b17abf2002-07-09 09:23:27 +000073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 int iflags = flags;
75 return PyParser_ParseStringFlagsFilenameEx(s, filename, g, start,
76 err_ret, &iflags);
Christian Heimes4d6ec852008-03-26 22:34:47 +000077}
78
79node *
Victor Stinner14e461d2013-08-26 22:28:21 +020080PyParser_ParseStringObject(const char *s, PyObject *filename,
81 grammar *g, int start,
82 perrdetail *err_ret, int *flags)
Christian Heimes4d6ec852008-03-26 22:34:47 +000083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 struct tok_state *tok;
85 int exec_input = start == file_input;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000086
Victor Stinner7f2fee32011-04-05 00:39:01 +020087 if (initerr(err_ret, filename) < 0)
88 return NULL;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 if (*flags & PyPARSE_IGNORE_COOKIE)
91 tok = PyTokenizer_FromUTF8(s, exec_input);
92 else
93 tok = PyTokenizer_FromString(s, exec_input);
94 if (tok == NULL) {
95 err_ret->error = PyErr_Occurred() ? E_DECODE : E_NOMEM;
96 return NULL;
97 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -080098 if (*flags & PyPARSE_TYPE_COMMENTS) {
99 tok->type_comments = 1;
100 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000101
Victor Stinner7f2fee32011-04-05 00:39:01 +0200102#ifndef PGEN
103 Py_INCREF(err_ret->filename);
104 tok->filename = err_ret->filename;
105#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 return parsetok(tok, g, start, err_ret, flags);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000107}
108
Victor Stinner14e461d2013-08-26 22:28:21 +0200109node *
110PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename_str,
111 grammar *g, int start,
112 perrdetail *err_ret, int *flags)
113{
114 node *n;
115 PyObject *filename = NULL;
116#ifndef PGEN
117 if (filename_str != NULL) {
118 filename = PyUnicode_DecodeFSDefault(filename_str);
119 if (filename == NULL) {
120 err_ret->error = E_ERROR;
121 return NULL;
122 }
123 }
124#endif
125 n = PyParser_ParseStringObject(s, filename, g, start, err_ret, flags);
126#ifndef PGEN
127 Py_XDECREF(filename);
128#endif
129 return n;
130}
131
Guido van Rossum3f5da241990-12-20 15:06:42 +0000132/* Parse input coming from a file. Return error code, print some errors. */
133
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000134node *
Martin v. Löwis95292d62002-12-11 14:04:59 +0000135PyParser_ParseFile(FILE *fp, const char *filename, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300136 const char *ps1, const char *ps2,
137 perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000138{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 return PyParser_ParseFileFlags(fp, filename, NULL,
140 g, start, ps1, ps2, err_ret, 0);
Tim Petersfe2127d2001-07-16 05:37:24 +0000141}
142
143node *
Christian Heimes4d6ec852008-03-26 22:34:47 +0000144PyParser_ParseFileFlags(FILE *fp, const char *filename, const char *enc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145 grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300146 const char *ps1, const char *ps2,
147 perrdetail *err_ret, int flags)
Tim Petersfe2127d2001-07-16 05:37:24 +0000148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 int iflags = flags;
150 return PyParser_ParseFileFlagsEx(fp, filename, enc, g, start, ps1,
151 ps2, err_ret, &iflags);
Christian Heimes4d6ec852008-03-26 22:34:47 +0000152}
153
154node *
Victor Stinner14e461d2013-08-26 22:28:21 +0200155PyParser_ParseFileObject(FILE *fp, PyObject *filename,
156 const char *enc, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300157 const char *ps1, const char *ps2,
158 perrdetail *err_ret, int *flags)
Christian Heimes4d6ec852008-03-26 22:34:47 +0000159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 struct tok_state *tok;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000161
Victor Stinner7f2fee32011-04-05 00:39:01 +0200162 if (initerr(err_ret, filename) < 0)
163 return NULL;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000164
Serhiy Storchakac6792272013-10-19 21:03:34 +0300165 if ((tok = PyTokenizer_FromFile(fp, enc, ps1, ps2)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000166 err_ret->error = E_NOMEM;
167 return NULL;
168 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800169 if (*flags & PyPARSE_TYPE_COMMENTS) {
170 tok->type_comments = 1;
171 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200172#ifndef PGEN
173 Py_INCREF(err_ret->filename);
174 tok->filename = err_ret->filename;
175#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 return parsetok(tok, g, start, err_ret, flags);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000177}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178
Victor Stinner14e461d2013-08-26 22:28:21 +0200179node *
180PyParser_ParseFileFlagsEx(FILE *fp, const char *filename,
181 const char *enc, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300182 const char *ps1, const char *ps2,
183 perrdetail *err_ret, int *flags)
Victor Stinner14e461d2013-08-26 22:28:21 +0200184{
185 node *n;
186 PyObject *fileobj = NULL;
187#ifndef PGEN
188 if (filename != NULL) {
189 fileobj = PyUnicode_DecodeFSDefault(filename);
190 if (fileobj == NULL) {
191 err_ret->error = E_ERROR;
192 return NULL;
193 }
194 }
195#endif
196 n = PyParser_ParseFileObject(fp, fileobj, enc, g,
197 start, ps1, ps2, err_ret, flags);
198#ifndef PGEN
199 Py_XDECREF(fileobj);
200#endif
201 return n;
202}
203
Neal Norwitze4993c72006-03-16 06:01:25 +0000204#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Brett Cannone3944a52009-04-01 05:08:41 +0000205#if 0
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200206static const char with_msg[] =
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000207"%s:%d: Warning: 'with' will become a reserved keyword in Python 2.6\n";
208
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200209static const char as_msg[] =
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000210"%s:%d: Warning: 'as' will become a reserved keyword in Python 2.6\n";
211
212static void
213warn(const char *msg, const char *filename, int lineno)
214{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 if (filename == NULL)
216 filename = "<string>";
217 PySys_WriteStderr(msg, filename, lineno);
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000218}
Neal Norwitzfc85c922006-03-17 05:44:46 +0000219#endif
Brett Cannone3944a52009-04-01 05:08:41 +0000220#endif
Guido van Rossumda62ecc2001-07-17 16:53:11 +0000221
Thomas Wouters89f507f2006-12-13 04:49:30 +0000222/* Parse input coming from the given tokenizer structure.
223 Return error code. */
224
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000225static node *
Tim Petersfe2127d2001-07-16 05:37:24 +0000226parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 int *flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 parser_state *ps;
230 node *n;
Brett Cannonb94767f2011-02-22 20:15:44 +0000231 int started = 0;
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000232 int col_offset, end_col_offset;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800233 growable_int_array type_ignores;
234
235 if (!growable_int_array_init(&type_ignores, 10)) {
236 err_ret->error = E_NOMEM;
237 PyTokenizer_Free(tok);
238 return NULL;
239 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 if ((ps = PyParser_New(g, start)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 err_ret->error = E_NOMEM;
243 PyTokenizer_Free(tok);
244 return NULL;
245 }
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000246#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 if (*flags & PyPARSE_BARRY_AS_BDFL)
248 ps->p_flags |= CO_FUTURE_BARRY_AS_BDFL;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800249 if (*flags & PyPARSE_TYPE_COMMENTS)
250 ps->p_flags |= PyCF_TYPE_COMMENTS;
Neil Schemenauerc24ea082002-03-22 23:53:36 +0000251#endif
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000252
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 for (;;) {
254 char *a, *b;
255 int type;
256 size_t len;
257 char *str;
Ammar Askar025eb982018-09-24 17:12:49 -0400258 col_offset = -1;
Anthony Sottile995d9b92019-01-12 20:05:13 -0800259 int lineno;
260 const char *line_start;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 type = PyTokenizer_Get(tok, &a, &b);
263 if (type == ERRORTOKEN) {
264 err_ret->error = tok->done;
265 break;
266 }
267 if (type == ENDMARKER && started) {
268 type = NEWLINE; /* Add an extra newline */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 started = 0;
270 /* Add the right number of dedent tokens,
271 except if a certain flag is given --
272 codeop.py uses this. */
273 if (tok->indent &&
274 !(*flags & PyPARSE_DONT_IMPLY_DEDENT))
275 {
276 tok->pendin = -tok->indent;
277 tok->indent = 0;
278 }
279 }
280 else
281 started = 1;
Zackery Spytz7c4ab2a2018-08-15 00:27:26 -0600282 len = (a != NULL && b != NULL) ? b - a : 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 str = (char *) PyObject_MALLOC(len + 1);
284 if (str == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 err_ret->error = E_NOMEM;
286 break;
287 }
288 if (len > 0)
289 strncpy(str, a, len);
290 str[len] = '\0';
Guido van Rossumda62ecc2001-07-17 16:53:11 +0000291
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000292#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 if (type == NOTEQUAL) {
294 if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
295 strcmp(str, "!=")) {
Antoine Pitrou9ec25932011-11-13 01:01:23 +0100296 PyObject_FREE(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 err_ret->error = E_SYNTAX;
298 break;
299 }
300 else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
301 strcmp(str, "<>")) {
Antoine Pitrou9ec25932011-11-13 01:01:23 +0100302 PyObject_FREE(str);
Serhiy Storchakaaba24ff2018-07-23 23:41:11 +0300303 err_ret->expected = NOTEQUAL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 err_ret->error = E_SYNTAX;
305 break;
306 }
307 }
Neil Schemenauerc24ea082002-03-22 23:53:36 +0000308#endif
Anthony Sottile995d9b92019-01-12 20:05:13 -0800309
310 /* Nodes of type STRING, especially multi line strings
311 must be handled differently in order to get both
312 the starting line number and the column offset right.
313 (cf. issue 16806) */
314 lineno = type == STRING ? tok->first_lineno : tok->lineno;
315 line_start = type == STRING ? tok->multi_line_start : tok->line_start;
316 if (a != NULL && a >= line_start) {
317 col_offset = Py_SAFE_DOWNCAST(a - line_start,
Benjamin Petersonca470632016-09-06 13:47:26 -0700318 intptr_t, int);
Zackery Spytz3e26e422018-08-20 21:11:40 -0600319 }
320 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321 col_offset = -1;
Zackery Spytz3e26e422018-08-20 21:11:40 -0600322 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000323
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000324 if (b != NULL && b >= tok->line_start) {
325 end_col_offset = Py_SAFE_DOWNCAST(b - tok->line_start,
326 intptr_t, int);
327 }
328 else {
329 end_col_offset = -1;
330 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800331
332 if (type == TYPE_IGNORE) {
333 if (!growable_int_array_add(&type_ignores, tok->lineno)) {
334 err_ret->error = E_NOMEM;
335 break;
336 }
337 continue;
338 }
339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 if ((err_ret->error =
341 PyParser_AddToken(ps, (int)type, str,
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000342 lineno, col_offset, tok->lineno, end_col_offset,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 &(err_ret->expected))) != E_OK) {
344 if (err_ret->error != E_DONE) {
345 PyObject_FREE(str);
346 err_ret->token = type;
347 }
348 break;
349 }
350 }
351
352 if (err_ret->error == E_DONE) {
353 n = ps->p_tree;
354 ps->p_tree = NULL;
Meador Ingefa21bf02012-01-19 01:08:41 -0600355
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800356 if (n->n_type == file_input) {
357 /* Put type_ignore nodes in the ENDMARKER of file_input. */
358 int num;
359 node *ch;
360 size_t i;
361
362 num = NCH(n);
363 ch = CHILD(n, num - 1);
364 REQ(ch, ENDMARKER);
365
366 for (i = 0; i < type_ignores.num_items; i++) {
367 PyNode_AddChild(ch, TYPE_IGNORE, NULL,
368 type_ignores.items[i], 0,
369 type_ignores.items[i], 0);
370 }
371 }
372 growable_int_array_deallocate(&type_ignores);
373
Benjamin Peterson79c1f962012-01-19 08:48:11 -0500374#ifndef PGEN
Meador Ingefa21bf02012-01-19 01:08:41 -0600375 /* Check that the source for a single input statement really
376 is a single statement by looking at what is left in the
377 buffer after parsing. Trailing whitespace and comments
378 are OK. */
379 if (start == single_input) {
380 char *cur = tok->cur;
381 char c = *tok->cur;
382
Benjamin Petersoncff92372012-01-19 17:46:13 -0500383 for (;;) {
384 while (c == ' ' || c == '\t' || c == '\n' || c == '\014')
385 c = *++cur;
Meador Ingefa21bf02012-01-19 01:08:41 -0600386
Benjamin Petersoncff92372012-01-19 17:46:13 -0500387 if (!c)
388 break;
389
390 if (c != '#') {
391 err_ret->error = E_BADSINGLE;
392 PyNode_Free(n);
393 n = NULL;
394 break;
395 }
396
397 /* Suck up comment. */
398 while (c && c != '\n')
399 c = *++cur;
Meador Ingefa21bf02012-01-19 01:08:41 -0600400 }
401 }
Benjamin Peterson79c1f962012-01-19 08:48:11 -0500402#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 }
404 else
405 n = NULL;
Christian Heimesb1b3efc2008-03-26 23:24:27 +0000406
Christian Heimes4d6ec852008-03-26 22:34:47 +0000407#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 *flags = ps->p_flags;
Christian Heimes4d6ec852008-03-26 22:34:47 +0000409#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 PyParser_Delete(ps);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 if (n == NULL) {
Benjamin Peterson758888d2011-05-30 11:12:38 -0500413 if (tok->done == E_EOF)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 err_ret->error = E_EOF;
415 err_ret->lineno = tok->lineno;
416 if (tok->buf != NULL) {
417 size_t len;
418 assert(tok->cur - tok->buf < INT_MAX);
Ammar Askar025eb982018-09-24 17:12:49 -0400419 /* if we've managed to parse a token, point the offset to its start,
420 * else use the current reading position of the tokenizer
421 */
422 err_ret->offset = col_offset != -1 ? col_offset + 1 : ((int)(tok->cur - tok->buf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 len = tok->inp - tok->buf;
424 err_ret->text = (char *) PyObject_MALLOC(len + 1);
425 if (err_ret->text != NULL) {
426 if (len > 0)
427 strncpy(err_ret->text, tok->buf, len);
428 err_ret->text[len] = '\0';
429 }
430 }
431 } else if (tok->encoding != NULL) {
432 /* 'nodes->n_str' uses PyObject_*, while 'tok->encoding' was
433 * allocated using PyMem_
434 */
435 node* r = PyNode_New(encoding_decl);
436 if (r)
437 r->n_str = PyObject_MALLOC(strlen(tok->encoding)+1);
438 if (!r || !r->n_str) {
439 err_ret->error = E_NOMEM;
440 if (r)
441 PyObject_FREE(r);
442 n = NULL;
443 goto done;
444 }
445 strcpy(r->n_str, tok->encoding);
446 PyMem_FREE(tok->encoding);
447 tok->encoding = NULL;
448 r->n_nchildren = 1;
449 r->n_child = n;
450 n = r;
451 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000452
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000453done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 PyTokenizer_Free(tok);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000455
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000456 if (n != NULL) {
457 _PyNode_FinalizeEndPos(n);
458 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 return n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000460}
Guido van Rossum0c156a52001-10-20 14:27:56 +0000461
Victor Stinner7f2fee32011-04-05 00:39:01 +0200462static int
Victor Stinner14e461d2013-08-26 22:28:21 +0200463initerr(perrdetail *err_ret, PyObject *filename)
Guido van Rossum0c156a52001-10-20 14:27:56 +0000464{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 err_ret->error = E_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 err_ret->lineno = 0;
467 err_ret->offset = 0;
468 err_ret->text = NULL;
469 err_ret->token = -1;
470 err_ret->expected = -1;
Victor Stinner7f2fee32011-04-05 00:39:01 +0200471#ifndef PGEN
Victor Stinner14e461d2013-08-26 22:28:21 +0200472 if (filename) {
473 Py_INCREF(filename);
474 err_ret->filename = filename;
475 }
476 else {
Victor Stinner7f2fee32011-04-05 00:39:01 +0200477 err_ret->filename = PyUnicode_FromString("<string>");
Victor Stinner14e461d2013-08-26 22:28:21 +0200478 if (err_ret->filename == NULL) {
479 err_ret->error = E_ERROR;
480 return -1;
481 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200482 }
483#endif
484 return 0;
Guido van Rossum0c156a52001-10-20 14:27:56 +0000485}