blob: a5d78974b871b3e975d140ba43e09895336c9d1b [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;
249 PyTokenizer_Free(tok);
250 return NULL;
251 }
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000252#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 if (*flags & PyPARSE_BARRY_AS_BDFL)
254 ps->p_flags |= CO_FUTURE_BARRY_AS_BDFL;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800255 if (*flags & PyPARSE_TYPE_COMMENTS)
256 ps->p_flags |= PyCF_TYPE_COMMENTS;
Neil Schemenauerc24ea082002-03-22 23:53:36 +0000257#endif
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 for (;;) {
260 char *a, *b;
261 int type;
262 size_t len;
263 char *str;
Ammar Askar025eb982018-09-24 17:12:49 -0400264 col_offset = -1;
Anthony Sottile995d9b92019-01-12 20:05:13 -0800265 int lineno;
266 const char *line_start;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 type = PyTokenizer_Get(tok, &a, &b);
269 if (type == ERRORTOKEN) {
270 err_ret->error = tok->done;
271 break;
272 }
273 if (type == ENDMARKER && started) {
274 type = NEWLINE; /* Add an extra newline */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 started = 0;
276 /* Add the right number of dedent tokens,
277 except if a certain flag is given --
278 codeop.py uses this. */
279 if (tok->indent &&
280 !(*flags & PyPARSE_DONT_IMPLY_DEDENT))
281 {
282 tok->pendin = -tok->indent;
283 tok->indent = 0;
284 }
285 }
286 else
287 started = 1;
Zackery Spytz7c4ab2a2018-08-15 00:27:26 -0600288 len = (a != NULL && b != NULL) ? b - a : 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 str = (char *) PyObject_MALLOC(len + 1);
290 if (str == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 err_ret->error = E_NOMEM;
292 break;
293 }
294 if (len > 0)
295 strncpy(str, a, len);
296 str[len] = '\0';
Guido van Rossumda62ecc2001-07-17 16:53:11 +0000297
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000298#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000299 if (type == NOTEQUAL) {
300 if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
301 strcmp(str, "!=")) {
Antoine Pitrou9ec25932011-11-13 01:01:23 +0100302 PyObject_FREE(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 err_ret->error = E_SYNTAX;
304 break;
305 }
306 else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
307 strcmp(str, "<>")) {
Antoine Pitrou9ec25932011-11-13 01:01:23 +0100308 PyObject_FREE(str);
Serhiy Storchakaaba24ff2018-07-23 23:41:11 +0300309 err_ret->expected = NOTEQUAL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 err_ret->error = E_SYNTAX;
311 break;
312 }
313 }
Neil Schemenauerc24ea082002-03-22 23:53:36 +0000314#endif
Anthony Sottile995d9b92019-01-12 20:05:13 -0800315
316 /* Nodes of type STRING, especially multi line strings
317 must be handled differently in order to get both
318 the starting line number and the column offset right.
319 (cf. issue 16806) */
320 lineno = type == STRING ? tok->first_lineno : tok->lineno;
321 line_start = type == STRING ? tok->multi_line_start : tok->line_start;
322 if (a != NULL && a >= line_start) {
323 col_offset = Py_SAFE_DOWNCAST(a - line_start,
Benjamin Petersonca470632016-09-06 13:47:26 -0700324 intptr_t, int);
Zackery Spytz3e26e422018-08-20 21:11:40 -0600325 }
326 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 col_offset = -1;
Zackery Spytz3e26e422018-08-20 21:11:40 -0600328 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000329
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000330 if (b != NULL && b >= tok->line_start) {
331 end_col_offset = Py_SAFE_DOWNCAST(b - tok->line_start,
332 intptr_t, int);
333 }
334 else {
335 end_col_offset = -1;
336 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800337
338 if (type == TYPE_IGNORE) {
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700339 if (!growable_comment_array_add(&type_ignores, tok->lineno, str)) {
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800340 err_ret->error = E_NOMEM;
341 break;
342 }
343 continue;
344 }
345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000346 if ((err_ret->error =
347 PyParser_AddToken(ps, (int)type, str,
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000348 lineno, col_offset, tok->lineno, end_col_offset,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 &(err_ret->expected))) != E_OK) {
350 if (err_ret->error != E_DONE) {
351 PyObject_FREE(str);
352 err_ret->token = type;
353 }
354 break;
355 }
356 }
357
358 if (err_ret->error == E_DONE) {
359 n = ps->p_tree;
360 ps->p_tree = NULL;
Meador Ingefa21bf02012-01-19 01:08:41 -0600361
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800362 if (n->n_type == file_input) {
363 /* Put type_ignore nodes in the ENDMARKER of file_input. */
364 int num;
365 node *ch;
366 size_t i;
367
368 num = NCH(n);
369 ch = CHILD(n, num - 1);
370 REQ(ch, ENDMARKER);
371
372 for (i = 0; i < type_ignores.num_items; i++) {
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700373 int res = PyNode_AddChild(ch, TYPE_IGNORE, type_ignores.items[i].comment,
374 type_ignores.items[i].lineno, 0,
375 type_ignores.items[i].lineno, 0);
376 if (res != 0) {
377 err_ret->error = res;
378 PyNode_Free(n);
379 n = NULL;
380 break;
381 }
382 type_ignores.items[i].comment = NULL;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800383 }
384 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800385
Meador Ingefa21bf02012-01-19 01:08:41 -0600386 /* Check that the source for a single input statement really
387 is a single statement by looking at what is left in the
388 buffer after parsing. Trailing whitespace and comments
389 are OK. */
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700390 if (err_ret->error == E_DONE && start == single_input) {
Meador Ingefa21bf02012-01-19 01:08:41 -0600391 char *cur = tok->cur;
392 char c = *tok->cur;
393
Benjamin Petersoncff92372012-01-19 17:46:13 -0500394 for (;;) {
395 while (c == ' ' || c == '\t' || c == '\n' || c == '\014')
396 c = *++cur;
Meador Ingefa21bf02012-01-19 01:08:41 -0600397
Benjamin Petersoncff92372012-01-19 17:46:13 -0500398 if (!c)
399 break;
400
401 if (c != '#') {
402 err_ret->error = E_BADSINGLE;
403 PyNode_Free(n);
404 n = NULL;
405 break;
406 }
407
408 /* Suck up comment. */
409 while (c && c != '\n')
410 c = *++cur;
Meador Ingefa21bf02012-01-19 01:08:41 -0600411 }
412 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 }
414 else
415 n = NULL;
Christian Heimesb1b3efc2008-03-26 23:24:27 +0000416
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700417 growable_comment_array_deallocate(&type_ignores);
Pablo Galindob9d2e972019-02-13 00:45:53 +0000418
Christian Heimes4d6ec852008-03-26 22:34:47 +0000419#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 *flags = ps->p_flags;
Christian Heimes4d6ec852008-03-26 22:34:47 +0000421#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 PyParser_Delete(ps);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 if (n == NULL) {
Benjamin Peterson758888d2011-05-30 11:12:38 -0500425 if (tok->done == E_EOF)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 err_ret->error = E_EOF;
427 err_ret->lineno = tok->lineno;
428 if (tok->buf != NULL) {
429 size_t len;
430 assert(tok->cur - tok->buf < INT_MAX);
Ammar Askar025eb982018-09-24 17:12:49 -0400431 /* if we've managed to parse a token, point the offset to its start,
432 * else use the current reading position of the tokenizer
433 */
434 err_ret->offset = col_offset != -1 ? col_offset + 1 : ((int)(tok->cur - tok->buf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 len = tok->inp - tok->buf;
436 err_ret->text = (char *) PyObject_MALLOC(len + 1);
437 if (err_ret->text != NULL) {
438 if (len > 0)
439 strncpy(err_ret->text, tok->buf, len);
440 err_ret->text[len] = '\0';
441 }
442 }
443 } else if (tok->encoding != NULL) {
444 /* 'nodes->n_str' uses PyObject_*, while 'tok->encoding' was
445 * allocated using PyMem_
446 */
447 node* r = PyNode_New(encoding_decl);
448 if (r)
449 r->n_str = PyObject_MALLOC(strlen(tok->encoding)+1);
450 if (!r || !r->n_str) {
451 err_ret->error = E_NOMEM;
452 if (r)
453 PyObject_FREE(r);
454 n = NULL;
455 goto done;
456 }
457 strcpy(r->n_str, tok->encoding);
458 PyMem_FREE(tok->encoding);
459 tok->encoding = NULL;
460 r->n_nchildren = 1;
461 r->n_child = n;
462 n = r;
463 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000464
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000465done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 PyTokenizer_Free(tok);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000467
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000468 if (n != NULL) {
469 _PyNode_FinalizeEndPos(n);
470 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 return n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000472}
Guido van Rossum0c156a52001-10-20 14:27:56 +0000473
Victor Stinner7f2fee32011-04-05 00:39:01 +0200474static int
Victor Stinner14e461d2013-08-26 22:28:21 +0200475initerr(perrdetail *err_ret, PyObject *filename)
Guido van Rossum0c156a52001-10-20 14:27:56 +0000476{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 err_ret->error = E_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 err_ret->lineno = 0;
479 err_ret->offset = 0;
480 err_ret->text = NULL;
481 err_ret->token = -1;
482 err_ret->expected = -1;
Victor Stinner14e461d2013-08-26 22:28:21 +0200483 if (filename) {
484 Py_INCREF(filename);
485 err_ret->filename = filename;
486 }
487 else {
Victor Stinner7f2fee32011-04-05 00:39:01 +0200488 err_ret->filename = PyUnicode_FromString("<string>");
Victor Stinner14e461d2013-08-26 22:28:21 +0200489 if (err_ret->filename == NULL) {
490 err_ret->error = E_ERROR;
491 return -1;
492 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200493 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200494 return 0;
Guido van Rossum0c156a52001-10-20 14:27:56 +0000495}