blob: 2bb733d0dcd66bc66eab1569c1335ec3511c4a35 [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) {
40 arr->size *= 2;
41 arr->items = realloc(arr->items, arr->size * sizeof(*arr->items));
42 if (!arr->items) {
43 return 0;
44 }
45 }
46
Michael J. Sullivan933e1502019-05-22 07:54:20 -070047 arr->items[arr->num_items].lineno = lineno;
48 arr->items[arr->num_items].comment = comment;
Guido van Rossumdcfcd142019-01-31 03:40:27 -080049 arr->num_items++;
50 return 1;
51}
52
53static void
Michael J. Sullivan933e1502019-05-22 07:54:20 -070054growable_comment_array_deallocate(growable_comment_array *arr) {
55 for (unsigned i = 0; i < arr->num_items; i++) {
56 PyObject_FREE(arr->items[i].comment);
57 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -080058 free(arr->items);
59}
60
Guido van Rossum3f5da241990-12-20 15:06:42 +000061/* Parse input coming from a string. Return error code, print some errors. */
Guido van Rossumbd0389d1994-08-29 12:25:45 +000062node *
Martin v. Löwis95292d62002-12-11 14:04:59 +000063PyParser_ParseString(const char *s, grammar *g, int start, perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000064{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 return PyParser_ParseStringFlagsFilename(s, NULL, g, start, err_ret, 0);
Tim Petersfe2127d2001-07-16 05:37:24 +000066}
67
68node *
Martin v. Löwis95292d62002-12-11 14:04:59 +000069PyParser_ParseStringFlags(const char *s, grammar *g, int start,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000070 perrdetail *err_ret, int flags)
Tim Petersfe2127d2001-07-16 05:37:24 +000071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000072 return PyParser_ParseStringFlagsFilename(s, NULL,
73 g, start, err_ret, flags);
Thomas Heller6b17abf2002-07-09 09:23:27 +000074}
75
76node *
Martin v. Löwis95292d62002-12-11 14:04:59 +000077PyParser_ParseStringFlagsFilename(const char *s, const char *filename,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078 grammar *g, int start,
79 perrdetail *err_ret, int flags)
Thomas Heller6b17abf2002-07-09 09:23:27 +000080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081 int iflags = flags;
82 return PyParser_ParseStringFlagsFilenameEx(s, filename, g, start,
83 err_ret, &iflags);
Christian Heimes4d6ec852008-03-26 22:34:47 +000084}
85
86node *
Victor Stinner14e461d2013-08-26 22:28:21 +020087PyParser_ParseStringObject(const char *s, PyObject *filename,
88 grammar *g, int start,
89 perrdetail *err_ret, int *flags)
Christian Heimes4d6ec852008-03-26 22:34:47 +000090{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 struct tok_state *tok;
92 int exec_input = start == file_input;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000093
Victor Stinner7f2fee32011-04-05 00:39:01 +020094 if (initerr(err_ret, filename) < 0)
95 return NULL;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000096
Steve Dowerb82e17e2019-05-23 08:45:22 -070097 if (PySys_Audit("compile", "yO", s, err_ret->filename) < 0) {
98 err_ret->error = E_ERROR;
99 return NULL;
100 }
101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000102 if (*flags & PyPARSE_IGNORE_COOKIE)
103 tok = PyTokenizer_FromUTF8(s, exec_input);
104 else
105 tok = PyTokenizer_FromString(s, exec_input);
106 if (tok == NULL) {
107 err_ret->error = PyErr_Occurred() ? E_DECODE : E_NOMEM;
108 return NULL;
109 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800110 if (*flags & PyPARSE_TYPE_COMMENTS) {
111 tok->type_comments = 1;
112 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000113
Victor Stinner7f2fee32011-04-05 00:39:01 +0200114 Py_INCREF(err_ret->filename);
115 tok->filename = err_ret->filename;
Guido van Rossum495da292019-03-07 12:38:08 -0800116 if (*flags & PyPARSE_ASYNC_HACKS)
117 tok->async_hacks = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 return parsetok(tok, g, start, err_ret, flags);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000119}
120
Victor Stinner14e461d2013-08-26 22:28:21 +0200121node *
122PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename_str,
123 grammar *g, int start,
124 perrdetail *err_ret, int *flags)
125{
126 node *n;
127 PyObject *filename = NULL;
Victor Stinner14e461d2013-08-26 22:28:21 +0200128 if (filename_str != NULL) {
129 filename = PyUnicode_DecodeFSDefault(filename_str);
130 if (filename == NULL) {
131 err_ret->error = E_ERROR;
132 return NULL;
133 }
134 }
Victor Stinner14e461d2013-08-26 22:28:21 +0200135 n = PyParser_ParseStringObject(s, filename, g, start, err_ret, flags);
Victor Stinner14e461d2013-08-26 22:28:21 +0200136 Py_XDECREF(filename);
Victor Stinner14e461d2013-08-26 22:28:21 +0200137 return n;
138}
139
Guido van Rossum3f5da241990-12-20 15:06:42 +0000140/* Parse input coming from a file. Return error code, print some errors. */
141
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000142node *
Martin v. Löwis95292d62002-12-11 14:04:59 +0000143PyParser_ParseFile(FILE *fp, const char *filename, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300144 const char *ps1, const char *ps2,
145 perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 return PyParser_ParseFileFlags(fp, filename, NULL,
148 g, start, ps1, ps2, err_ret, 0);
Tim Petersfe2127d2001-07-16 05:37:24 +0000149}
150
151node *
Christian Heimes4d6ec852008-03-26 22:34:47 +0000152PyParser_ParseFileFlags(FILE *fp, const char *filename, const char *enc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300154 const char *ps1, const char *ps2,
155 perrdetail *err_ret, int flags)
Tim Petersfe2127d2001-07-16 05:37:24 +0000156{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 int iflags = flags;
158 return PyParser_ParseFileFlagsEx(fp, filename, enc, g, start, ps1,
159 ps2, err_ret, &iflags);
Christian Heimes4d6ec852008-03-26 22:34:47 +0000160}
161
162node *
Victor Stinner14e461d2013-08-26 22:28:21 +0200163PyParser_ParseFileObject(FILE *fp, PyObject *filename,
164 const char *enc, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300165 const char *ps1, const char *ps2,
166 perrdetail *err_ret, int *flags)
Christian Heimes4d6ec852008-03-26 22:34:47 +0000167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 struct tok_state *tok;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000169
Victor Stinner7f2fee32011-04-05 00:39:01 +0200170 if (initerr(err_ret, filename) < 0)
171 return NULL;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000172
Steve Dowerb82e17e2019-05-23 08:45:22 -0700173 if (PySys_Audit("compile", "OO", Py_None, err_ret->filename) < 0) {
174 return NULL;
175 }
176
Serhiy Storchakac6792272013-10-19 21:03:34 +0300177 if ((tok = PyTokenizer_FromFile(fp, enc, ps1, ps2)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000178 err_ret->error = E_NOMEM;
179 return NULL;
180 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800181 if (*flags & PyPARSE_TYPE_COMMENTS) {
182 tok->type_comments = 1;
183 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200184 Py_INCREF(err_ret->filename);
185 tok->filename = err_ret->filename;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 return parsetok(tok, g, start, err_ret, flags);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000187}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188
Victor Stinner14e461d2013-08-26 22:28:21 +0200189node *
190PyParser_ParseFileFlagsEx(FILE *fp, const char *filename,
191 const char *enc, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300192 const char *ps1, const char *ps2,
193 perrdetail *err_ret, int *flags)
Victor Stinner14e461d2013-08-26 22:28:21 +0200194{
195 node *n;
196 PyObject *fileobj = NULL;
Victor Stinner14e461d2013-08-26 22:28:21 +0200197 if (filename != NULL) {
198 fileobj = PyUnicode_DecodeFSDefault(filename);
199 if (fileobj == NULL) {
200 err_ret->error = E_ERROR;
201 return NULL;
202 }
203 }
Victor Stinner14e461d2013-08-26 22:28:21 +0200204 n = PyParser_ParseFileObject(fp, fileobj, enc, g,
205 start, ps1, ps2, err_ret, flags);
Victor Stinner14e461d2013-08-26 22:28:21 +0200206 Py_XDECREF(fileobj);
Victor Stinner14e461d2013-08-26 22:28:21 +0200207 return n;
208}
209
Neal Norwitze4993c72006-03-16 06:01:25 +0000210#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Brett Cannone3944a52009-04-01 05:08:41 +0000211#if 0
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200212static const char with_msg[] =
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000213"%s:%d: Warning: 'with' will become a reserved keyword in Python 2.6\n";
214
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200215static const char as_msg[] =
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000216"%s:%d: Warning: 'as' will become a reserved keyword in Python 2.6\n";
217
218static void
219warn(const char *msg, const char *filename, int lineno)
220{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000221 if (filename == NULL)
222 filename = "<string>";
223 PySys_WriteStderr(msg, filename, lineno);
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000224}
Neal Norwitzfc85c922006-03-17 05:44:46 +0000225#endif
Brett Cannone3944a52009-04-01 05:08:41 +0000226#endif
Guido van Rossumda62ecc2001-07-17 16:53:11 +0000227
Thomas Wouters89f507f2006-12-13 04:49:30 +0000228/* Parse input coming from the given tokenizer structure.
229 Return error code. */
230
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000231static node *
Tim Petersfe2127d2001-07-16 05:37:24 +0000232parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000233 int *flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 parser_state *ps;
236 node *n;
Brett Cannonb94767f2011-02-22 20:15:44 +0000237 int started = 0;
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000238 int col_offset, end_col_offset;
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700239 growable_comment_array type_ignores;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800240
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700241 if (!growable_comment_array_init(&type_ignores, 10)) {
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800242 err_ret->error = E_NOMEM;
243 PyTokenizer_Free(tok);
244 return NULL;
245 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 if ((ps = PyParser_New(g, start)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 err_ret->error = E_NOMEM;
Miss Islington (bot)9671b6b2020-01-13 02:54:24 -0800249 growable_comment_array_deallocate(&type_ignores);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 PyTokenizer_Free(tok);
251 return NULL;
252 }
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000253#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 if (*flags & PyPARSE_BARRY_AS_BDFL)
255 ps->p_flags |= CO_FUTURE_BARRY_AS_BDFL;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800256 if (*flags & PyPARSE_TYPE_COMMENTS)
257 ps->p_flags |= PyCF_TYPE_COMMENTS;
Neil Schemenauerc24ea082002-03-22 23:53:36 +0000258#endif
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 for (;;) {
261 char *a, *b;
262 int type;
263 size_t len;
264 char *str;
Ammar Askar025eb982018-09-24 17:12:49 -0400265 col_offset = -1;
Anthony Sottile995d9b92019-01-12 20:05:13 -0800266 int lineno;
267 const char *line_start;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 type = PyTokenizer_Get(tok, &a, &b);
270 if (type == ERRORTOKEN) {
271 err_ret->error = tok->done;
272 break;
273 }
274 if (type == ENDMARKER && started) {
275 type = NEWLINE; /* Add an extra newline */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276 started = 0;
277 /* Add the right number of dedent tokens,
278 except if a certain flag is given --
279 codeop.py uses this. */
280 if (tok->indent &&
281 !(*flags & PyPARSE_DONT_IMPLY_DEDENT))
282 {
283 tok->pendin = -tok->indent;
284 tok->indent = 0;
285 }
286 }
287 else
288 started = 1;
Zackery Spytz7c4ab2a2018-08-15 00:27:26 -0600289 len = (a != NULL && b != NULL) ? b - a : 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 str = (char *) PyObject_MALLOC(len + 1);
291 if (str == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000292 err_ret->error = E_NOMEM;
293 break;
294 }
295 if (len > 0)
296 strncpy(str, a, len);
297 str[len] = '\0';
Guido van Rossumda62ecc2001-07-17 16:53:11 +0000298
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000299#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 if (type == NOTEQUAL) {
301 if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
302 strcmp(str, "!=")) {
Antoine Pitrou9ec25932011-11-13 01:01:23 +0100303 PyObject_FREE(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 err_ret->error = E_SYNTAX;
305 break;
306 }
307 else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
308 strcmp(str, "<>")) {
Antoine Pitrou9ec25932011-11-13 01:01:23 +0100309 PyObject_FREE(str);
Serhiy Storchakaaba24ff2018-07-23 23:41:11 +0300310 err_ret->expected = NOTEQUAL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 err_ret->error = E_SYNTAX;
312 break;
313 }
314 }
Neil Schemenauerc24ea082002-03-22 23:53:36 +0000315#endif
Anthony Sottile995d9b92019-01-12 20:05:13 -0800316
317 /* Nodes of type STRING, especially multi line strings
318 must be handled differently in order to get both
319 the starting line number and the column offset right.
320 (cf. issue 16806) */
321 lineno = type == STRING ? tok->first_lineno : tok->lineno;
322 line_start = type == STRING ? tok->multi_line_start : tok->line_start;
323 if (a != NULL && a >= line_start) {
324 col_offset = Py_SAFE_DOWNCAST(a - line_start,
Benjamin Petersonca470632016-09-06 13:47:26 -0700325 intptr_t, int);
Zackery Spytz3e26e422018-08-20 21:11:40 -0600326 }
327 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 col_offset = -1;
Zackery Spytz3e26e422018-08-20 21:11:40 -0600329 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000330
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000331 if (b != NULL && b >= tok->line_start) {
332 end_col_offset = Py_SAFE_DOWNCAST(b - tok->line_start,
333 intptr_t, int);
334 }
335 else {
336 end_col_offset = -1;
337 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800338
339 if (type == TYPE_IGNORE) {
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700340 if (!growable_comment_array_add(&type_ignores, tok->lineno, str)) {
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800341 err_ret->error = E_NOMEM;
342 break;
343 }
344 continue;
345 }
346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 if ((err_ret->error =
348 PyParser_AddToken(ps, (int)type, str,
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000349 lineno, col_offset, tok->lineno, end_col_offset,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 &(err_ret->expected))) != E_OK) {
351 if (err_ret->error != E_DONE) {
352 PyObject_FREE(str);
353 err_ret->token = type;
354 }
355 break;
356 }
357 }
358
359 if (err_ret->error == E_DONE) {
360 n = ps->p_tree;
361 ps->p_tree = NULL;
Meador Ingefa21bf02012-01-19 01:08:41 -0600362
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800363 if (n->n_type == file_input) {
364 /* Put type_ignore nodes in the ENDMARKER of file_input. */
365 int num;
366 node *ch;
367 size_t i;
368
369 num = NCH(n);
370 ch = CHILD(n, num - 1);
371 REQ(ch, ENDMARKER);
372
373 for (i = 0; i < type_ignores.num_items; i++) {
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700374 int res = PyNode_AddChild(ch, TYPE_IGNORE, type_ignores.items[i].comment,
375 type_ignores.items[i].lineno, 0,
376 type_ignores.items[i].lineno, 0);
377 if (res != 0) {
378 err_ret->error = res;
379 PyNode_Free(n);
380 n = NULL;
381 break;
382 }
383 type_ignores.items[i].comment = NULL;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800384 }
385 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800386
Meador Ingefa21bf02012-01-19 01:08:41 -0600387 /* Check that the source for a single input statement really
388 is a single statement by looking at what is left in the
389 buffer after parsing. Trailing whitespace and comments
390 are OK. */
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700391 if (err_ret->error == E_DONE && start == single_input) {
Meador Ingefa21bf02012-01-19 01:08:41 -0600392 char *cur = tok->cur;
393 char c = *tok->cur;
394
Benjamin Petersoncff92372012-01-19 17:46:13 -0500395 for (;;) {
396 while (c == ' ' || c == '\t' || c == '\n' || c == '\014')
397 c = *++cur;
Meador Ingefa21bf02012-01-19 01:08:41 -0600398
Benjamin Petersoncff92372012-01-19 17:46:13 -0500399 if (!c)
400 break;
401
402 if (c != '#') {
403 err_ret->error = E_BADSINGLE;
404 PyNode_Free(n);
405 n = NULL;
406 break;
407 }
408
409 /* Suck up comment. */
410 while (c && c != '\n')
411 c = *++cur;
Meador Ingefa21bf02012-01-19 01:08:41 -0600412 }
413 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 }
415 else
416 n = NULL;
Christian Heimesb1b3efc2008-03-26 23:24:27 +0000417
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700418 growable_comment_array_deallocate(&type_ignores);
Pablo Galindob9d2e972019-02-13 00:45:53 +0000419
Christian Heimes4d6ec852008-03-26 22:34:47 +0000420#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 *flags = ps->p_flags;
Christian Heimes4d6ec852008-03-26 22:34:47 +0000422#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 PyParser_Delete(ps);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000425 if (n == NULL) {
Benjamin Peterson758888d2011-05-30 11:12:38 -0500426 if (tok->done == E_EOF)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 err_ret->error = E_EOF;
428 err_ret->lineno = tok->lineno;
429 if (tok->buf != NULL) {
430 size_t len;
431 assert(tok->cur - tok->buf < INT_MAX);
Ammar Askar025eb982018-09-24 17:12:49 -0400432 /* if we've managed to parse a token, point the offset to its start,
433 * else use the current reading position of the tokenizer
434 */
435 err_ret->offset = col_offset != -1 ? col_offset + 1 : ((int)(tok->cur - tok->buf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 len = tok->inp - tok->buf;
437 err_ret->text = (char *) PyObject_MALLOC(len + 1);
438 if (err_ret->text != NULL) {
439 if (len > 0)
440 strncpy(err_ret->text, tok->buf, len);
441 err_ret->text[len] = '\0';
442 }
443 }
444 } else if (tok->encoding != NULL) {
445 /* 'nodes->n_str' uses PyObject_*, while 'tok->encoding' was
446 * allocated using PyMem_
447 */
448 node* r = PyNode_New(encoding_decl);
449 if (r)
450 r->n_str = PyObject_MALLOC(strlen(tok->encoding)+1);
451 if (!r || !r->n_str) {
452 err_ret->error = E_NOMEM;
453 if (r)
454 PyObject_FREE(r);
455 n = NULL;
456 goto done;
457 }
458 strcpy(r->n_str, tok->encoding);
459 PyMem_FREE(tok->encoding);
460 tok->encoding = NULL;
461 r->n_nchildren = 1;
462 r->n_child = n;
463 n = r;
464 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000465
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000466done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 PyTokenizer_Free(tok);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000468
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000469 if (n != NULL) {
470 _PyNode_FinalizeEndPos(n);
471 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 return n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000473}
Guido van Rossum0c156a52001-10-20 14:27:56 +0000474
Victor Stinner7f2fee32011-04-05 00:39:01 +0200475static int
Victor Stinner14e461d2013-08-26 22:28:21 +0200476initerr(perrdetail *err_ret, PyObject *filename)
Guido van Rossum0c156a52001-10-20 14:27:56 +0000477{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 err_ret->error = E_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 err_ret->lineno = 0;
480 err_ret->offset = 0;
481 err_ret->text = NULL;
482 err_ret->token = -1;
483 err_ret->expected = -1;
Victor Stinner14e461d2013-08-26 22:28:21 +0200484 if (filename) {
485 Py_INCREF(filename);
486 err_ret->filename = filename;
487 }
488 else {
Victor Stinner7f2fee32011-04-05 00:39:01 +0200489 err_ret->filename = PyUnicode_FromString("<string>");
Victor Stinner14e461d2013-08-26 22:28:21 +0200490 if (err_ret->filename == NULL) {
491 err_ret->error = E_ERROR;
492 return -1;
493 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200494 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200495 return 0;
Guido van Rossum0c156a52001-10-20 14:27:56 +0000496}