blob: 55fd7f7db3da812a0d10ebfa2d59b048077741e6 [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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097 if (*flags & PyPARSE_IGNORE_COOKIE)
98 tok = PyTokenizer_FromUTF8(s, exec_input);
99 else
100 tok = PyTokenizer_FromString(s, exec_input);
101 if (tok == NULL) {
102 err_ret->error = PyErr_Occurred() ? E_DECODE : E_NOMEM;
103 return NULL;
104 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800105 if (*flags & PyPARSE_TYPE_COMMENTS) {
106 tok->type_comments = 1;
107 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000108
Victor Stinner7f2fee32011-04-05 00:39:01 +0200109 Py_INCREF(err_ret->filename);
110 tok->filename = err_ret->filename;
Guido van Rossum495da292019-03-07 12:38:08 -0800111 if (*flags & PyPARSE_ASYNC_HACKS)
112 tok->async_hacks = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 return parsetok(tok, g, start, err_ret, flags);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000114}
115
Victor Stinner14e461d2013-08-26 22:28:21 +0200116node *
117PyParser_ParseStringFlagsFilenameEx(const char *s, const char *filename_str,
118 grammar *g, int start,
119 perrdetail *err_ret, int *flags)
120{
121 node *n;
122 PyObject *filename = NULL;
Victor Stinner14e461d2013-08-26 22:28:21 +0200123 if (filename_str != NULL) {
124 filename = PyUnicode_DecodeFSDefault(filename_str);
125 if (filename == NULL) {
126 err_ret->error = E_ERROR;
127 return NULL;
128 }
129 }
Victor Stinner14e461d2013-08-26 22:28:21 +0200130 n = PyParser_ParseStringObject(s, filename, g, start, err_ret, flags);
Victor Stinner14e461d2013-08-26 22:28:21 +0200131 Py_XDECREF(filename);
Victor Stinner14e461d2013-08-26 22:28:21 +0200132 return n;
133}
134
Guido van Rossum3f5da241990-12-20 15:06:42 +0000135/* Parse input coming from a file. Return error code, print some errors. */
136
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000137node *
Martin v. Löwis95292d62002-12-11 14:04:59 +0000138PyParser_ParseFile(FILE *fp, const char *filename, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300139 const char *ps1, const char *ps2,
140 perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000141{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000142 return PyParser_ParseFileFlags(fp, filename, NULL,
143 g, start, ps1, ps2, err_ret, 0);
Tim Petersfe2127d2001-07-16 05:37:24 +0000144}
145
146node *
Christian Heimes4d6ec852008-03-26 22:34:47 +0000147PyParser_ParseFileFlags(FILE *fp, const char *filename, const char *enc,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300149 const char *ps1, const char *ps2,
150 perrdetail *err_ret, int flags)
Tim Petersfe2127d2001-07-16 05:37:24 +0000151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 int iflags = flags;
153 return PyParser_ParseFileFlagsEx(fp, filename, enc, g, start, ps1,
154 ps2, err_ret, &iflags);
Christian Heimes4d6ec852008-03-26 22:34:47 +0000155}
156
157node *
Victor Stinner14e461d2013-08-26 22:28:21 +0200158PyParser_ParseFileObject(FILE *fp, PyObject *filename,
159 const char *enc, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300160 const char *ps1, const char *ps2,
161 perrdetail *err_ret, int *flags)
Christian Heimes4d6ec852008-03-26 22:34:47 +0000162{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 struct tok_state *tok;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000164
Victor Stinner7f2fee32011-04-05 00:39:01 +0200165 if (initerr(err_ret, filename) < 0)
166 return NULL;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000167
Serhiy Storchakac6792272013-10-19 21:03:34 +0300168 if ((tok = PyTokenizer_FromFile(fp, enc, ps1, ps2)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 err_ret->error = E_NOMEM;
170 return NULL;
171 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800172 if (*flags & PyPARSE_TYPE_COMMENTS) {
173 tok->type_comments = 1;
174 }
Victor Stinner7f2fee32011-04-05 00:39:01 +0200175 Py_INCREF(err_ret->filename);
176 tok->filename = err_ret->filename;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 return parsetok(tok, g, start, err_ret, flags);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000178}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000179
Victor Stinner14e461d2013-08-26 22:28:21 +0200180node *
181PyParser_ParseFileFlagsEx(FILE *fp, const char *filename,
182 const char *enc, grammar *g, int start,
Serhiy Storchakac6792272013-10-19 21:03:34 +0300183 const char *ps1, const char *ps2,
184 perrdetail *err_ret, int *flags)
Victor Stinner14e461d2013-08-26 22:28:21 +0200185{
186 node *n;
187 PyObject *fileobj = NULL;
Victor Stinner14e461d2013-08-26 22:28:21 +0200188 if (filename != NULL) {
189 fileobj = PyUnicode_DecodeFSDefault(filename);
190 if (fileobj == NULL) {
191 err_ret->error = E_ERROR;
192 return NULL;
193 }
194 }
Victor Stinner14e461d2013-08-26 22:28:21 +0200195 n = PyParser_ParseFileObject(fp, fileobj, enc, g,
196 start, ps1, ps2, err_ret, flags);
Victor Stinner14e461d2013-08-26 22:28:21 +0200197 Py_XDECREF(fileobj);
Victor Stinner14e461d2013-08-26 22:28:21 +0200198 return n;
199}
200
Neal Norwitze4993c72006-03-16 06:01:25 +0000201#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Brett Cannone3944a52009-04-01 05:08:41 +0000202#if 0
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200203static const char with_msg[] =
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000204"%s:%d: Warning: 'with' will become a reserved keyword in Python 2.6\n";
205
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200206static const char as_msg[] =
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000207"%s:%d: Warning: 'as' will become a reserved keyword in Python 2.6\n";
208
209static void
210warn(const char *msg, const char *filename, int lineno)
211{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 if (filename == NULL)
213 filename = "<string>";
214 PySys_WriteStderr(msg, filename, lineno);
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000215}
Neal Norwitzfc85c922006-03-17 05:44:46 +0000216#endif
Brett Cannone3944a52009-04-01 05:08:41 +0000217#endif
Guido van Rossumda62ecc2001-07-17 16:53:11 +0000218
Thomas Wouters89f507f2006-12-13 04:49:30 +0000219/* Parse input coming from the given tokenizer structure.
220 Return error code. */
221
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000222static node *
Tim Petersfe2127d2001-07-16 05:37:24 +0000223parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 int *flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 parser_state *ps;
227 node *n;
Brett Cannonb94767f2011-02-22 20:15:44 +0000228 int started = 0;
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000229 int col_offset, end_col_offset;
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700230 growable_comment_array type_ignores;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800231
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700232 if (!growable_comment_array_init(&type_ignores, 10)) {
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800233 err_ret->error = E_NOMEM;
234 PyTokenizer_Free(tok);
235 return NULL;
236 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 if ((ps = PyParser_New(g, start)) == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 err_ret->error = E_NOMEM;
240 PyTokenizer_Free(tok);
241 return NULL;
242 }
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000243#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 if (*flags & PyPARSE_BARRY_AS_BDFL)
245 ps->p_flags |= CO_FUTURE_BARRY_AS_BDFL;
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800246 if (*flags & PyPARSE_TYPE_COMMENTS)
247 ps->p_flags |= PyCF_TYPE_COMMENTS;
Neil Schemenauerc24ea082002-03-22 23:53:36 +0000248#endif
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000249
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 for (;;) {
251 char *a, *b;
252 int type;
253 size_t len;
254 char *str;
Ammar Askar025eb982018-09-24 17:12:49 -0400255 col_offset = -1;
Anthony Sottile995d9b92019-01-12 20:05:13 -0800256 int lineno;
257 const char *line_start;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 type = PyTokenizer_Get(tok, &a, &b);
260 if (type == ERRORTOKEN) {
261 err_ret->error = tok->done;
262 break;
263 }
264 if (type == ENDMARKER && started) {
265 type = NEWLINE; /* Add an extra newline */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 started = 0;
267 /* Add the right number of dedent tokens,
268 except if a certain flag is given --
269 codeop.py uses this. */
270 if (tok->indent &&
271 !(*flags & PyPARSE_DONT_IMPLY_DEDENT))
272 {
273 tok->pendin = -tok->indent;
274 tok->indent = 0;
275 }
276 }
277 else
278 started = 1;
Zackery Spytz7c4ab2a2018-08-15 00:27:26 -0600279 len = (a != NULL && b != NULL) ? b - a : 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 str = (char *) PyObject_MALLOC(len + 1);
281 if (str == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000282 err_ret->error = E_NOMEM;
283 break;
284 }
285 if (len > 0)
286 strncpy(str, a, len);
287 str[len] = '\0';
Guido van Rossumda62ecc2001-07-17 16:53:11 +0000288
Thomas Wouters34aa7ba2006-02-28 19:02:24 +0000289#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 if (type == NOTEQUAL) {
291 if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
292 strcmp(str, "!=")) {
Antoine Pitrou9ec25932011-11-13 01:01:23 +0100293 PyObject_FREE(str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 err_ret->error = E_SYNTAX;
295 break;
296 }
297 else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) &&
298 strcmp(str, "<>")) {
Antoine Pitrou9ec25932011-11-13 01:01:23 +0100299 PyObject_FREE(str);
Serhiy Storchakaaba24ff2018-07-23 23:41:11 +0300300 err_ret->expected = NOTEQUAL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301 err_ret->error = E_SYNTAX;
302 break;
303 }
304 }
Neil Schemenauerc24ea082002-03-22 23:53:36 +0000305#endif
Anthony Sottile995d9b92019-01-12 20:05:13 -0800306
307 /* Nodes of type STRING, especially multi line strings
308 must be handled differently in order to get both
309 the starting line number and the column offset right.
310 (cf. issue 16806) */
311 lineno = type == STRING ? tok->first_lineno : tok->lineno;
312 line_start = type == STRING ? tok->multi_line_start : tok->line_start;
313 if (a != NULL && a >= line_start) {
314 col_offset = Py_SAFE_DOWNCAST(a - line_start,
Benjamin Petersonca470632016-09-06 13:47:26 -0700315 intptr_t, int);
Zackery Spytz3e26e422018-08-20 21:11:40 -0600316 }
317 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 col_offset = -1;
Zackery Spytz3e26e422018-08-20 21:11:40 -0600319 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000320
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000321 if (b != NULL && b >= tok->line_start) {
322 end_col_offset = Py_SAFE_DOWNCAST(b - tok->line_start,
323 intptr_t, int);
324 }
325 else {
326 end_col_offset = -1;
327 }
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800328
329 if (type == TYPE_IGNORE) {
Michael J. Sullivan933e1502019-05-22 07:54:20 -0700330 if (!growable_comment_array_add(&type_ignores, tok->lineno, str)) {
Guido van Rossumdcfcd142019-01-31 03:40:27 -0800331 err_ret->error = E_NOMEM;
332 break;
333 }
334 continue;
335 }
336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 if ((err_ret->error =
338 PyParser_AddToken(ps, (int)type, str,
Ivan Levkivskyi9932a222019-01-22 11:18:22 +0000339 lineno, col_offset, tok->lineno, end_col_offset,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 &(err_ret->expected))) != E_OK) {
341 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) {
Meador Ingefa21bf02012-01-19 01:08:41 -0600382 char *cur = tok->cur;
383 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}