blob: 6471b8ee997fcf8ea1f6d5aed201edf82b823985 [file] [log] [blame]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001/* parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002 *
Guido van Rossum47478871996-08-21 14:32:37 +00003 * Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic
4 * Institute and State University, Blacksburg, Virginia, USA.
5 * Portions copyright 1991-1995 by Stichting Mathematisch Centrum,
6 * Amsterdam, The Netherlands. Copying is permitted under the terms
7 * associated with the main Python distribution, with the additional
8 * restriction that this additional notice be included and maintained
9 * on all distributed copies.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000010 *
Guido van Rossum47478871996-08-21 14:32:37 +000011 * This module serves to replace the original parser module written
12 * by Guido. The functionality is not matched precisely, but the
13 * original may be implemented on top of this. This is desirable
14 * since the source of the text to be parsed is now divorced from
15 * this interface.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000016 *
Guido van Rossum47478871996-08-21 14:32:37 +000017 * Unlike the prior interface, the ability to give a parse tree
18 * produced by Python code as a tuple to the compiler is enabled by
19 * this module. See the documentation for more details.
Fred Drake268397f1998-04-29 14:16:32 +000020 *
21 * I've added some annotations that help with the lint code-checking
22 * program, but they're not complete by a long shot. The real errors
23 * that lint detects are gone, but there are still warnings with
24 * Py_[X]DECREF() and Py_[X]INCREF() macros. The lint annotations
25 * look like "NOTE(...)".
Benjamin Peterson025e9eb2015-05-05 20:16:41 -040026 *
27 * To debug parser errors like
28 * "parser.ParserError: Expected node type 12, got 333."
29 * decode symbol numbers using the automatically-generated files
30 * Lib/symbol.h and Include/token.h.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000031 */
32
Fred Drakeff9ea482000-04-19 13:54:15 +000033#include "Python.h" /* general Python API */
Benjamin Petersonf216c942008-10-31 02:28:05 +000034#include "Python-ast.h" /* mod_ty */
Fred Drakeff9ea482000-04-19 13:54:15 +000035#include "graminit.h" /* symbols defined in the grammar */
36#include "node.h" /* internal parser structure */
Fred Drake8b55b2d2001-12-05 22:10:44 +000037#include "errcode.h" /* error codes for PyNode_*() */
Fred Drakeff9ea482000-04-19 13:54:15 +000038#include "token.h" /* token definitions */
Benjamin Petersonf216c942008-10-31 02:28:05 +000039#include "grammar.h"
40#include "parsetok.h"
Fred Drakeff9ea482000-04-19 13:54:15 +000041 /* ISTERMINAL() / ISNONTERMINAL() */
Benjamin Petersonf216c942008-10-31 02:28:05 +000042#undef Yield
43#include "ast.h"
Benjamin Petersonf216c942008-10-31 02:28:05 +000044
45extern grammar _PyParser_Grammar; /* From graminit.c */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000046
Fred Drake268397f1998-04-29 14:16:32 +000047#ifdef lint
48#include <note.h>
49#else
50#define NOTE(x)
51#endif
52
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000053/* String constants used to initialize module attributes.
54 *
55 */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000056static char parser_copyright_string[] =
57"Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
Guido van Rossum2a288461996-08-21 21:55:43 +000058University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
59Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\
60Centrum, Amsterdam, The Netherlands.";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000061
62
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000063PyDoc_STRVAR(parser_doc_string,
64"This is an interface to Python's internal parser.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000065
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000066static char parser_version_string[] = "0.5";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000067
68
Martin v. Löwis18e16552006-02-15 17:27:45 +000069typedef PyObject* (*SeqMaker) (Py_ssize_t length);
Fred Drakeff9ea482000-04-19 13:54:15 +000070typedef int (*SeqInserter) (PyObject* sequence,
Martin v. Löwis18e16552006-02-15 17:27:45 +000071 Py_ssize_t index,
Fred Drakeff9ea482000-04-19 13:54:15 +000072 PyObject* element);
Guido van Rossum47478871996-08-21 14:32:37 +000073
Thomas Wouters7e474022000-07-16 12:04:32 +000074/* The function below is copyrighted by Stichting Mathematisch Centrum. The
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000075 * original copyright statement is included below, and continues to apply
76 * in full to the function immediately following. All other material is
77 * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
78 * Institute and State University. Changes were made to comply with the
Guido van Rossum2a288461996-08-21 21:55:43 +000079 * new naming conventions. Added arguments to provide support for creating
80 * lists as well as tuples, and optionally including the line numbers.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000081 */
82
Guido van Rossum52f2c051993-11-10 12:53:24 +000083
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000084static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +000085node2tuple(node *n, /* node to convert */
86 SeqMaker mkseq, /* create sequence */
87 SeqInserter addelem, /* func. to add elem. in seq. */
Thomas Wouters89f507f2006-12-13 04:49:30 +000088 int lineno, /* include line numbers? */
89 int col_offset) /* include column offsets? */
Guido van Rossum47478871996-08-21 14:32:37 +000090{
Victor Stinnerdf4572c2013-07-12 01:35:10 +020091 PyObject *result = NULL, *w;
92
Guido van Rossum3d602e31996-07-21 02:33:56 +000093 if (n == NULL) {
Fred Drakeff9ea482000-04-19 13:54:15 +000094 Py_INCREF(Py_None);
Victor Stinnerdf4572c2013-07-12 01:35:10 +020095 return Py_None;
Guido van Rossum3d602e31996-07-21 02:33:56 +000096 }
Victor Stinnerdf4572c2013-07-12 01:35:10 +020097
Guido van Rossum3d602e31996-07-21 02:33:56 +000098 if (ISNONTERMINAL(TYPE(n))) {
Fred Drakeff9ea482000-04-19 13:54:15 +000099 int i;
Fred Drake268397f1998-04-29 14:16:32 +0000100
Victor Stinnerdf4572c2013-07-12 01:35:10 +0200101 result = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl));
102 if (result == NULL)
103 goto error;
104
Christian Heimes217cfd12007-12-02 14:31:20 +0000105 w = PyLong_FromLong(TYPE(n));
Victor Stinnerdf4572c2013-07-12 01:35:10 +0200106 if (w == NULL)
107 goto error;
108 (void) addelem(result, 0, w);
109
Fred Drakeff9ea482000-04-19 13:54:15 +0000110 for (i = 0; i < NCH(n); i++) {
Thomas Wouters89f507f2006-12-13 04:49:30 +0000111 w = node2tuple(CHILD(n, i), mkseq, addelem, lineno, col_offset);
Victor Stinnerdf4572c2013-07-12 01:35:10 +0200112 if (w == NULL)
113 goto error;
114 (void) addelem(result, i+1, w);
Fred Drakeff9ea482000-04-19 13:54:15 +0000115 }
Tim Peters6a627252003-07-21 14:25:23 +0000116
Victor Stinnerdf4572c2013-07-12 01:35:10 +0200117 if (TYPE(n) == encoding_decl) {
118 w = PyUnicode_FromString(STR(n));
119 if (w == NULL)
120 goto error;
121 (void) addelem(result, i+1, w);
122 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000123 }
124 else if (ISTERMINAL(TYPE(n))) {
Victor Stinnerdf4572c2013-07-12 01:35:10 +0200125 result = mkseq(2 + lineno + col_offset);
126 if (result == NULL)
127 goto error;
128
129 w = PyLong_FromLong(TYPE(n));
130 if (w == NULL)
131 goto error;
132 (void) addelem(result, 0, w);
133
134 w = PyUnicode_FromString(STR(n));
135 if (w == NULL)
136 goto error;
137 (void) addelem(result, 1, w);
138
139 if (lineno == 1) {
140 w = PyLong_FromLong(n->n_lineno);
141 if (w == NULL)
142 goto error;
143 (void) addelem(result, 2, w);
Fred Drakeff9ea482000-04-19 13:54:15 +0000144 }
Victor Stinnerdf4572c2013-07-12 01:35:10 +0200145
146 if (col_offset == 1) {
147 w = PyLong_FromLong(n->n_col_offset);
148 if (w == NULL)
149 goto error;
150 (void) addelem(result, 3, w);
151 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000152 }
153 else {
Fred Drakeff9ea482000-04-19 13:54:15 +0000154 PyErr_SetString(PyExc_SystemError,
155 "unrecognized parse tree node type");
156 return ((PyObject*) NULL);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000157 }
Victor Stinnerdf4572c2013-07-12 01:35:10 +0200158 return result;
159
160error:
161 Py_XDECREF(result);
162 return NULL;
Fred Drakeff9ea482000-04-19 13:54:15 +0000163}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000164/*
165 * End of material copyrighted by Stichting Mathematisch Centrum.
166 */
Guido van Rossum52f2c051993-11-10 12:53:24 +0000167
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000168
169
170/* There are two types of intermediate objects we're interested in:
Fred Drakec2683dd2001-07-17 19:32:05 +0000171 * 'eval' and 'exec' types. These constants can be used in the st_type
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000172 * field of the object type to identify which any given object represents.
173 * These should probably go in an external header to allow other extensions
174 * to use them, but then, we really should be using C++ too. ;-)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000175 */
176
Fred Drakec2683dd2001-07-17 19:32:05 +0000177#define PyST_EXPR 1
178#define PyST_SUITE 2
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000179
180
181/* These are the internal objects and definitions required to implement the
Fred Drakec2683dd2001-07-17 19:32:05 +0000182 * ST type. Most of the internal names are more reminiscent of the 'old'
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000183 * naming style, but the code uses the new naming convention.
184 */
185
186static PyObject*
187parser_error = 0;
188
189
Fred Drakec2683dd2001-07-17 19:32:05 +0000190typedef struct {
Fred Drakeff9ea482000-04-19 13:54:15 +0000191 PyObject_HEAD /* standard object header */
Fred Drakec2683dd2001-07-17 19:32:05 +0000192 node* st_node; /* the node* returned by the parser */
193 int st_type; /* EXPR or SUITE ? */
Benjamin Petersonf216c942008-10-31 02:28:05 +0000194 PyCompilerFlags st_flags; /* Parser and compiler flags */
Fred Drakec2683dd2001-07-17 19:32:05 +0000195} PyST_Object;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000196
197
Jeremy Hylton938ace62002-07-17 16:30:39 +0000198static void parser_free(PyST_Object *st);
Jesus Ceae9c53182012-08-03 14:28:37 +0200199static PyObject* parser_sizeof(PyST_Object *, void *);
Mark Dickinson211c6252009-02-01 10:28:51 +0000200static PyObject* parser_richcompare(PyObject *left, PyObject *right, int op);
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000201static PyObject* parser_compilest(PyST_Object *, PyObject *, PyObject *);
202static PyObject* parser_isexpr(PyST_Object *, PyObject *, PyObject *);
203static PyObject* parser_issuite(PyST_Object *, PyObject *, PyObject *);
204static PyObject* parser_st2list(PyST_Object *, PyObject *, PyObject *);
205static PyObject* parser_st2tuple(PyST_Object *, PyObject *, PyObject *);
Fred Drake503d8d61998-04-13 18:45:18 +0000206
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000207#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS)
208
209static PyMethodDef parser_methods[] = {
210 {"compile", (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE,
211 PyDoc_STR("Compile this ST object into a code object.")},
212 {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
213 PyDoc_STR("Determines if this ST object was created from an expression.")},
214 {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
215 PyDoc_STR("Determines if this ST object was created from a suite.")},
216 {"tolist", (PyCFunction)parser_st2list, PUBLIC_METHOD_TYPE,
217 PyDoc_STR("Creates a list-tree representation of this ST.")},
218 {"totuple", (PyCFunction)parser_st2tuple, PUBLIC_METHOD_TYPE,
219 PyDoc_STR("Creates a tuple-tree representation of this ST.")},
Jesus Ceae9c53182012-08-03 14:28:37 +0200220 {"__sizeof__", (PyCFunction)parser_sizeof, METH_NOARGS,
221 PyDoc_STR("Returns size in memory, in bytes.")},
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000222 {NULL, NULL, 0, NULL}
223};
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000224
Fred Drake268397f1998-04-29 14:16:32 +0000225static
Fred Drakec2683dd2001-07-17 19:32:05 +0000226PyTypeObject PyST_Type = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000227 PyVarObject_HEAD_INIT(NULL, 0)
Guido van Rossum14648392001-12-08 18:02:58 +0000228 "parser.st", /* tp_name */
Fred Drakec2683dd2001-07-17 19:32:05 +0000229 (int) sizeof(PyST_Object), /* tp_basicsize */
Fred Drakeff9ea482000-04-19 13:54:15 +0000230 0, /* tp_itemsize */
231 (destructor)parser_free, /* tp_dealloc */
232 0, /* tp_print */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000233 0, /* tp_getattr */
Fred Drakeff9ea482000-04-19 13:54:15 +0000234 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +0000235 0, /* tp_reserved */
Fred Drakeff9ea482000-04-19 13:54:15 +0000236 0, /* tp_repr */
237 0, /* tp_as_number */
238 0, /* tp_as_sequence */
239 0, /* tp_as_mapping */
240 0, /* tp_hash */
241 0, /* tp_call */
242 0, /* tp_str */
243 0, /* tp_getattro */
244 0, /* tp_setattro */
Fred Drake69b9ae41997-05-23 04:04:17 +0000245
246 /* Functions to access object as input/output buffer */
Fred Drakeff9ea482000-04-19 13:54:15 +0000247 0, /* tp_as_buffer */
Fred Drake69b9ae41997-05-23 04:04:17 +0000248
Fred Drakeff9ea482000-04-19 13:54:15 +0000249 Py_TPFLAGS_DEFAULT, /* tp_flags */
Fred Drake69b9ae41997-05-23 04:04:17 +0000250
251 /* __doc__ */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000252 "Intermediate representation of a Python parse tree.",
253 0, /* tp_traverse */
254 0, /* tp_clear */
Mark Dickinson211c6252009-02-01 10:28:51 +0000255 parser_richcompare, /* tp_richcompare */
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000256 0, /* tp_weaklistoffset */
257 0, /* tp_iter */
258 0, /* tp_iternext */
259 parser_methods, /* tp_methods */
Fred Drakec2683dd2001-07-17 19:32:05 +0000260}; /* PyST_Type */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000261
262
Mark Dickinson211c6252009-02-01 10:28:51 +0000263/* PyST_Type isn't subclassable, so just check ob_type */
264#define PyST_Object_Check(v) ((v)->ob_type == &PyST_Type)
265
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000266static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000267parser_compare_nodes(node *left, node *right)
Guido van Rossum47478871996-08-21 14:32:37 +0000268{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000269 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000270
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000271 if (TYPE(left) < TYPE(right))
Fred Drakeff9ea482000-04-19 13:54:15 +0000272 return (-1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000273
274 if (TYPE(right) < TYPE(left))
Fred Drakeff9ea482000-04-19 13:54:15 +0000275 return (1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000276
277 if (ISTERMINAL(TYPE(left)))
Fred Drakeff9ea482000-04-19 13:54:15 +0000278 return (strcmp(STR(left), STR(right)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000279
280 if (NCH(left) < NCH(right))
Fred Drakeff9ea482000-04-19 13:54:15 +0000281 return (-1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000282
283 if (NCH(right) < NCH(left))
Fred Drakeff9ea482000-04-19 13:54:15 +0000284 return (1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000285
286 for (j = 0; j < NCH(left); ++j) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000287 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000288
Fred Drakeff9ea482000-04-19 13:54:15 +0000289 if (v != 0)
290 return (v);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000291 }
292 return (0);
Fred Drakeff9ea482000-04-19 13:54:15 +0000293}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000294
Mark Dickinson211c6252009-02-01 10:28:51 +0000295/* parser_richcompare(PyObject* left, PyObject* right, int op)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000296 *
297 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
298 * This really just wraps a call to parser_compare_nodes() with some easy
299 * checks and protection code.
300 *
301 */
Mark Dickinson211c6252009-02-01 10:28:51 +0000302
303#define TEST_COND(cond) ((cond) ? Py_True : Py_False)
304
305static PyObject *
306parser_richcompare(PyObject *left, PyObject *right, int op)
Guido van Rossum47478871996-08-21 14:32:37 +0000307{
Mark Dickinson211c6252009-02-01 10:28:51 +0000308 int result;
309 PyObject *v;
310
311 /* neither argument should be NULL, unless something's gone wrong */
312 if (left == NULL || right == NULL) {
313 PyErr_BadInternalCall();
314 return NULL;
315 }
316
317 /* both arguments should be instances of PyST_Object */
318 if (!PyST_Object_Check(left) || !PyST_Object_Check(right)) {
319 v = Py_NotImplemented;
320 goto finished;
321 }
322
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000323 if (left == right)
Mark Dickinson211c6252009-02-01 10:28:51 +0000324 /* if arguments are identical, they're equal */
325 result = 0;
326 else
327 result = parser_compare_nodes(((PyST_Object *)left)->st_node,
328 ((PyST_Object *)right)->st_node);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000329
Mark Dickinson211c6252009-02-01 10:28:51 +0000330 /* Convert return value to a Boolean */
331 switch (op) {
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000332 case Py_EQ:
Mark Dickinson211c6252009-02-01 10:28:51 +0000333 v = TEST_COND(result == 0);
334 break;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000335 case Py_NE:
Mark Dickinson211c6252009-02-01 10:28:51 +0000336 v = TEST_COND(result != 0);
337 break;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000338 case Py_LE:
Mark Dickinson211c6252009-02-01 10:28:51 +0000339 v = TEST_COND(result <= 0);
340 break;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000341 case Py_GE:
Mark Dickinson211c6252009-02-01 10:28:51 +0000342 v = TEST_COND(result >= 0);
343 break;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000344 case Py_LT:
Mark Dickinson211c6252009-02-01 10:28:51 +0000345 v = TEST_COND(result < 0);
346 break;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000347 case Py_GT:
Mark Dickinson211c6252009-02-01 10:28:51 +0000348 v = TEST_COND(result > 0);
349 break;
Nick Coghlan1f7ce622012-01-13 21:43:40 +1000350 default:
Mark Dickinson211c6252009-02-01 10:28:51 +0000351 PyErr_BadArgument();
352 return NULL;
353 }
354 finished:
355 Py_INCREF(v);
356 return v;
Fred Drakeff9ea482000-04-19 13:54:15 +0000357}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000358
Fred Drakec2683dd2001-07-17 19:32:05 +0000359/* parser_newstobject(node* st)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000360 *
Fred Drakec2683dd2001-07-17 19:32:05 +0000361 * Allocates a new Python object representing an ST. This is simply the
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000362 * 'wrapper' object that holds a node* and allows it to be passed around in
363 * Python code.
364 *
365 */
366static PyObject*
Fred Drakec2683dd2001-07-17 19:32:05 +0000367parser_newstobject(node *st, int type)
Guido van Rossum47478871996-08-21 14:32:37 +0000368{
Fred Drakec2683dd2001-07-17 19:32:05 +0000369 PyST_Object* o = PyObject_New(PyST_Object, &PyST_Type);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000370
371 if (o != 0) {
Fred Drakec2683dd2001-07-17 19:32:05 +0000372 o->st_node = st;
373 o->st_type = type;
Benjamin Petersonf216c942008-10-31 02:28:05 +0000374 o->st_flags.cf_flags = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000375 }
Fred Drake268397f1998-04-29 14:16:32 +0000376 else {
Fred Drakec2683dd2001-07-17 19:32:05 +0000377 PyNode_Free(st);
Fred Drake268397f1998-04-29 14:16:32 +0000378 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000379 return ((PyObject*)o);
Fred Drakeff9ea482000-04-19 13:54:15 +0000380}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000381
382
Fred Drakec2683dd2001-07-17 19:32:05 +0000383/* void parser_free(PyST_Object* st)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000384 *
385 * This is called by a del statement that reduces the reference count to 0.
386 *
387 */
388static void
Fred Drakec2683dd2001-07-17 19:32:05 +0000389parser_free(PyST_Object *st)
Guido van Rossum47478871996-08-21 14:32:37 +0000390{
Fred Drakec2683dd2001-07-17 19:32:05 +0000391 PyNode_Free(st->st_node);
392 PyObject_Del(st);
Fred Drakeff9ea482000-04-19 13:54:15 +0000393}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000394
Jesus Ceae9c53182012-08-03 14:28:37 +0200395static PyObject *
396parser_sizeof(PyST_Object *st, void *unused)
397{
398 Py_ssize_t res;
399
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +0200400 res = _PyObject_SIZE(Py_TYPE(st)) + _PyNode_SizeOf(st->st_node);
Jesus Ceae9c53182012-08-03 14:28:37 +0200401 return PyLong_FromSsize_t(res);
402}
403
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000404
Fred Drakec2683dd2001-07-17 19:32:05 +0000405/* parser_st2tuple(PyObject* self, PyObject* args, PyObject* kw)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000406 *
407 * This provides conversion from a node* to a tuple object that can be
Fred Drakec2683dd2001-07-17 19:32:05 +0000408 * returned to the Python-level caller. The ST object is not modified.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000409 *
410 */
411static PyObject*
Fred Drakec2683dd2001-07-17 19:32:05 +0000412parser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000413{
Antoine Pitrou721738f2012-08-15 23:20:39 +0200414 int line_info = 0;
415 int col_info = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000416 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000417 int ok;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000418
Georg Brandl30704ea02008-07-23 15:07:12 +0000419 static char *keywords[] = {"st", "line_info", "col_info", NULL};
Fred Drake7a15ba51999-09-09 14:21:52 +0000420
Martin v. Löwis1a214512008-06-11 05:26:20 +0000421 if (self == NULL || PyModule_Check(self)) {
Antoine Pitrou721738f2012-08-15 23:20:39 +0200422 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|pp:st2tuple", keywords,
423 &PyST_Type, &self, &line_info,
424 &col_info);
Fred Drake268397f1998-04-29 14:16:32 +0000425 }
Fred Drake503d8d61998-04-13 18:45:18 +0000426 else
Antoine Pitrou721738f2012-08-15 23:20:39 +0200427 ok = PyArg_ParseTupleAndKeywords(args, kw, "|pp:totuple", &keywords[1],
428 &line_info, &col_info);
Fred Drake268397f1998-04-29 14:16:32 +0000429 if (ok != 0) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000430 /*
Fred Drakec2683dd2001-07-17 19:32:05 +0000431 * Convert ST into a tuple representation. Use Guido's function,
Fred Drakeff9ea482000-04-19 13:54:15 +0000432 * since it's known to work already.
433 */
Fred Drakec2683dd2001-07-17 19:32:05 +0000434 res = node2tuple(((PyST_Object*)self)->st_node,
Antoine Pitrou721738f2012-08-15 23:20:39 +0200435 PyTuple_New, PyTuple_SetItem, line_info, col_info);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000436 }
437 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000438}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000439
440
Fred Drakec2683dd2001-07-17 19:32:05 +0000441/* parser_st2list(PyObject* self, PyObject* args, PyObject* kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000442 *
Fred Drake2a6875e1999-09-20 22:32:18 +0000443 * This provides conversion from a node* to a list object that can be
Fred Drakec2683dd2001-07-17 19:32:05 +0000444 * returned to the Python-level caller. The ST object is not modified.
Guido van Rossum47478871996-08-21 14:32:37 +0000445 *
446 */
447static PyObject*
Fred Drakec2683dd2001-07-17 19:32:05 +0000448parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000449{
Antoine Pitrou721738f2012-08-15 23:20:39 +0200450 int line_info = 0;
451 int col_info = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000452 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000453 int ok;
Guido van Rossum47478871996-08-21 14:32:37 +0000454
Georg Brandl30704ea02008-07-23 15:07:12 +0000455 static char *keywords[] = {"st", "line_info", "col_info", NULL};
Fred Drake7a15ba51999-09-09 14:21:52 +0000456
Martin v. Löwis1a214512008-06-11 05:26:20 +0000457 if (self == NULL || PyModule_Check(self))
Antoine Pitrou721738f2012-08-15 23:20:39 +0200458 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|pp:st2list", keywords,
459 &PyST_Type, &self, &line_info,
460 &col_info);
Fred Drake503d8d61998-04-13 18:45:18 +0000461 else
Antoine Pitrou721738f2012-08-15 23:20:39 +0200462 ok = PyArg_ParseTupleAndKeywords(args, kw, "|pp:tolist", &keywords[1],
463 &line_info, &col_info);
Fred Drake503d8d61998-04-13 18:45:18 +0000464 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000465 /*
Fred Drakec2683dd2001-07-17 19:32:05 +0000466 * Convert ST into a tuple representation. Use Guido's function,
Fred Drakeff9ea482000-04-19 13:54:15 +0000467 * since it's known to work already.
468 */
Fred Drakec2683dd2001-07-17 19:32:05 +0000469 res = node2tuple(self->st_node,
Antoine Pitrou721738f2012-08-15 23:20:39 +0200470 PyList_New, PyList_SetItem, line_info, col_info);
Guido van Rossum47478871996-08-21 14:32:37 +0000471 }
472 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000473}
Guido van Rossum47478871996-08-21 14:32:37 +0000474
475
Fred Drakec2683dd2001-07-17 19:32:05 +0000476/* parser_compilest(PyObject* self, PyObject* args)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000477 *
478 * This function creates code objects from the parse tree represented by
479 * the passed-in data object. An optional file name is passed in as well.
480 *
481 */
482static PyObject*
Fred Drakec2683dd2001-07-17 19:32:05 +0000483parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000484{
Victor Stinner14e461d2013-08-26 22:28:21 +0200485 PyObject* res = NULL;
486 PyArena* arena = NULL;
Benjamin Petersonf216c942008-10-31 02:28:05 +0000487 mod_ty mod;
Victor Stinner14e461d2013-08-26 22:28:21 +0200488 PyObject* filename = NULL;
Fred Drake503d8d61998-04-13 18:45:18 +0000489 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000490
Georg Brandl30704ea02008-07-23 15:07:12 +0000491 static char *keywords[] = {"st", "filename", NULL};
Fred Drake7a15ba51999-09-09 14:21:52 +0000492
Martin v. Löwis1a214512008-06-11 05:26:20 +0000493 if (self == NULL || PyModule_Check(self))
Victor Stinner14e461d2013-08-26 22:28:21 +0200494 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O&:compilest", keywords,
495 &PyST_Type, &self,
496 PyUnicode_FSDecoder, &filename);
Fred Drake503d8d61998-04-13 18:45:18 +0000497 else
Victor Stinner14e461d2013-08-26 22:28:21 +0200498 ok = PyArg_ParseTupleAndKeywords(args, kw, "|O&:compile", &keywords[1],
499 PyUnicode_FSDecoder, &filename);
500 if (!ok)
501 goto error;
Fred Drake503d8d61998-04-13 18:45:18 +0000502
Victor Stinner14e461d2013-08-26 22:28:21 +0200503 if (filename == NULL) {
504 filename = PyUnicode_FromString("<syntax-tree>");
505 if (filename == NULL)
506 goto error;
Benjamin Petersonf216c942008-10-31 02:28:05 +0000507 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000508
Victor Stinner14e461d2013-08-26 22:28:21 +0200509 arena = PyArena_New();
510 if (!arena)
511 goto error;
512
513 mod = PyAST_FromNodeObject(self->st_node, &self->st_flags,
514 filename, arena);
515 if (!mod)
516 goto error;
517
518 res = (PyObject *)PyAST_CompileObject(mod, filename,
519 &self->st_flags, -1, arena);
520error:
521 Py_XDECREF(filename);
522 if (arena != NULL)
523 PyArena_Free(arena);
524 return res;
Fred Drakeff9ea482000-04-19 13:54:15 +0000525}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000526
527
528/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
529 * PyObject* parser_issuite(PyObject* self, PyObject* args)
530 *
Fred Drakec2683dd2001-07-17 19:32:05 +0000531 * Checks the passed-in ST object to determine if it is an expression or
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000532 * a statement suite, respectively. The return is a Python truth value.
533 *
534 */
535static PyObject*
Fred Drakec2683dd2001-07-17 19:32:05 +0000536parser_isexpr(PyST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000537{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000538 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000539 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000540
Georg Brandl30704ea02008-07-23 15:07:12 +0000541 static char *keywords[] = {"st", NULL};
Fred Drake7a15ba51999-09-09 14:21:52 +0000542
Martin v. Löwis1a214512008-06-11 05:26:20 +0000543 if (self == NULL || PyModule_Check(self))
Fred Drakeff9ea482000-04-19 13:54:15 +0000544 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
Fred Drakec2683dd2001-07-17 19:32:05 +0000545 &PyST_Type, &self);
Fred Drake503d8d61998-04-13 18:45:18 +0000546 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000547 ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]);
Fred Drake503d8d61998-04-13 18:45:18 +0000548
549 if (ok) {
Fred Drakec2683dd2001-07-17 19:32:05 +0000550 /* Check to see if the ST represents an expression or not. */
551 res = (self->st_type == PyST_EXPR) ? Py_True : Py_False;
Fred Drakeff9ea482000-04-19 13:54:15 +0000552 Py_INCREF(res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000553 }
554 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000555}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000556
557
558static PyObject*
Fred Drakec2683dd2001-07-17 19:32:05 +0000559parser_issuite(PyST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000560{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000561 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000562 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000563
Georg Brandl30704ea02008-07-23 15:07:12 +0000564 static char *keywords[] = {"st", NULL};
Fred Drake7a15ba51999-09-09 14:21:52 +0000565
Martin v. Löwis1a214512008-06-11 05:26:20 +0000566 if (self == NULL || PyModule_Check(self))
Fred Drakeff9ea482000-04-19 13:54:15 +0000567 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
Fred Drakec2683dd2001-07-17 19:32:05 +0000568 &PyST_Type, &self);
Fred Drake503d8d61998-04-13 18:45:18 +0000569 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000570 ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]);
Fred Drake503d8d61998-04-13 18:45:18 +0000571
572 if (ok) {
Fred Drakec2683dd2001-07-17 19:32:05 +0000573 /* Check to see if the ST represents an expression or not. */
574 res = (self->st_type == PyST_EXPR) ? Py_False : Py_True;
Fred Drakeff9ea482000-04-19 13:54:15 +0000575 Py_INCREF(res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000576 }
577 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000578}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000579
580
Guido van Rossum3d602e31996-07-21 02:33:56 +0000581/* err_string(char* message)
582 *
583 * Sets the error string for an exception of type ParserError.
584 *
585 */
586static void
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +0000587err_string(char *message)
Guido van Rossum47478871996-08-21 14:32:37 +0000588{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000589 PyErr_SetString(parser_error, message);
Fred Drakeff9ea482000-04-19 13:54:15 +0000590}
Guido van Rossum3d602e31996-07-21 02:33:56 +0000591
592
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000593/* PyObject* parser_do_parse(PyObject* args, int type)
594 *
595 * Internal function to actually execute the parse and return the result if
Jeremy Hyltonaccb62b2002-12-31 18:17:44 +0000596 * successful or set an exception if not.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000597 *
598 */
599static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000600parser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type)
Guido van Rossum47478871996-08-21 14:32:37 +0000601{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000602 char* string = 0;
603 PyObject* res = 0;
Benjamin Petersonf216c942008-10-31 02:28:05 +0000604 int flags = 0;
605 perrdetail err;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000606
Martin v. Löwisb79afb62006-02-27 17:01:22 +0000607 static char *keywords[] = {"source", NULL};
Fred Drake7a15ba51999-09-09 14:21:52 +0000608
609 if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
Benjamin Petersonf216c942008-10-31 02:28:05 +0000610 node* n = PyParser_ParseStringFlagsFilenameEx(string, NULL,
611 &_PyParser_Grammar,
612 (type == PyST_EXPR)
613 ? eval_input : file_input,
614 &err, &flags);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 if (n) {
617 res = parser_newstobject(n, type);
Benjamin Petersonf216c942008-10-31 02:28:05 +0000618 if (res)
619 ((PyST_Object *)res)->st_flags.cf_flags = flags & PyCF_MASK;
620 }
Benjamin Petersonf719957d2011-06-04 22:06:42 -0500621 else {
Benjamin Petersonf216c942008-10-31 02:28:05 +0000622 PyParser_SetError(&err);
Benjamin Petersonf719957d2011-06-04 22:06:42 -0500623 }
Benjamin Petersonf0cdbad2011-06-05 22:14:05 -0500624 PyParser_ClearError(&err);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000625 }
626 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000627}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000628
629
630/* PyObject* parser_expr(PyObject* self, PyObject* args)
631 * PyObject* parser_suite(PyObject* self, PyObject* args)
632 *
633 * External interfaces to the parser itself. Which is called determines if
634 * the parser attempts to recognize an expression ('eval' form) or statement
635 * suite ('exec' form). The real work is done by parser_do_parse() above.
636 *
637 */
638static PyObject*
Fred Drakec2683dd2001-07-17 19:32:05 +0000639parser_expr(PyST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000640{
Fred Drake268397f1998-04-29 14:16:32 +0000641 NOTE(ARGUNUSED(self))
Fred Drakec2683dd2001-07-17 19:32:05 +0000642 return (parser_do_parse(args, kw, "s:expr", PyST_EXPR));
Fred Drakeff9ea482000-04-19 13:54:15 +0000643}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000644
645
646static PyObject*
Fred Drakec2683dd2001-07-17 19:32:05 +0000647parser_suite(PyST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000648{
Fred Drake268397f1998-04-29 14:16:32 +0000649 NOTE(ARGUNUSED(self))
Fred Drakec2683dd2001-07-17 19:32:05 +0000650 return (parser_do_parse(args, kw, "s:suite", PyST_SUITE));
Fred Drakeff9ea482000-04-19 13:54:15 +0000651}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000652
653
654
Fred Drakec2683dd2001-07-17 19:32:05 +0000655/* This is the messy part of the code. Conversion from a tuple to an ST
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000656 * object requires that the input tuple be valid without having to rely on
657 * catching an exception from the compiler. This is done to allow the
658 * compiler itself to remain fast, since most of its input will come from
659 * the parser directly, and therefore be known to be syntactically correct.
660 * This validation is done to ensure that we don't core dump the compile
661 * phase, returning an exception instead.
662 *
663 * Two aspects can be broken out in this code: creating a node tree from
664 * the tuple passed in, and verifying that it is indeed valid. It may be
Fred Drakec2683dd2001-07-17 19:32:05 +0000665 * advantageous to expand the number of ST types to include funcdefs and
666 * lambdadefs to take advantage of the optimizer, recognizing those STs
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000667 * here. They are not necessary, and not quite as useful in a raw form.
668 * For now, let's get expressions and suites working reliably.
669 */
670
671
Jeremy Hylton938ace62002-07-17 16:30:39 +0000672static node* build_node_tree(PyObject *tuple);
673static int validate_expr_tree(node *tree);
674static int validate_file_input(node *tree);
Michael W. Hudsondf1252d2003-02-08 18:05:10 +0000675static int validate_encoding_decl(node *tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000676
Fred Drakec2683dd2001-07-17 19:32:05 +0000677/* PyObject* parser_tuple2st(PyObject* self, PyObject* args)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000678 *
679 * This is the public function, called from the Python code. It receives a
Fred Drakec2683dd2001-07-17 19:32:05 +0000680 * single tuple object from the caller, and creates an ST object if the
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000681 * tuple can be validated. It does this by checking the first code of the
682 * tuple, and, if acceptable, builds the internal representation. If this
683 * step succeeds, the internal representation is validated as fully as
684 * possible with the various validate_*() routines defined below.
685 *
Fred Drakec2683dd2001-07-17 19:32:05 +0000686 * This function must be changed if support is to be added for PyST_FRAGMENT
687 * ST objects.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000688 *
689 */
690static PyObject*
Fred Drakec2683dd2001-07-17 19:32:05 +0000691parser_tuple2st(PyST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000692{
Fred Drake268397f1998-04-29 14:16:32 +0000693 NOTE(ARGUNUSED(self))
Fred Drakec2683dd2001-07-17 19:32:05 +0000694 PyObject *st = 0;
Fred Drake0ac9b072000-09-12 21:58:06 +0000695 PyObject *tuple;
696 node *tree;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000697
Martin v. Löwisb79afb62006-02-27 17:01:22 +0000698 static char *keywords[] = {"sequence", NULL};
Fred Drake7a15ba51999-09-09 14:21:52 +0000699
Fred Drakec2683dd2001-07-17 19:32:05 +0000700 if (!PyArg_ParseTupleAndKeywords(args, kw, "O:sequence2st", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000701 &tuple))
Fred Drakeff9ea482000-04-19 13:54:15 +0000702 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000703 if (!PySequence_Check(tuple)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000704 PyErr_SetString(PyExc_ValueError,
Fred Drakec2683dd2001-07-17 19:32:05 +0000705 "sequence2st() requires a single sequence argument");
Fred Drakeff9ea482000-04-19 13:54:15 +0000706 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000707 }
708 /*
Fred Drake0ac9b072000-09-12 21:58:06 +0000709 * Convert the tree to the internal form before checking it.
Guido van Rossum47478871996-08-21 14:32:37 +0000710 */
Fred Drake0ac9b072000-09-12 21:58:06 +0000711 tree = build_node_tree(tuple);
712 if (tree != 0) {
713 int start_sym = TYPE(tree);
714 if (start_sym == eval_input) {
715 /* Might be an eval form. */
716 if (validate_expr_tree(tree))
Fred Drakec2683dd2001-07-17 19:32:05 +0000717 st = parser_newstobject(tree, PyST_EXPR);
Fred Drake8b55b2d2001-12-05 22:10:44 +0000718 else
719 PyNode_Free(tree);
Fred Drakeff9ea482000-04-19 13:54:15 +0000720 }
Fred Drake0ac9b072000-09-12 21:58:06 +0000721 else if (start_sym == file_input) {
722 /* This looks like an exec form so far. */
723 if (validate_file_input(tree))
Fred Drakec2683dd2001-07-17 19:32:05 +0000724 st = parser_newstobject(tree, PyST_SUITE);
Fred Drake8b55b2d2001-12-05 22:10:44 +0000725 else
726 PyNode_Free(tree);
Fred Drake0ac9b072000-09-12 21:58:06 +0000727 }
Michael W. Hudsondf1252d2003-02-08 18:05:10 +0000728 else if (start_sym == encoding_decl) {
729 /* This looks like an encoding_decl so far. */
730 if (validate_encoding_decl(tree))
731 st = parser_newstobject(tree, PyST_SUITE);
732 else
733 PyNode_Free(tree);
734 }
Fred Drake0ac9b072000-09-12 21:58:06 +0000735 else {
736 /* This is a fragment, at best. */
737 PyNode_Free(tree);
Fred Drake661ea262000-10-24 19:57:45 +0000738 err_string("parse tree does not use a valid start symbol");
Fred Drake0ac9b072000-09-12 21:58:06 +0000739 }
Guido van Rossum47478871996-08-21 14:32:37 +0000740 }
Andrew Svetlov737fb892012-12-18 21:14:22 +0200741 /* Make sure we raise an exception on all errors. We should never
Guido van Rossum47478871996-08-21 14:32:37 +0000742 * get this, but we'd do well to be sure something is done.
743 */
Fred Drakec2683dd2001-07-17 19:32:05 +0000744 if (st == NULL && !PyErr_Occurred())
745 err_string("unspecified ST error occurred");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000746
Fred Drakec2683dd2001-07-17 19:32:05 +0000747 return st;
Fred Drakeff9ea482000-04-19 13:54:15 +0000748}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000749
750
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000751/* node* build_node_children()
752 *
753 * Iterate across the children of the current non-terminal node and build
754 * their structures. If successful, return the root of this portion of
755 * the tree, otherwise, 0. Any required exception will be specified already,
756 * and no memory will have been deallocated.
757 *
758 */
759static node*
Fred Drakeff9ea482000-04-19 13:54:15 +0000760build_node_children(PyObject *tuple, node *root, int *line_num)
Guido van Rossum47478871996-08-21 14:32:37 +0000761{
Martin v. Löwis18e16552006-02-15 17:27:45 +0000762 Py_ssize_t len = PyObject_Size(tuple);
763 Py_ssize_t i;
764 int err;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000765
766 for (i = 1; i < len; ++i) {
Fred Drake0ac9b072000-09-12 21:58:06 +0000767 /* elem must always be a sequence, however simple */
Fred Drakeff9ea482000-04-19 13:54:15 +0000768 PyObject* elem = PySequence_GetItem(tuple, i);
769 int ok = elem != NULL;
Serhiy Storchaka78980432013-01-15 01:12:17 +0200770 int type = 0;
Fred Drakeff9ea482000-04-19 13:54:15 +0000771 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000772
Fred Drakeff9ea482000-04-19 13:54:15 +0000773 if (ok)
774 ok = PySequence_Check(elem);
775 if (ok) {
776 PyObject *temp = PySequence_GetItem(elem, 0);
777 if (temp == NULL)
778 ok = 0;
779 else {
Christian Heimes217cfd12007-12-02 14:31:20 +0000780 ok = PyLong_Check(temp);
Serhiy Storchaka78980432013-01-15 01:12:17 +0200781 if (ok) {
782 type = _PyLong_AsInt(temp);
783 if (type == -1 && PyErr_Occurred()) {
784 Py_DECREF(temp);
785 Py_DECREF(elem);
786 return 0;
787 }
788 }
Fred Drakeff9ea482000-04-19 13:54:15 +0000789 Py_DECREF(temp);
790 }
791 }
792 if (!ok) {
Victor Stinner5f8d4852014-01-02 11:49:27 +0100793 PyObject *err = Py_BuildValue("Os", elem,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000794 "Illegal node construct.");
795 PyErr_SetObject(parser_error, err);
796 Py_XDECREF(err);
Fred Drakeff9ea482000-04-19 13:54:15 +0000797 Py_XDECREF(elem);
798 return (0);
799 }
800 if (ISTERMINAL(type)) {
Martin v. Löwis18e16552006-02-15 17:27:45 +0000801 Py_ssize_t len = PyObject_Size(elem);
Fred Drake0ac9b072000-09-12 21:58:06 +0000802 PyObject *temp;
Neal Norwitz3fcbea52007-08-26 04:51:28 +0000803 const char *temp_str;
Guido van Rossum47478871996-08-21 14:32:37 +0000804
Fred Drake0ac9b072000-09-12 21:58:06 +0000805 if ((len != 2) && (len != 3)) {
Fred Drake661ea262000-10-24 19:57:45 +0000806 err_string("terminal nodes must have 2 or 3 entries");
Fred Drake0ac9b072000-09-12 21:58:06 +0000807 return 0;
808 }
809 temp = PySequence_GetItem(elem, 1);
810 if (temp == NULL)
811 return 0;
Neal Norwitz3fcbea52007-08-26 04:51:28 +0000812 if (!PyUnicode_Check(temp)) {
Fred Drake0ac9b072000-09-12 21:58:06 +0000813 PyErr_Format(parser_error,
Fred Drake661ea262000-10-24 19:57:45 +0000814 "second item in terminal node must be a string,"
815 " found %s",
Christian Heimes90aa7642007-12-19 02:45:37 +0000816 Py_TYPE(temp)->tp_name);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000817 Py_DECREF(temp);
Neal Norwitz2cde0eb2007-08-11 04:58:43 +0000818 Py_DECREF(elem);
Fred Drake0ac9b072000-09-12 21:58:06 +0000819 return 0;
820 }
821 if (len == 3) {
822 PyObject *o = PySequence_GetItem(elem, 2);
823 if (o != NULL) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200824 if (PyLong_Check(o)) {
825 int num = _PyLong_AsInt(o);
826 if (num == -1 && PyErr_Occurred()) {
827 Py_DECREF(o);
828 Py_DECREF(temp);
829 Py_DECREF(elem);
830 return 0;
831 }
832 *line_num = num;
833 }
Fred Drake0ac9b072000-09-12 21:58:06 +0000834 else {
835 PyErr_Format(parser_error,
Fred Drake661ea262000-10-24 19:57:45 +0000836 "third item in terminal node must be an"
837 " integer, found %s",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000838 Py_TYPE(temp)->tp_name);
Fred Drake0ac9b072000-09-12 21:58:06 +0000839 Py_DECREF(o);
840 Py_DECREF(temp);
Neal Norwitz2cde0eb2007-08-11 04:58:43 +0000841 Py_DECREF(elem);
Fred Drake0ac9b072000-09-12 21:58:06 +0000842 return 0;
843 }
844 Py_DECREF(o);
Fred Drakeff9ea482000-04-19 13:54:15 +0000845 }
846 }
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +0000847 temp_str = _PyUnicode_AsStringAndSize(temp, &len);
Alexander Belopolskye239d232010-12-08 23:31:48 +0000848 if (temp_str == NULL) {
849 Py_DECREF(temp);
850 Py_XDECREF(elem);
851 return 0;
852 }
Alexandre Vassalottia85998a2008-05-03 18:24:43 +0000853 strn = (char *)PyObject_MALLOC(len + 1);
Victor Stinner3bd6abd2013-07-12 01:33:59 +0200854 if (strn == NULL) {
855 Py_DECREF(temp);
856 Py_XDECREF(elem);
857 PyErr_NoMemory();
858 return 0;
859 }
860 (void) memcpy(strn, temp_str, len + 1);
Fred Drake0ac9b072000-09-12 21:58:06 +0000861 Py_DECREF(temp);
Fred Drakeff9ea482000-04-19 13:54:15 +0000862 }
863 else if (!ISNONTERMINAL(type)) {
864 /*
865 * It has to be one or the other; this is an error.
Andrew Svetlov737fb892012-12-18 21:14:22 +0200866 * Raise an exception.
Fred Drakeff9ea482000-04-19 13:54:15 +0000867 */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000868 PyObject *err = Py_BuildValue("os", elem, "unknown node type.");
869 PyErr_SetObject(parser_error, err);
870 Py_XDECREF(err);
Fred Drakeff9ea482000-04-19 13:54:15 +0000871 Py_XDECREF(elem);
872 return (0);
873 }
Martin v. Löwis49c5da12006-03-01 22:49:05 +0000874 err = PyNode_AddChild(root, type, strn, *line_num, 0);
Fred Drake8b55b2d2001-12-05 22:10:44 +0000875 if (err == E_NOMEM) {
Neal Norwitz2cde0eb2007-08-11 04:58:43 +0000876 Py_XDECREF(elem);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000877 PyObject_FREE(strn);
Fred Drake8b55b2d2001-12-05 22:10:44 +0000878 return (node *) PyErr_NoMemory();
879 }
880 if (err == E_OVERFLOW) {
Neal Norwitz2cde0eb2007-08-11 04:58:43 +0000881 Py_XDECREF(elem);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000882 PyObject_FREE(strn);
Fred Drake8b55b2d2001-12-05 22:10:44 +0000883 PyErr_SetString(PyExc_ValueError,
884 "unsupported number of child nodes");
885 return NULL;
886 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000887
Fred Drakeff9ea482000-04-19 13:54:15 +0000888 if (ISNONTERMINAL(type)) {
889 node* new_child = CHILD(root, i - 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000890
Fred Drakeff9ea482000-04-19 13:54:15 +0000891 if (new_child != build_node_children(elem, new_child, line_num)) {
892 Py_XDECREF(elem);
893 return (0);
894 }
895 }
896 else if (type == NEWLINE) { /* It's true: we increment the */
897 ++(*line_num); /* line number *after* the newline! */
898 }
899 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000900 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000901 return root;
Fred Drakeff9ea482000-04-19 13:54:15 +0000902}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000903
904
905static node*
Fred Drakeff9ea482000-04-19 13:54:15 +0000906build_node_tree(PyObject *tuple)
Guido van Rossum47478871996-08-21 14:32:37 +0000907{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000908 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000909 PyObject *temp = PySequence_GetItem(tuple, 0);
Fred Drake0ac9b072000-09-12 21:58:06 +0000910 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000911
Guido van Rossum47478871996-08-21 14:32:37 +0000912 if (temp != NULL)
Christian Heimes217cfd12007-12-02 14:31:20 +0000913 num = PyLong_AsLong(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000914 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000915 if (ISTERMINAL(num)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000916 /*
917 * The tuple is simple, but it doesn't start with a start symbol.
Andrew Svetlov737fb892012-12-18 21:14:22 +0200918 * Raise an exception now and be done with it.
Fred Drakeff9ea482000-04-19 13:54:15 +0000919 */
Victor Stinner6684bdf2013-07-17 00:13:52 +0200920 tuple = Py_BuildValue("Os", tuple,
Fred Drakec2683dd2001-07-17 19:32:05 +0000921 "Illegal syntax-tree; cannot start with terminal symbol.");
Fred Drakeff9ea482000-04-19 13:54:15 +0000922 PyErr_SetObject(parser_error, tuple);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000923 Py_XDECREF(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000924 }
925 else if (ISNONTERMINAL(num)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000926 /*
927 * Not efficient, but that can be handled later.
928 */
929 int line_num = 0;
Michael W. Hudsondf1252d2003-02-08 18:05:10 +0000930 PyObject *encoding = NULL;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000931
Michael W. Hudsondf1252d2003-02-08 18:05:10 +0000932 if (num == encoding_decl) {
933 encoding = PySequence_GetItem(tuple, 2);
934 /* tuple isn't borrowed anymore here, need to DECREF */
935 tuple = PySequence_GetSlice(tuple, 0, 2);
Alexander Belopolskye239d232010-12-08 23:31:48 +0000936 if (tuple == NULL)
937 return NULL;
Michael W. Hudsondf1252d2003-02-08 18:05:10 +0000938 }
Fred Drakeff9ea482000-04-19 13:54:15 +0000939 res = PyNode_New(num);
Fred Drake8b55b2d2001-12-05 22:10:44 +0000940 if (res != NULL) {
941 if (res != build_node_children(tuple, res, &line_num)) {
942 PyNode_Free(res);
943 res = NULL;
944 }
Michael W. Hudsondf1252d2003-02-08 18:05:10 +0000945 if (res && encoding) {
Martin v. Löwisad0a4622006-02-16 14:30:23 +0000946 Py_ssize_t len;
Neal Norwitz3fcbea52007-08-26 04:51:28 +0000947 const char *temp;
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +0000948 temp = _PyUnicode_AsStringAndSize(encoding, &len);
Alexander Belopolskye239d232010-12-08 23:31:48 +0000949 if (temp == NULL) {
950 Py_DECREF(res);
951 Py_DECREF(encoding);
952 Py_DECREF(tuple);
953 return NULL;
954 }
Alexandre Vassalottia85998a2008-05-03 18:24:43 +0000955 res->n_str = (char *)PyObject_MALLOC(len + 1);
Victor Stinner3bd6abd2013-07-12 01:33:59 +0200956 if (res->n_str == NULL) {
957 Py_DECREF(res);
958 Py_DECREF(encoding);
959 Py_DECREF(tuple);
960 PyErr_NoMemory();
961 return NULL;
962 }
963 (void) memcpy(res->n_str, temp, len + 1);
Michael W. Hudsondf1252d2003-02-08 18:05:10 +0000964 Py_DECREF(encoding);
965 Py_DECREF(tuple);
966 }
Fred Drakeff9ea482000-04-19 13:54:15 +0000967 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000968 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000969 else {
Fred Drakeff9ea482000-04-19 13:54:15 +0000970 /* The tuple is illegal -- if the number is neither TERMINAL nor
Fred Drake0ac9b072000-09-12 21:58:06 +0000971 * NONTERMINAL, we can't use it. Not sure the implementation
972 * allows this condition, but the API doesn't preclude it.
Fred Drakeff9ea482000-04-19 13:54:15 +0000973 */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000974 PyObject *err = Py_BuildValue("os", tuple,
975 "Illegal component tuple.");
976 PyErr_SetObject(parser_error, err);
977 Py_XDECREF(err);
978 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000979
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000980 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000981}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000982
983
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000984/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000985 * Validation routines used within the validation section:
986 */
Jeremy Hylton938ace62002-07-17 16:30:39 +0000987static int validate_terminal(node *terminal, int type, char *string);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000988
Fred Drakeff9ea482000-04-19 13:54:15 +0000989#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
990#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
991#define validate_colon(ch) validate_terminal(ch, COLON, ":")
992#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
993#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
994#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
995#define validate_indent(ch) validate_terminal(ch, INDENT, (char*)NULL)
996#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
997#define validate_newline(ch) validate_terminal(ch, NEWLINE, (char*)NULL)
998#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
999#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
1000#define validate_star(ch) validate_terminal(ch, STAR, "*")
1001#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
1002#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
1003#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Anthony Baxterc2a5a632004-08-02 06:10:11 +00001004#define validate_at(ch) validate_terminal(ch, AT, "@")
Mark Dickinsonea7e9f92012-04-29 18:34:40 +01001005#define validate_rarrow(ch) validate_terminal(ch, RARROW, "->")
Fred Drakeff9ea482000-04-19 13:54:15 +00001006#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001007
Fred Drake0ac9b072000-09-12 21:58:06 +00001008#define VALIDATER(n) static int validate_##n(node *tree)
1009
Fred Drakeff9ea482000-04-19 13:54:15 +00001010VALIDATER(node); VALIDATER(small_stmt);
1011VALIDATER(class); VALIDATER(node);
1012VALIDATER(parameters); VALIDATER(suite);
1013VALIDATER(testlist); VALIDATER(varargslist);
Guido van Rossumfc158e22007-11-15 19:17:28 +00001014VALIDATER(vfpdef);
Fred Drakeff9ea482000-04-19 13:54:15 +00001015VALIDATER(stmt); VALIDATER(simple_stmt);
1016VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossum452bf512007-02-09 05:32:43 +00001017VALIDATER(del_stmt);
Nick Coghlan650f0d02007-04-15 12:05:43 +00001018VALIDATER(return_stmt); VALIDATER(raise_stmt);
1019VALIDATER(import_stmt); VALIDATER(import_stmt);
1020VALIDATER(import_name); VALIDATER(yield_stmt);
Mark Dickinson407b3bd2012-04-29 22:18:31 +01001021VALIDATER(global_stmt); VALIDATER(nonlocal_stmt);
1022VALIDATER(assert_stmt);
Benjamin Peterson4905e802009-09-27 02:43:28 +00001023VALIDATER(compound_stmt); VALIDATER(test_or_star_expr);
Fred Drakeff9ea482000-04-19 13:54:15 +00001024VALIDATER(while); VALIDATER(for);
1025VALIDATER(try); VALIDATER(except_clause);
1026VALIDATER(test); VALIDATER(and_test);
1027VALIDATER(not_test); VALIDATER(comparison);
Guido van Rossumfc158e22007-11-15 19:17:28 +00001028VALIDATER(comp_op);
Guido van Rossum0368b722007-05-11 16:50:42 +00001029VALIDATER(star_expr); VALIDATER(expr);
Fred Drakeff9ea482000-04-19 13:54:15 +00001030VALIDATER(xor_expr); VALIDATER(and_expr);
1031VALIDATER(shift_expr); VALIDATER(arith_expr);
1032VALIDATER(term); VALIDATER(factor);
1033VALIDATER(atom); VALIDATER(lambdef);
1034VALIDATER(trailer); VALIDATER(subscript);
1035VALIDATER(subscriptlist); VALIDATER(sliceop);
Nick Coghlan650f0d02007-04-15 12:05:43 +00001036VALIDATER(exprlist); VALIDATER(dictorsetmaker);
Fred Drakeff9ea482000-04-19 13:54:15 +00001037VALIDATER(arglist); VALIDATER(argument);
Benjamin Peterson4905e802009-09-27 02:43:28 +00001038VALIDATER(comp_for);
Nick Coghlan650f0d02007-04-15 12:05:43 +00001039VALIDATER(comp_iter); VALIDATER(comp_if);
1040VALIDATER(testlist_comp); VALIDATER(yield_expr);
Benjamin Peterson4905e802009-09-27 02:43:28 +00001041VALIDATER(or_test);
Nick Coghlan650f0d02007-04-15 12:05:43 +00001042VALIDATER(test_nocond); VALIDATER(lambdef_nocond);
Nick Coghlan1f7ce622012-01-13 21:43:40 +10001043VALIDATER(yield_arg);
Yury Selivanov75445082015-05-11 22:57:16 -04001044VALIDATER(async_funcdef); VALIDATER(async_stmt);
1045VALIDATER(atom_expr);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001046
Fred Drake0ac9b072000-09-12 21:58:06 +00001047#undef VALIDATER
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001048
Fred Drakeff9ea482000-04-19 13:54:15 +00001049#define is_even(n) (((n) & 1) == 0)
1050#define is_odd(n) (((n) & 1) == 1)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001051
1052
1053static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001054validate_ntype(node *n, int t)
Guido van Rossum47478871996-08-21 14:32:37 +00001055{
Fred Drake0ac9b072000-09-12 21:58:06 +00001056 if (TYPE(n) != t) {
1057 PyErr_Format(parser_error, "Expected node type %d, got %d.",
1058 t, TYPE(n));
1059 return 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001060 }
Fred Drake0ac9b072000-09-12 21:58:06 +00001061 return 1;
Fred Drakeff9ea482000-04-19 13:54:15 +00001062}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001063
1064
Fred Drakee7ab64e2000-04-25 04:14:46 +00001065/* Verifies that the number of child nodes is exactly 'num', raising
1066 * an exception if it isn't. The exception message does not indicate
1067 * the exact number of nodes, allowing this to be used to raise the
1068 * "right" exception when the wrong number of nodes is present in a
1069 * specific variant of a statement's syntax. This is commonly used
1070 * in that fashion.
1071 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001072static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001073validate_numnodes(node *n, int num, const char *const name)
Guido van Rossum47478871996-08-21 14:32:37 +00001074{
Guido van Rossum3d602e31996-07-21 02:33:56 +00001075 if (NCH(n) != num) {
Fred Drake0ac9b072000-09-12 21:58:06 +00001076 PyErr_Format(parser_error,
1077 "Illegal number of children for %s node.", name);
1078 return 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001079 }
Fred Drake0ac9b072000-09-12 21:58:06 +00001080 return 1;
Fred Drakeff9ea482000-04-19 13:54:15 +00001081}
Guido van Rossum3d602e31996-07-21 02:33:56 +00001082
1083
1084static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001085validate_terminal(node *terminal, int type, char *string)
Guido van Rossum47478871996-08-21 14:32:37 +00001086{
Guido van Rossum3d602e31996-07-21 02:33:56 +00001087 int res = (validate_ntype(terminal, type)
Fred Drakeff9ea482000-04-19 13:54:15 +00001088 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001089
1090 if (!res && !PyErr_Occurred()) {
Fred Drake0ac9b072000-09-12 21:58:06 +00001091 PyErr_Format(parser_error,
1092 "Illegal terminal: expected \"%s\"", string);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001093 }
1094 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001095}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001096
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001097/* X (',' X) [','] */
Guido van Rossum47478871996-08-21 14:32:37 +00001098static int
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001099validate_repeating_list_variable(node *tree,
1100 int list_node_type,
1101 int (*validate_child_func_inc)(node *, int *),
1102 int *pos,
1103 const char *const list_node_type_name)
Guido van Rossum47478871996-08-21 14:32:37 +00001104{
1105 int nch = NCH(tree);
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001106 int res = (nch && validate_ntype(tree, list_node_type));
Guido van Rossum47478871996-08-21 14:32:37 +00001107
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001108 if (!res && !PyErr_Occurred()) {
1109 /* Unconditionally raise. */
1110 (void) validate_numnodes(tree, 1, list_node_type_name);
1111 }
Guido van Rossum47478871996-08-21 14:32:37 +00001112 else {
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001113 for ( ; res && *pos < nch; ) {
1114 res = validate_child_func_inc(tree, pos);
1115 if (!res || *pos >= nch)
1116 break;
1117 res = validate_comma(CHILD(tree, (*pos)++));
Fred Drakeff9ea482000-04-19 13:54:15 +00001118 }
Guido van Rossum47478871996-08-21 14:32:37 +00001119 }
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04001120 return res;
1121}
1122
1123/* X (',' X) [','] */
1124static int
1125validate_repeating_list(node *tree,
1126 int list_node_type,
1127 int (*validate_child_func)(node *),
1128 const char *const list_node_type_name)
1129{
1130 int nch = NCH(tree);
1131 int res = (nch && validate_ntype(tree, list_node_type));
1132 int pos = 0;
1133
1134 if (!res && !PyErr_Occurred()) {
1135 /* Unconditionally raise. */
1136 (void) validate_numnodes(tree, 1, list_node_type_name);
1137 }
1138 else {
1139 for ( ; res && pos < nch; ) {
1140 res = validate_child_func(CHILD(tree, pos++));
1141 if (!res || pos >= nch)
1142 break;
1143 res = validate_comma(CHILD(tree, pos++));
1144 }
1145 }
1146 return res;
Fred Drakeff9ea482000-04-19 13:54:15 +00001147}
Guido van Rossum47478871996-08-21 14:32:37 +00001148
1149
Fred Drakecff283c2000-08-21 22:24:43 +00001150/* validate_class()
Guido van Rossum3d602e31996-07-21 02:33:56 +00001151 *
1152 * classdef:
Fred Drakeff9ea482000-04-19 13:54:15 +00001153 * 'class' NAME ['(' testlist ')'] ':' suite
Guido van Rossum3d602e31996-07-21 02:33:56 +00001154 */
Guido van Rossum47478871996-08-21 14:32:37 +00001155static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001156validate_class(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001157{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001158 int nch = NCH(tree);
Brett Cannonf4189912005-04-09 02:30:16 +00001159 int res = (validate_ntype(tree, classdef) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 ((nch == 4) || (nch == 6) || (nch == 7)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001161
Guido van Rossum3d602e31996-07-21 02:33:56 +00001162 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001163 res = (validate_name(CHILD(tree, 0), "class")
1164 && validate_ntype(CHILD(tree, 1), NAME)
1165 && validate_colon(CHILD(tree, nch - 2))
1166 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001167 }
Brett Cannonf4189912005-04-09 02:30:16 +00001168 else {
Fred Drakeff9ea482000-04-19 13:54:15 +00001169 (void) validate_numnodes(tree, 4, "class");
Brett Cannonf4189912005-04-09 02:30:16 +00001170 }
Guido van Rossumfc158e22007-11-15 19:17:28 +00001171
Brett Cannonf4189912005-04-09 02:30:16 +00001172 if (res) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 if (nch == 7) {
1174 res = ((validate_lparen(CHILD(tree, 2)) &&
1175 validate_arglist(CHILD(tree, 3)) &&
1176 validate_rparen(CHILD(tree, 4))));
1177 }
1178 else if (nch == 6) {
1179 res = (validate_lparen(CHILD(tree,2)) &&
1180 validate_rparen(CHILD(tree,3)));
1181 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001182 }
1183 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001184}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001185
1186
Guido van Rossum3d602e31996-07-21 02:33:56 +00001187/* if_stmt:
Fred Drakeff9ea482000-04-19 13:54:15 +00001188 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001189 */
Guido van Rossum47478871996-08-21 14:32:37 +00001190static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001191validate_if(node *tree)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001192{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001193 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001194 int res = (validate_ntype(tree, if_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001195 && (nch >= 4)
1196 && validate_name(CHILD(tree, 0), "if")
1197 && validate_test(CHILD(tree, 1))
1198 && validate_colon(CHILD(tree, 2))
1199 && validate_suite(CHILD(tree, 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001200
1201 if (res && ((nch % 4) == 3)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001202 /* ... 'else' ':' suite */
1203 res = (validate_name(CHILD(tree, nch - 3), "else")
1204 && validate_colon(CHILD(tree, nch - 2))
1205 && validate_suite(CHILD(tree, nch - 1)));
1206 nch -= 3;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001207 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001208 else if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00001209 (void) validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001210 if ((nch % 4) != 0)
Fred Drakeff9ea482000-04-19 13:54:15 +00001211 /* Will catch the case for nch < 4 */
1212 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001213 else if (res && (nch > 4)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001214 /* ... ('elif' test ':' suite)+ ... */
1215 int j = 4;
1216 while ((j < nch) && res) {
1217 res = (validate_name(CHILD(tree, j), "elif")
1218 && validate_colon(CHILD(tree, j + 2))
1219 && validate_test(CHILD(tree, j + 1))
1220 && validate_suite(CHILD(tree, j + 3)));
1221 j += 4;
1222 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001223 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001224 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001225}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001226
1227
Guido van Rossum3d602e31996-07-21 02:33:56 +00001228/* parameters:
Fred Drakeff9ea482000-04-19 13:54:15 +00001229 * '(' [varargslist] ')'
Guido van Rossum3d602e31996-07-21 02:33:56 +00001230 *
1231 */
Guido van Rossum47478871996-08-21 14:32:37 +00001232static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001233validate_parameters(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001234{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001235 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001236 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001237
Guido van Rossum3d602e31996-07-21 02:33:56 +00001238 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001239 res = (validate_lparen(CHILD(tree, 0))
1240 && validate_rparen(CHILD(tree, nch - 1)));
1241 if (res && (nch == 3))
1242 res = validate_varargslist(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001243 }
Fred Drakeff9ea482000-04-19 13:54:15 +00001244 else {
1245 (void) validate_numnodes(tree, 2, "parameters");
1246 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001247 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001248}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001249
1250
Fred Drakecff283c2000-08-21 22:24:43 +00001251/* validate_suite()
Guido van Rossum3d602e31996-07-21 02:33:56 +00001252 *
1253 * suite:
Fred Drakeff9ea482000-04-19 13:54:15 +00001254 * simple_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00001255 * | NEWLINE INDENT stmt+ DEDENT
1256 */
Guido van Rossum47478871996-08-21 14:32:37 +00001257static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001258validate_suite(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001259{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001260 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001261 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001262
Guido van Rossum3d602e31996-07-21 02:33:56 +00001263 if (res && (nch == 1))
Fred Drakeff9ea482000-04-19 13:54:15 +00001264 res = validate_simple_stmt(CHILD(tree, 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001265 else if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001266 /* NEWLINE INDENT stmt+ DEDENT */
1267 res = (validate_newline(CHILD(tree, 0))
1268 && validate_indent(CHILD(tree, 1))
1269 && validate_stmt(CHILD(tree, 2))
1270 && validate_dedent(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001271
Fred Drakeff9ea482000-04-19 13:54:15 +00001272 if (res && (nch > 4)) {
1273 int i = 3;
1274 --nch; /* forget the DEDENT */
1275 for ( ; res && (i < nch); ++i)
1276 res = validate_stmt(CHILD(tree, i));
1277 }
1278 else if (nch < 4)
1279 res = validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001280 }
1281 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001282}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001283
1284
Guido van Rossum47478871996-08-21 14:32:37 +00001285static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001286validate_testlist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001287{
Guido van Rossum47478871996-08-21 14:32:37 +00001288 return (validate_repeating_list(tree, testlist,
Fred Drakeff9ea482000-04-19 13:54:15 +00001289 validate_test, "testlist"));
1290}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001291
Guido van Rossum1c917072001-10-15 15:44:05 +00001292static int
Benjamin Peterson4905e802009-09-27 02:43:28 +00001293validate_testlist_star_expr(node *tl)
Guido van Rossum2d3b9862002-05-24 15:47:06 +00001294{
Benjamin Peterson4905e802009-09-27 02:43:28 +00001295 return (validate_repeating_list(tl, testlist_star_expr, validate_test_or_star_expr,
1296 "testlist"));
Guido van Rossum2d3b9862002-05-24 15:47:06 +00001297}
1298
1299
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001300/* validate either vfpdef or tfpdef.
1301 * vfpdef: NAME
1302 * tfpdef: NAME [':' test]
Neal Norwitzc1505362006-12-28 06:47:50 +00001303 */
1304static int
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001305validate_vfpdef(node *tree)
Neal Norwitzc1505362006-12-28 06:47:50 +00001306{
1307 int nch = NCH(tree);
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001308 if (TYPE(tree) == vfpdef) {
Neal Norwitzc1505362006-12-28 06:47:50 +00001309 return nch == 1 && validate_name(CHILD(tree, 0), NULL);
1310 }
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001311 else if (TYPE(tree) == tfpdef) {
Neal Norwitzc1505362006-12-28 06:47:50 +00001312 if (nch == 1) {
1313 return validate_name(CHILD(tree, 0), NULL);
1314 }
1315 else if (nch == 3) {
1316 return validate_name(CHILD(tree, 0), NULL) &&
1317 validate_colon(CHILD(tree, 1)) &&
1318 validate_test(CHILD(tree, 2));
1319 }
1320 }
1321 return 0;
1322}
1323
Mark Dickinsonea7e9f92012-04-29 18:34:40 +01001324/* '*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001325 * ..or tfpdef in place of vfpdef. vfpdef: NAME; tfpdef: NAME [':' test]
Fred Drakecff283c2000-08-21 22:24:43 +00001326 */
1327static int
1328validate_varargslist_trailer(node *tree, int start)
1329{
1330 int nch = NCH(tree);
Mark Dickinsonea7e9f92012-04-29 18:34:40 +01001331 int res = 0;
Fred Drakecff283c2000-08-21 22:24:43 +00001332
1333 if (nch <= start) {
1334 err_string("expected variable argument trailer for varargslist");
1335 return 0;
1336 }
Mark Dickinsonea7e9f92012-04-29 18:34:40 +01001337 if (TYPE(CHILD(tree, start)) == STAR) {
Fred Drakecff283c2000-08-21 22:24:43 +00001338 /*
Mark Dickinsonea7e9f92012-04-29 18:34:40 +01001339 * '*' [vfpdef]
Fred Drakecff283c2000-08-21 22:24:43 +00001340 */
Mark Dickinsonea7e9f92012-04-29 18:34:40 +01001341 res = validate_star(CHILD(tree, start++));
1342 if (res && start < nch && (TYPE(CHILD(tree, start)) == vfpdef ||
1343 TYPE(CHILD(tree, start)) == tfpdef))
1344 res = validate_vfpdef(CHILD(tree, start++));
1345 /*
1346 * (',' vfpdef ['=' test])*
1347 */
1348 while (res && start + 1 < nch && (
1349 TYPE(CHILD(tree, start + 1)) == vfpdef ||
1350 TYPE(CHILD(tree, start + 1)) == tfpdef)) {
1351 res = (validate_comma(CHILD(tree, start++))
1352 && validate_vfpdef(CHILD(tree, start++)));
1353 if (res && start + 1 < nch && TYPE(CHILD(tree, start)) == EQUAL)
1354 res = (validate_equal(CHILD(tree, start++))
1355 && validate_test(CHILD(tree, start++)));
1356 }
1357 /*
1358 * [',' '**' vfpdef]
1359 */
1360 if (res && start + 2 < nch && TYPE(CHILD(tree, start+1)) == DOUBLESTAR)
1361 res = (validate_comma(CHILD(tree, start++))
1362 && validate_doublestar(CHILD(tree, start++))
1363 && validate_vfpdef(CHILD(tree, start++)));
1364 }
1365 else if (TYPE(CHILD(tree, start)) == DOUBLESTAR) {
1366 /*
1367 * '**' vfpdef
1368 */
1369 if (start + 1 < nch)
1370 res = (validate_doublestar(CHILD(tree, start++))
1371 && validate_vfpdef(CHILD(tree, start++)));
Guido van Rossum4f72a782006-10-27 23:31:49 +00001372 else {
Mark Dickinsonea7e9f92012-04-29 18:34:40 +01001373 res = 0;
1374 err_string("expected vfpdef after ** in varargslist trailer");
Guido van Rossum4f72a782006-10-27 23:31:49 +00001375 }
Fred Drakecff283c2000-08-21 22:24:43 +00001376 }
Mark Dickinsonea7e9f92012-04-29 18:34:40 +01001377 else {
1378 res = 0;
1379 err_string("expected * or ** in varargslist trailer");
Fred Drakecff283c2000-08-21 22:24:43 +00001380 }
Mark Dickinsonea7e9f92012-04-29 18:34:40 +01001381
1382 if (res && start != nch) {
1383 res = 0;
1384 err_string("unexpected extra children in varargslist trailer");
1385 }
Fred Drakecff283c2000-08-21 22:24:43 +00001386 return res;
1387}
1388
1389
Neal Norwitzc1505362006-12-28 06:47:50 +00001390/* validate_varargslist()
Guido van Rossum3d602e31996-07-21 02:33:56 +00001391 *
Neal Norwitzc1505362006-12-28 06:47:50 +00001392 * Validate typedargslist or varargslist.
1393 *
1394 * typedargslist: ((tfpdef ['=' test] ',')*
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001395 * ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] |
1396 * '**' tfpdef)
Neal Norwitzc1505362006-12-28 06:47:50 +00001397 * | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001398 * tfpdef: NAME [':' test]
Neal Norwitzc1505362006-12-28 06:47:50 +00001399 * varargslist: ((vfpdef ['=' test] ',')*
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001400 * ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] |
1401 * '**' vfpdef)
Neal Norwitzc1505362006-12-28 06:47:50 +00001402 * | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001403 * vfpdef: NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00001404 *
1405 */
Guido van Rossum47478871996-08-21 14:32:37 +00001406static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001407validate_varargslist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001408{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001409 int nch = NCH(tree);
Neal Norwitzc1505362006-12-28 06:47:50 +00001410 int res = (TYPE(tree) == varargslist ||
1411 TYPE(tree) == typedargslist) &&
1412 (nch != 0);
Fred Drakecff283c2000-08-21 22:24:43 +00001413 int sym;
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001414 node *ch;
1415 int i = 0;
Guido van Rossumfc158e22007-11-15 19:17:28 +00001416
Fred Drakeb6429a22000-12-11 22:08:27 +00001417 if (!res)
1418 return 0;
Fred Drakecff283c2000-08-21 22:24:43 +00001419 if (nch < 1) {
1420 err_string("varargslist missing child nodes");
1421 return 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001422 }
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001423 while (i < nch) {
Guido van Rossumfc158e22007-11-15 19:17:28 +00001424 ch = CHILD(tree, i);
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001425 sym = TYPE(ch);
1426 if (sym == vfpdef || sym == tfpdef) {
1427 /* validate (vfpdef ['=' test] ',')+ */
1428 res = validate_vfpdef(ch);
Fred Drakecff283c2000-08-21 22:24:43 +00001429 ++i;
Fred Drakeb6429a22000-12-11 22:08:27 +00001430 if (res && (i+2 <= nch) && TYPE(CHILD(tree, i)) == EQUAL) {
1431 res = (validate_equal(CHILD(tree, i))
1432 && validate_test(CHILD(tree, i+1)));
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001433 if (res)
1434 i += 2;
Fred Drakecff283c2000-08-21 22:24:43 +00001435 }
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001436 if (res && i < nch) {
1437 res = validate_comma(CHILD(tree, i));
1438 ++i;
Fred Drakecff283c2000-08-21 22:24:43 +00001439 }
Guido van Rossum1bc535d2007-05-15 18:46:22 +00001440 } else if (sym == DOUBLESTAR || sym == STAR) {
1441 res = validate_varargslist_trailer(tree, i);
1442 break;
1443 } else {
1444 res = 0;
1445 err_string("illegal formation for varargslist");
Fred Drakeff9ea482000-04-19 13:54:15 +00001446 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001447 }
Fred Drakecff283c2000-08-21 22:24:43 +00001448 return res;
Fred Drakeff9ea482000-04-19 13:54:15 +00001449}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001450
1451
Nick Coghlan650f0d02007-04-15 12:05:43 +00001452/* comp_iter: comp_for | comp_if
Fred Drakecff283c2000-08-21 22:24:43 +00001453 */
1454static int
Nick Coghlan650f0d02007-04-15 12:05:43 +00001455validate_comp_iter(node *tree)
Fred Drakecff283c2000-08-21 22:24:43 +00001456{
Nick Coghlan650f0d02007-04-15 12:05:43 +00001457 int res = (validate_ntype(tree, comp_iter)
1458 && validate_numnodes(tree, 1, "comp_iter"));
1459 if (res && TYPE(CHILD(tree, 0)) == comp_for)
1460 res = validate_comp_for(CHILD(tree, 0));
Fred Drakecff283c2000-08-21 22:24:43 +00001461 else
Nick Coghlan650f0d02007-04-15 12:05:43 +00001462 res = validate_comp_if(CHILD(tree, 0));
Fred Drakecff283c2000-08-21 22:24:43 +00001463
1464 return res;
1465}
1466
Nick Coghlan650f0d02007-04-15 12:05:43 +00001467/* comp_for: 'for' exprlist 'in' test [comp_iter]
Raymond Hettinger354433a2004-05-19 08:20:33 +00001468 */
1469static int
Nick Coghlan650f0d02007-04-15 12:05:43 +00001470validate_comp_for(node *tree)
Fred Drakecff283c2000-08-21 22:24:43 +00001471{
1472 int nch = NCH(tree);
1473 int res;
1474
1475 if (nch == 5)
Nick Coghlan650f0d02007-04-15 12:05:43 +00001476 res = validate_comp_iter(CHILD(tree, 4));
Fred Drakecff283c2000-08-21 22:24:43 +00001477 else
Nick Coghlan650f0d02007-04-15 12:05:43 +00001478 res = validate_numnodes(tree, 4, "comp_for");
Raymond Hettinger354433a2004-05-19 08:20:33 +00001479
1480 if (res)
1481 res = (validate_name(CHILD(tree, 0), "for")
1482 && validate_exprlist(CHILD(tree, 1))
1483 && validate_name(CHILD(tree, 2), "in")
Thomas Wouterse2dd78c2006-02-27 16:25:11 +00001484 && validate_or_test(CHILD(tree, 3)));
Raymond Hettinger354433a2004-05-19 08:20:33 +00001485
1486 return res;
1487}
1488
Nick Coghlan650f0d02007-04-15 12:05:43 +00001489/* comp_if: 'if' test_nocond [comp_iter]
Fred Drakecff283c2000-08-21 22:24:43 +00001490 */
1491static int
Nick Coghlan650f0d02007-04-15 12:05:43 +00001492validate_comp_if(node *tree)
Fred Drakecff283c2000-08-21 22:24:43 +00001493{
1494 int nch = NCH(tree);
1495 int res;
1496
1497 if (nch == 3)
Nick Coghlan650f0d02007-04-15 12:05:43 +00001498 res = validate_comp_iter(CHILD(tree, 2));
Fred Drakecff283c2000-08-21 22:24:43 +00001499 else
Nick Coghlan650f0d02007-04-15 12:05:43 +00001500 res = validate_numnodes(tree, 2, "comp_if");
Fred Drakecff283c2000-08-21 22:24:43 +00001501
1502 if (res)
1503 res = (validate_name(CHILD(tree, 0), "if")
Nick Coghlan650f0d02007-04-15 12:05:43 +00001504 && validate_test_nocond(CHILD(tree, 1)));
Fred Drakecff283c2000-08-21 22:24:43 +00001505
1506 return res;
1507}
1508
1509
Guido van Rossum3d602e31996-07-21 02:33:56 +00001510/* simple_stmt | compound_stmt
1511 *
1512 */
Guido van Rossum47478871996-08-21 14:32:37 +00001513static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001514validate_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001515{
1516 int res = (validate_ntype(tree, stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001517 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001518
Guido van Rossum3d602e31996-07-21 02:33:56 +00001519 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001520 tree = CHILD(tree, 0);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001521
Fred Drakeff9ea482000-04-19 13:54:15 +00001522 if (TYPE(tree) == simple_stmt)
1523 res = validate_simple_stmt(tree);
1524 else
1525 res = validate_compound_stmt(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001526 }
1527 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001528}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001529
1530
Guido van Rossum3d602e31996-07-21 02:33:56 +00001531/* small_stmt (';' small_stmt)* [';'] NEWLINE
1532 *
1533 */
Guido van Rossum47478871996-08-21 14:32:37 +00001534static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001535validate_simple_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001536{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001537 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001538 int res = (validate_ntype(tree, simple_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001539 && (nch >= 2)
1540 && validate_small_stmt(CHILD(tree, 0))
1541 && validate_newline(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001542
Guido van Rossum3d602e31996-07-21 02:33:56 +00001543 if (nch < 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001544 res = validate_numnodes(tree, 2, "simple_stmt");
1545 --nch; /* forget the NEWLINE */
Guido van Rossum3d602e31996-07-21 02:33:56 +00001546 if (res && is_even(nch))
Fred Drakeff9ea482000-04-19 13:54:15 +00001547 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001548 if (res && (nch > 2)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001549 int i;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001550
Fred Drakeff9ea482000-04-19 13:54:15 +00001551 for (i = 1; res && (i < nch); i += 2)
1552 res = (validate_semi(CHILD(tree, i))
1553 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001554 }
1555 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001556}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001557
1558
Guido van Rossum47478871996-08-21 14:32:37 +00001559static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001560validate_small_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001561{
1562 int nch = NCH(tree);
Fred Drake0ac9b072000-09-12 21:58:06 +00001563 int res = validate_numnodes(tree, 1, "small_stmt");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001564
Fred Drake0ac9b072000-09-12 21:58:06 +00001565 if (res) {
1566 int ntype = TYPE(CHILD(tree, 0));
1567
1568 if ( (ntype == expr_stmt)
Fred Drake0ac9b072000-09-12 21:58:06 +00001569 || (ntype == del_stmt)
1570 || (ntype == pass_stmt)
1571 || (ntype == flow_stmt)
1572 || (ntype == import_stmt)
1573 || (ntype == global_stmt)
Mark Dickinson407b3bd2012-04-29 22:18:31 +01001574 || (ntype == nonlocal_stmt)
Georg Brandl7cae87c2006-09-06 06:51:57 +00001575 || (ntype == assert_stmt))
Fred Drake0ac9b072000-09-12 21:58:06 +00001576 res = validate_node(CHILD(tree, 0));
1577 else {
1578 res = 0;
1579 err_string("illegal small_stmt child type");
1580 }
1581 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001582 else if (nch == 1) {
Fred Drake0ac9b072000-09-12 21:58:06 +00001583 res = 0;
1584 PyErr_Format(parser_error,
1585 "Unrecognized child node of small_stmt: %d.",
1586 TYPE(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001587 }
1588 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001589}
Guido van Rossum3d602e31996-07-21 02:33:56 +00001590
1591
1592/* compound_stmt:
Benjamin Peterson4469d0c2008-11-30 22:46:23 +00001593 * if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated
Guido van Rossum3d602e31996-07-21 02:33:56 +00001594 */
Guido van Rossum47478871996-08-21 14:32:37 +00001595static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001596validate_compound_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001597{
1598 int res = (validate_ntype(tree, compound_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001599 && validate_numnodes(tree, 1, "compound_stmt"));
Fred Drake0ac9b072000-09-12 21:58:06 +00001600 int ntype;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001601
1602 if (!res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001603 return (0);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001604
1605 tree = CHILD(tree, 0);
Fred Drake0ac9b072000-09-12 21:58:06 +00001606 ntype = TYPE(tree);
1607 if ( (ntype == if_stmt)
1608 || (ntype == while_stmt)
1609 || (ntype == for_stmt)
1610 || (ntype == try_stmt)
Benjamin Peterson4469d0c2008-11-30 22:46:23 +00001611 || (ntype == with_stmt)
Fred Drake0ac9b072000-09-12 21:58:06 +00001612 || (ntype == funcdef)
Yury Selivanov75445082015-05-11 22:57:16 -04001613 || (ntype == async_stmt)
Guido van Rossumd59da4b2007-05-22 18:11:13 +00001614 || (ntype == classdef)
1615 || (ntype == decorated))
Fred Drakeff9ea482000-04-19 13:54:15 +00001616 res = validate_node(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001617 else {
Fred Drake0ac9b072000-09-12 21:58:06 +00001618 res = 0;
1619 PyErr_Format(parser_error,
1620 "Illegal compound statement type: %d.", TYPE(tree));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001621 }
1622 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001623}
Guido van Rossum3d602e31996-07-21 02:33:56 +00001624
Guido van Rossum47478871996-08-21 14:32:37 +00001625static int
Benjamin Peterson4905e802009-09-27 02:43:28 +00001626validate_yield_or_testlist(node *tree, int tse)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +00001627{
Benjamin Peterson4905e802009-09-27 02:43:28 +00001628 if (TYPE(tree) == yield_expr) {
1629 return validate_yield_expr(tree);
1630 }
1631 else {
1632 if (tse)
1633 return validate_testlist_star_expr(tree);
1634 else
1635 return validate_testlist(tree);
1636 }
Phillip J. Eby0d6615f2005-08-02 00:46:46 +00001637}
1638
1639static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001640validate_expr_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001641{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001642 int j;
1643 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001644 int res = (validate_ntype(tree, expr_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001645 && is_odd(nch)
Benjamin Peterson4905e802009-09-27 02:43:28 +00001646 && validate_testlist_star_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001647
Fred Drake28f739a2000-08-25 22:42:40 +00001648 if (res && nch == 3
1649 && TYPE(CHILD(tree, 1)) == augassign) {
Phillip J. Eby0d6615f2005-08-02 00:46:46 +00001650 res = validate_numnodes(CHILD(tree, 1), 1, "augassign")
Benjamin Peterson4905e802009-09-27 02:43:28 +00001651 && validate_yield_or_testlist(CHILD(tree, 2), 0);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001652
Fred Drake28f739a2000-08-25 22:42:40 +00001653 if (res) {
1654 char *s = STR(CHILD(CHILD(tree, 1), 0));
1655
1656 res = (strcmp(s, "+=") == 0
1657 || strcmp(s, "-=") == 0
1658 || strcmp(s, "*=") == 0
1659 || strcmp(s, "/=") == 0
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +00001660 || strcmp(s, "//=") == 0
Fred Drake28f739a2000-08-25 22:42:40 +00001661 || strcmp(s, "%=") == 0
1662 || strcmp(s, "&=") == 0
1663 || strcmp(s, "|=") == 0
1664 || strcmp(s, "^=") == 0
1665 || strcmp(s, "<<=") == 0
1666 || strcmp(s, ">>=") == 0
1667 || strcmp(s, "**=") == 0);
1668 if (!res)
Ezio Melotti42da6632011-03-15 05:18:48 +02001669 err_string("illegal augmented assignment operator");
Fred Drake28f739a2000-08-25 22:42:40 +00001670 }
1671 }
1672 else {
1673 for (j = 1; res && (j < nch); j += 2)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +00001674 res = validate_equal(CHILD(tree, j))
Benjamin Peterson4905e802009-09-27 02:43:28 +00001675 && validate_yield_or_testlist(CHILD(tree, j + 1), 1);
Fred Drake28f739a2000-08-25 22:42:40 +00001676 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001677 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001678}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001679
1680
Guido van Rossum47478871996-08-21 14:32:37 +00001681static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001682validate_del_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001683{
1684 return (validate_numnodes(tree, 2, "del_stmt")
Fred Drakeff9ea482000-04-19 13:54:15 +00001685 && validate_name(CHILD(tree, 0), "del")
1686 && validate_exprlist(CHILD(tree, 1)));
1687}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001688
1689
Guido van Rossum47478871996-08-21 14:32:37 +00001690static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001691validate_return_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001692{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001693 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001694 int res = (validate_ntype(tree, return_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001695 && ((nch == 1) || (nch == 2))
1696 && validate_name(CHILD(tree, 0), "return"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001697
Guido van Rossum3d602e31996-07-21 02:33:56 +00001698 if (res && (nch == 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00001699 res = validate_testlist(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001700
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001701 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001702}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001703
1704
Mark Dickinsoncf360b92012-05-07 12:01:27 +01001705/*
1706 * raise_stmt:
1707 *
1708 * 'raise' [test ['from' test]]
1709 */
Guido van Rossum47478871996-08-21 14:32:37 +00001710static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001711validate_raise_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001712{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001713 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001714 int res = (validate_ntype(tree, raise_stmt)
Mark Dickinsoncf360b92012-05-07 12:01:27 +01001715 && ((nch == 1) || (nch == 2) || (nch == 4)));
1716
1717 if (!res && !PyErr_Occurred())
1718 (void) validate_numnodes(tree, 2, "raise");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001719
Guido van Rossum3d602e31996-07-21 02:33:56 +00001720 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001721 res = validate_name(CHILD(tree, 0), "raise");
1722 if (res && (nch >= 2))
1723 res = validate_test(CHILD(tree, 1));
Mark Dickinsoncf360b92012-05-07 12:01:27 +01001724 if (res && (nch == 4)) {
1725 res = (validate_name(CHILD(tree, 2), "from")
Fred Drakeff9ea482000-04-19 13:54:15 +00001726 && validate_test(CHILD(tree, 3)));
Fred Drakeff9ea482000-04-19 13:54:15 +00001727 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001728 }
1729 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001730}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001731
1732
Nick Coghlan1f7ce622012-01-13 21:43:40 +10001733/* yield_expr: 'yield' [yield_arg]
Phillip J. Eby0d6615f2005-08-02 00:46:46 +00001734 */
1735static int
1736validate_yield_expr(node *tree)
1737{
1738 int nch = NCH(tree);
Nick Coghlan1f7ce622012-01-13 21:43:40 +10001739 if (nch < 1 || nch > 2)
1740 return 0;
1741 if (!validate_ntype(tree, yield_expr))
1742 return 0;
1743 if (!validate_name(CHILD(tree, 0), "yield"))
1744 return 0;
1745 if (nch == 2) {
1746 if (!validate_yield_arg(CHILD(tree, 1)))
1747 return 0;
1748 }
1749 return 1;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +00001750}
1751
Nick Coghlan1f7ce622012-01-13 21:43:40 +10001752/* yield_arg: 'from' test | testlist
1753 */
1754static int
1755validate_yield_arg(node *tree)
1756{
1757 int nch = NCH(tree);
1758 if (!validate_ntype(tree, yield_arg))
1759 return 0;
1760 switch (nch) {
1761 case 1:
1762 if (!validate_testlist(CHILD(tree, nch - 1)))
1763 return 0;
1764 break;
1765 case 2:
1766 if (!validate_name(CHILD(tree, 0), "from"))
1767 return 0;
1768 if (!validate_test(CHILD(tree, 1)))
1769 return 0;
1770 break;
1771 default:
1772 return 0;
1773 }
1774 return 1;
1775}
Phillip J. Eby0d6615f2005-08-02 00:46:46 +00001776
1777/* yield_stmt: yield_expr
Fred Drake02126f22001-07-17 02:59:15 +00001778 */
1779static int
1780validate_yield_stmt(node *tree)
1781{
1782 return (validate_ntype(tree, yield_stmt)
Phillip J. Eby0d6615f2005-08-02 00:46:46 +00001783 && validate_numnodes(tree, 1, "yield_stmt")
1784 && validate_yield_expr(CHILD(tree, 0)));
Fred Drake02126f22001-07-17 02:59:15 +00001785}
1786
1787
Fred Drakecff283c2000-08-21 22:24:43 +00001788static int
1789validate_import_as_name(node *tree)
1790{
1791 int nch = NCH(tree);
1792 int ok = validate_ntype(tree, import_as_name);
1793
1794 if (ok) {
1795 if (nch == 1)
1796 ok = validate_name(CHILD(tree, 0), NULL);
1797 else if (nch == 3)
1798 ok = (validate_name(CHILD(tree, 0), NULL)
1799 && validate_name(CHILD(tree, 1), "as")
1800 && validate_name(CHILD(tree, 2), NULL));
1801 else
1802 ok = validate_numnodes(tree, 3, "import_as_name");
1803 }
1804 return ok;
1805}
1806
1807
Fred Drake71137082001-01-07 05:59:59 +00001808/* dotted_name: NAME ("." NAME)*
1809 */
1810static int
1811validate_dotted_name(node *tree)
1812{
1813 int nch = NCH(tree);
1814 int res = (validate_ntype(tree, dotted_name)
1815 && is_odd(nch)
1816 && validate_name(CHILD(tree, 0), NULL));
1817 int i;
1818
1819 for (i = 1; res && (i < nch); i += 2) {
1820 res = (validate_dot(CHILD(tree, i))
1821 && validate_name(CHILD(tree, i+1), NULL));
1822 }
1823 return res;
1824}
1825
1826
Fred Drakecff283c2000-08-21 22:24:43 +00001827/* dotted_as_name: dotted_name [NAME NAME]
1828 */
1829static int
1830validate_dotted_as_name(node *tree)
1831{
1832 int nch = NCH(tree);
1833 int res = validate_ntype(tree, dotted_as_name);
1834
1835 if (res) {
1836 if (nch == 1)
Fred Drake71137082001-01-07 05:59:59 +00001837 res = validate_dotted_name(CHILD(tree, 0));
Fred Drakecff283c2000-08-21 22:24:43 +00001838 else if (nch == 3)
Fred Drake71137082001-01-07 05:59:59 +00001839 res = (validate_dotted_name(CHILD(tree, 0))
Fred Drakecff283c2000-08-21 22:24:43 +00001840 && validate_name(CHILD(tree, 1), "as")
1841 && validate_name(CHILD(tree, 2), NULL));
1842 else {
1843 res = 0;
Fred Drake661ea262000-10-24 19:57:45 +00001844 err_string("illegal number of children for dotted_as_name");
Fred Drakecff283c2000-08-21 22:24:43 +00001845 }
1846 }
1847 return res;
1848}
1849
1850
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001851/* dotted_as_name (',' dotted_as_name)* */
1852static int
1853validate_dotted_as_names(node *tree)
1854{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 int nch = NCH(tree);
1856 int res = is_odd(nch) && validate_dotted_as_name(CHILD(tree, 0));
1857 int i;
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001858
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001859 for (i = 1; res && (i < nch); i += 2)
1860 res = (validate_comma(CHILD(tree, i))
1861 && validate_dotted_as_name(CHILD(tree, i + 1)));
1862 return (res);
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001863}
1864
1865
1866/* import_as_name (',' import_as_name)* [','] */
1867static int
1868validate_import_as_names(node *tree)
1869{
1870 int nch = NCH(tree);
1871 int res = validate_import_as_name(CHILD(tree, 0));
1872 int i;
1873
1874 for (i = 1; res && (i + 1 < nch); i += 2)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001875 res = (validate_comma(CHILD(tree, i))
1876 && validate_import_as_name(CHILD(tree, i + 1)));
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001877 return (res);
1878}
1879
1880
1881/* 'import' dotted_as_names */
1882static int
1883validate_import_name(node *tree)
1884{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 return (validate_ntype(tree, import_name)
1886 && validate_numnodes(tree, 2, "import_name")
1887 && validate_name(CHILD(tree, 0), "import")
1888 && validate_dotted_as_names(CHILD(tree, 1)));
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001889}
1890
Mark Dickinsonfeb3b752010-07-04 18:38:57 +00001891/* Helper function to count the number of leading dots (or ellipsis tokens) in
Thomas Woutersf7f438b2006-02-28 16:09:29 +00001892 * 'from ...module import name'
1893 */
1894static int
1895count_from_dots(node *tree)
1896{
Mark Dickinsonfeb3b752010-07-04 18:38:57 +00001897 int i;
1898 for (i = 1; i < NCH(tree); i++)
1899 if (TYPE(CHILD(tree, i)) != DOT && TYPE(CHILD(tree, i)) != ELLIPSIS)
1900 break;
1901 return i - 1;
Thomas Woutersf7f438b2006-02-28 16:09:29 +00001902}
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001903
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +00001904/* import_from: ('from' ('.'* dotted_name | '.'+)
1905 * 'import' ('*' | '(' import_as_names ')' | import_as_names))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001906 */
Guido van Rossum47478871996-08-21 14:32:37 +00001907static int
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001908validate_import_from(node *tree)
1909{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 int nch = NCH(tree);
1911 int ndots = count_from_dots(tree);
1912 int havename = (TYPE(CHILD(tree, ndots + 1)) == dotted_name);
1913 int offset = ndots + havename;
1914 int res = validate_ntype(tree, import_from)
Mark Dickinson2cc8a5e2010-07-04 18:11:51 +00001915 && (offset >= 1)
1916 && (nch >= 3 + offset)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 && validate_name(CHILD(tree, 0), "from")
1918 && (!havename || validate_dotted_name(CHILD(tree, ndots + 1)))
1919 && validate_name(CHILD(tree, offset + 1), "import");
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921 if (res && TYPE(CHILD(tree, offset + 2)) == LPAR)
1922 res = ((nch == offset + 5)
1923 && validate_lparen(CHILD(tree, offset + 2))
1924 && validate_import_as_names(CHILD(tree, offset + 3))
1925 && validate_rparen(CHILD(tree, offset + 4)));
1926 else if (res && TYPE(CHILD(tree, offset + 2)) != STAR)
1927 res = validate_import_as_names(CHILD(tree, offset + 2));
1928 return (res);
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001929}
1930
1931
1932/* import_stmt: import_name | import_from */
1933static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001934validate_import_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001935{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001936 int nch = NCH(tree);
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001937 int res = validate_numnodes(tree, 1, "import_stmt");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001938
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001939 if (res) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 int ntype = TYPE(CHILD(tree, 0));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001941
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001942 if (ntype == import_name || ntype == import_from)
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001943 res = validate_node(CHILD(tree, 0));
Fred Drakeff9ea482000-04-19 13:54:15 +00001944 else {
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001945 res = 0;
1946 err_string("illegal import_stmt child type");
Fred Drakeff9ea482000-04-19 13:54:15 +00001947 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001948 }
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001949 else if (nch == 1) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001950 res = 0;
Anthony Baxter1a4ddae2004-08-31 10:07:13 +00001951 PyErr_Format(parser_error,
1952 "Unrecognized child node of import_stmt: %d.",
1953 TYPE(CHILD(tree, 0)));
1954 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001955 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001956}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001957
1958
Mark Dickinson407b3bd2012-04-29 22:18:31 +01001959/* global_stmt:
1960 *
1961 * 'global' NAME (',' NAME)*
1962 */
Guido van Rossum47478871996-08-21 14:32:37 +00001963static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001964validate_global_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001965{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001966 int j;
1967 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001968 int res = (validate_ntype(tree, global_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001969 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001970
Michael W. Hudsondf1252d2003-02-08 18:05:10 +00001971 if (!res && !PyErr_Occurred())
1972 err_string("illegal global statement");
1973
Guido van Rossum3d602e31996-07-21 02:33:56 +00001974 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001975 res = (validate_name(CHILD(tree, 0), "global")
1976 && validate_ntype(CHILD(tree, 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001977 for (j = 2; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001978 res = (validate_comma(CHILD(tree, j))
1979 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001980
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001981 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001982}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001983
Mark Dickinson407b3bd2012-04-29 22:18:31 +01001984/* nonlocal_stmt:
1985 *
1986 * 'nonlocal' NAME (',' NAME)*
1987 */
1988static int
1989validate_nonlocal_stmt(node *tree)
1990{
1991 int j;
1992 int nch = NCH(tree);
1993 int res = (validate_ntype(tree, nonlocal_stmt)
1994 && is_even(nch) && (nch >= 2));
1995
1996 if (!res && !PyErr_Occurred())
1997 err_string("illegal nonlocal statement");
1998
1999 if (res)
2000 res = (validate_name(CHILD(tree, 0), "nonlocal")
2001 && validate_ntype(CHILD(tree, 1), NAME));
2002 for (j = 2; res && (j < nch); j += 2)
2003 res = (validate_comma(CHILD(tree, j))
2004 && validate_ntype(CHILD(tree, j + 1), NAME));
2005
2006 return res;
2007}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002008
Guido van Rossum925e5471997-04-02 05:32:13 +00002009/* assert_stmt:
2010 *
2011 * 'assert' test [',' test]
2012 */
2013static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002014validate_assert_stmt(node *tree)
Guido van Rossum925e5471997-04-02 05:32:13 +00002015{
2016 int nch = NCH(tree);
2017 int res = (validate_ntype(tree, assert_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00002018 && ((nch == 2) || (nch == 4))
Michael W. Hudsondf1252d2003-02-08 18:05:10 +00002019 && (validate_name(CHILD(tree, 0), "assert"))
Fred Drakeff9ea482000-04-19 13:54:15 +00002020 && validate_test(CHILD(tree, 1)));
Guido van Rossum925e5471997-04-02 05:32:13 +00002021
2022 if (!res && !PyErr_Occurred())
Fred Drake661ea262000-10-24 19:57:45 +00002023 err_string("illegal assert statement");
Guido van Rossum925e5471997-04-02 05:32:13 +00002024 if (res && (nch > 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00002025 res = (validate_comma(CHILD(tree, 2))
2026 && validate_test(CHILD(tree, 3)));
Guido van Rossum925e5471997-04-02 05:32:13 +00002027
2028 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002029}
Guido van Rossum925e5471997-04-02 05:32:13 +00002030
2031
Guido van Rossum47478871996-08-21 14:32:37 +00002032static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002033validate_while(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002034{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002035 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002036 int res = (validate_ntype(tree, while_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00002037 && ((nch == 4) || (nch == 7))
2038 && validate_name(CHILD(tree, 0), "while")
2039 && validate_test(CHILD(tree, 1))
2040 && validate_colon(CHILD(tree, 2))
2041 && validate_suite(CHILD(tree, 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002042
Guido van Rossum3d602e31996-07-21 02:33:56 +00002043 if (res && (nch == 7))
Fred Drakeff9ea482000-04-19 13:54:15 +00002044 res = (validate_name(CHILD(tree, 4), "else")
2045 && validate_colon(CHILD(tree, 5))
2046 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002047
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002048 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002049}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002050
2051
Guido van Rossum47478871996-08-21 14:32:37 +00002052static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002053validate_for(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002054{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002055 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002056 int res = (validate_ntype(tree, for_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00002057 && ((nch == 6) || (nch == 9))
2058 && validate_name(CHILD(tree, 0), "for")
2059 && validate_exprlist(CHILD(tree, 1))
2060 && validate_name(CHILD(tree, 2), "in")
2061 && validate_testlist(CHILD(tree, 3))
2062 && validate_colon(CHILD(tree, 4))
2063 && validate_suite(CHILD(tree, 5)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002064
Guido van Rossum3d602e31996-07-21 02:33:56 +00002065 if (res && (nch == 9))
Fred Drakeff9ea482000-04-19 13:54:15 +00002066 res = (validate_name(CHILD(tree, 6), "else")
2067 && validate_colon(CHILD(tree, 7))
2068 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002069
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002070 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002071}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002072
2073
Guido van Rossum3d602e31996-07-21 02:33:56 +00002074/* try_stmt:
Fred Drakeff9ea482000-04-19 13:54:15 +00002075 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
Georg Brandleee31162008-12-07 15:15:22 +00002076 ['finally' ':' suite]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002077 * | 'try' ':' suite 'finally' ':' suite
2078 *
2079 */
Guido van Rossum47478871996-08-21 14:32:37 +00002080static int
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +00002081validate_try(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002082{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002083 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002084 int pos = 3;
2085 int res = (validate_ntype(tree, try_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00002086 && (nch >= 6) && ((nch % 3) == 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002087
2088 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00002089 res = (validate_name(CHILD(tree, 0), "try")
2090 && validate_colon(CHILD(tree, 1))
2091 && validate_suite(CHILD(tree, 2))
2092 && validate_colon(CHILD(tree, nch - 2))
2093 && validate_suite(CHILD(tree, nch - 1)));
Fred Drake0ac9b072000-09-12 21:58:06 +00002094 else if (!PyErr_Occurred()) {
Fred Drake22269b52000-07-03 18:07:43 +00002095 const char* name = "except";
Fred Drakeff9ea482000-04-19 13:54:15 +00002096 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
2097 name = STR(CHILD(tree, nch - 3));
Fred Drake0ac9b072000-09-12 21:58:06 +00002098
2099 PyErr_Format(parser_error,
2100 "Illegal number of children for try/%s node.", name);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002101 }
Georg Brandleee31162008-12-07 15:15:22 +00002102 /* Handle try/finally statement */
2103 if (res && (TYPE(CHILD(tree, pos)) == NAME) &&
2104 (strcmp(STR(CHILD(tree, pos)), "finally") == 0)) {
2105 res = (validate_numnodes(tree, 6, "try/finally")
2106 && validate_colon(CHILD(tree, 4))
2107 && validate_suite(CHILD(tree, 5)));
2108 return (res);
2109 }
2110 /* try/except statement: skip past except_clause sections */
Antoine Pitrou37d1c182009-05-14 21:54:00 +00002111 while (res && pos < nch && (TYPE(CHILD(tree, pos)) == except_clause)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002112 res = (validate_except_clause(CHILD(tree, pos))
2113 && validate_colon(CHILD(tree, pos + 1))
2114 && validate_suite(CHILD(tree, pos + 2)));
2115 pos += 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002116 }
Georg Brandleee31162008-12-07 15:15:22 +00002117 /* skip else clause */
Antoine Pitrou37d1c182009-05-14 21:54:00 +00002118 if (res && pos < nch && (TYPE(CHILD(tree, pos)) == NAME) &&
Georg Brandleee31162008-12-07 15:15:22 +00002119 (strcmp(STR(CHILD(tree, pos)), "else") == 0)) {
2120 res = (validate_colon(CHILD(tree, pos + 1))
2121 && validate_suite(CHILD(tree, pos + 2)));
2122 pos += 3;
2123 }
2124 if (res && pos < nch) {
2125 /* last clause must be a finally */
2126 res = (validate_name(CHILD(tree, pos), "finally")
2127 && validate_numnodes(tree, pos + 3, "try/except/finally")
2128 && validate_colon(CHILD(tree, pos + 1))
2129 && validate_suite(CHILD(tree, pos + 2)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002130 }
2131 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002132}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002133
2134
Guido van Rossum47478871996-08-21 14:32:37 +00002135static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002136validate_except_clause(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002137{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002138 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002139 int res = (validate_ntype(tree, except_clause)
Fred Drakeff9ea482000-04-19 13:54:15 +00002140 && ((nch == 1) || (nch == 2) || (nch == 4))
2141 && validate_name(CHILD(tree, 0), "except"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002142
Guido van Rossum3d602e31996-07-21 02:33:56 +00002143 if (res && (nch > 1))
Fred Drakeff9ea482000-04-19 13:54:15 +00002144 res = validate_test(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002145 if (res && (nch == 4))
Guido van Rossumb940e112007-01-10 16:19:56 +00002146 res = (validate_name(CHILD(tree, 2), "as")
2147 && validate_ntype(CHILD(tree, 3), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002148
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002149 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002150}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002151
2152
Guido van Rossum47478871996-08-21 14:32:37 +00002153static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002154validate_test(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002155{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002156 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002157 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002158
Guido van Rossum3d602e31996-07-21 02:33:56 +00002159 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Fred Drakeff9ea482000-04-19 13:54:15 +00002160 res = ((nch == 1)
2161 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002162 else if (res) {
Thomas Wouterse2dd78c2006-02-27 16:25:11 +00002163 res = validate_or_test(CHILD(tree, 0));
2164 res = (res && (nch == 1 || (nch == 5 &&
2165 validate_name(CHILD(tree, 1), "if") &&
2166 validate_or_test(CHILD(tree, 2)) &&
2167 validate_name(CHILD(tree, 3), "else") &&
2168 validate_test(CHILD(tree, 4)))));
2169 }
2170 return (res);
2171}
2172
2173static int
Nick Coghlan650f0d02007-04-15 12:05:43 +00002174validate_test_nocond(node *tree)
Thomas Wouterse2dd78c2006-02-27 16:25:11 +00002175{
2176 int nch = NCH(tree);
Nick Coghlan650f0d02007-04-15 12:05:43 +00002177 int res = validate_ntype(tree, test_nocond) && (nch == 1);
Thomas Wouterse2dd78c2006-02-27 16:25:11 +00002178
Nick Coghlan650f0d02007-04-15 12:05:43 +00002179 if (res && (TYPE(CHILD(tree, 0)) == lambdef_nocond))
2180 res = (validate_lambdef_nocond(CHILD(tree, 0)));
Thomas Wouterse2dd78c2006-02-27 16:25:11 +00002181 else if (res) {
2182 res = (validate_or_test(CHILD(tree, 0)));
2183 }
2184 return (res);
2185}
2186
2187static int
2188validate_or_test(node *tree)
2189{
2190 int nch = NCH(tree);
2191 int res = validate_ntype(tree, or_test) && is_odd(nch);
2192
2193 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002194 int pos;
2195 res = validate_and_test(CHILD(tree, 0));
2196 for (pos = 1; res && (pos < nch); pos += 2)
2197 res = (validate_name(CHILD(tree, pos), "or")
2198 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002199 }
2200 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002201}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002202
2203
Guido van Rossum47478871996-08-21 14:32:37 +00002204static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002205validate_and_test(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002206{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002207 int pos;
2208 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002209 int res = (validate_ntype(tree, and_test)
Fred Drakeff9ea482000-04-19 13:54:15 +00002210 && is_odd(nch)
2211 && validate_not_test(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002212
Guido van Rossum3d602e31996-07-21 02:33:56 +00002213 for (pos = 1; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00002214 res = (validate_name(CHILD(tree, pos), "and")
2215 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002216
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002217 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002218}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002219
2220
Guido van Rossum47478871996-08-21 14:32:37 +00002221static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002222validate_not_test(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002223{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002224 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002225 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002226
Guido van Rossum3d602e31996-07-21 02:33:56 +00002227 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002228 if (nch == 2)
2229 res = (validate_name(CHILD(tree, 0), "not")
2230 && validate_not_test(CHILD(tree, 1)));
2231 else if (nch == 1)
2232 res = validate_comparison(CHILD(tree, 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002233 }
2234 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002235}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002236
2237
Guido van Rossum47478871996-08-21 14:32:37 +00002238static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002239validate_comparison(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002240{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002241 int pos;
2242 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002243 int res = (validate_ntype(tree, comparison)
Fred Drakeff9ea482000-04-19 13:54:15 +00002244 && is_odd(nch)
Benjamin Peterson4905e802009-09-27 02:43:28 +00002245 && validate_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002246
Guido van Rossum3d602e31996-07-21 02:33:56 +00002247 for (pos = 1; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00002248 res = (validate_comp_op(CHILD(tree, pos))
Benjamin Peterson4905e802009-09-27 02:43:28 +00002249 && validate_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002250
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002251 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002252}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002253
2254
Guido van Rossum47478871996-08-21 14:32:37 +00002255static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002256validate_comp_op(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002257{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002258 int res = 0;
2259 int nch = NCH(tree);
2260
Guido van Rossum3d602e31996-07-21 02:33:56 +00002261 if (!validate_ntype(tree, comp_op))
Fred Drakeff9ea482000-04-19 13:54:15 +00002262 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002263 if (nch == 1) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002264 /*
2265 * Only child will be a terminal with a well-defined symbolic name
2266 * or a NAME with a string of either 'is' or 'in'
2267 */
2268 tree = CHILD(tree, 0);
2269 switch (TYPE(tree)) {
Nick Coghlan1f7ce622012-01-13 21:43:40 +10002270 case LESS:
2271 case GREATER:
2272 case EQEQUAL:
2273 case EQUAL:
2274 case LESSEQUAL:
2275 case GREATEREQUAL:
2276 case NOTEQUAL:
Fred Drakeff9ea482000-04-19 13:54:15 +00002277 res = 1;
2278 break;
Nick Coghlan1f7ce622012-01-13 21:43:40 +10002279 case NAME:
Fred Drakeff9ea482000-04-19 13:54:15 +00002280 res = ((strcmp(STR(tree), "in") == 0)
2281 || (strcmp(STR(tree), "is") == 0));
2282 if (!res) {
Fred Drake0ac9b072000-09-12 21:58:06 +00002283 PyErr_Format(parser_error,
Fred Drake661ea262000-10-24 19:57:45 +00002284 "illegal operator '%s'", STR(tree));
Fred Drakeff9ea482000-04-19 13:54:15 +00002285 }
2286 break;
2287 default:
Fred Drake661ea262000-10-24 19:57:45 +00002288 err_string("illegal comparison operator type");
Fred Drakeff9ea482000-04-19 13:54:15 +00002289 break;
2290 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002291 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00002292 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002293 res = (validate_ntype(CHILD(tree, 0), NAME)
2294 && validate_ntype(CHILD(tree, 1), NAME)
2295 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
2296 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
2297 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
2298 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
2299 if (!res && !PyErr_Occurred())
Fred Drake661ea262000-10-24 19:57:45 +00002300 err_string("unknown comparison operator");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002301 }
2302 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002303}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002304
2305
Guido van Rossum47478871996-08-21 14:32:37 +00002306static int
Guido van Rossum0368b722007-05-11 16:50:42 +00002307validate_star_expr(node *tree)
2308{
2309 int res = validate_ntype(tree, star_expr);
2310 if (!res) return res;
Benjamin Peterson4905e802009-09-27 02:43:28 +00002311 if (!validate_numnodes(tree, 2, "star_expr"))
2312 return 0;
2313 return validate_ntype(CHILD(tree, 0), STAR) && \
2314 validate_expr(CHILD(tree, 1));
Guido van Rossum0368b722007-05-11 16:50:42 +00002315}
2316
2317
2318static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002319validate_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002320{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002321 int j;
2322 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002323 int res = (validate_ntype(tree, expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00002324 && is_odd(nch)
2325 && validate_xor_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002326
Guido van Rossum3d602e31996-07-21 02:33:56 +00002327 for (j = 2; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00002328 res = (validate_xor_expr(CHILD(tree, j))
2329 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002330
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002331 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002332}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002333
2334
Guido van Rossum47478871996-08-21 14:32:37 +00002335static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002336validate_xor_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002337{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002338 int j;
2339 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002340 int res = (validate_ntype(tree, xor_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00002341 && is_odd(nch)
2342 && validate_and_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002343
Guido van Rossum3d602e31996-07-21 02:33:56 +00002344 for (j = 2; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00002345 res = (validate_circumflex(CHILD(tree, j - 1))
2346 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002347
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002348 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002349}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002350
2351
Guido van Rossum47478871996-08-21 14:32:37 +00002352static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002353validate_and_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002354{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002355 int pos;
2356 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002357 int res = (validate_ntype(tree, and_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00002358 && is_odd(nch)
2359 && validate_shift_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002360
Guido van Rossum3d602e31996-07-21 02:33:56 +00002361 for (pos = 1; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00002362 res = (validate_ampersand(CHILD(tree, pos))
2363 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002364
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002365 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002366}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002367
2368
2369static int
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +00002370validate_chain_two_ops(node *tree, int (*termvalid)(node *), int op1, int op2)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002371 {
2372 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002373 int nch = NCH(tree);
2374 int res = (is_odd(nch)
Fred Drakeff9ea482000-04-19 13:54:15 +00002375 && (*termvalid)(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002376
Guido van Rossum3d602e31996-07-21 02:33:56 +00002377 for ( ; res && (pos < nch); pos += 2) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002378 if (TYPE(CHILD(tree, pos)) != op1)
2379 res = validate_ntype(CHILD(tree, pos), op2);
2380 if (res)
2381 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002382 }
2383 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002384}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002385
2386
Guido van Rossum47478871996-08-21 14:32:37 +00002387static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002388validate_shift_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002389{
2390 return (validate_ntype(tree, shift_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00002391 && validate_chain_two_ops(tree, validate_arith_expr,
2392 LEFTSHIFT, RIGHTSHIFT));
2393}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002394
2395
Guido van Rossum47478871996-08-21 14:32:37 +00002396static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002397validate_arith_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002398{
2399 return (validate_ntype(tree, arith_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00002400 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
2401}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002402
2403
Guido van Rossum47478871996-08-21 14:32:37 +00002404static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002405validate_term(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002406{
2407 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002408 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002409 int res = (validate_ntype(tree, term)
Fred Drakeff9ea482000-04-19 13:54:15 +00002410 && is_odd(nch)
2411 && validate_factor(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002412
Guido van Rossum3d602e31996-07-21 02:33:56 +00002413 for ( ; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00002414 res = (((TYPE(CHILD(tree, pos)) == STAR)
2415 || (TYPE(CHILD(tree, pos)) == SLASH)
Michael W. Hudson5e83b7a2003-01-29 14:20:23 +00002416 || (TYPE(CHILD(tree, pos)) == DOUBLESLASH)
Fred Drakeff9ea482000-04-19 13:54:15 +00002417 || (TYPE(CHILD(tree, pos)) == PERCENT))
2418 && validate_factor(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002419
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002420 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002421}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002422
2423
Guido van Rossum3d602e31996-07-21 02:33:56 +00002424/* factor:
2425 *
2426 * factor: ('+'|'-'|'~') factor | power
2427 */
Guido van Rossum47478871996-08-21 14:32:37 +00002428static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002429validate_factor(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002430{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002431 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002432 int res = (validate_ntype(tree, factor)
Fred Drakeff9ea482000-04-19 13:54:15 +00002433 && (((nch == 2)
2434 && ((TYPE(CHILD(tree, 0)) == PLUS)
2435 || (TYPE(CHILD(tree, 0)) == MINUS)
2436 || (TYPE(CHILD(tree, 0)) == TILDE))
2437 && validate_factor(CHILD(tree, 1)))
2438 || ((nch == 1)
2439 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002440 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002441}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002442
2443
Guido van Rossum3d602e31996-07-21 02:33:56 +00002444/* power:
2445 *
Yury Selivanov75445082015-05-11 22:57:16 -04002446 * power: atom_expr trailer* ['**' factor]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002447 */
Guido van Rossum47478871996-08-21 14:32:37 +00002448static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002449validate_power(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002450{
Guido van Rossum3d602e31996-07-21 02:33:56 +00002451 int nch = NCH(tree);
2452 int res = (validate_ntype(tree, power) && (nch >= 1)
Yury Selivanov75445082015-05-11 22:57:16 -04002453 && validate_atom_expr(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002454
Yury Selivanov75445082015-05-11 22:57:16 -04002455 if (nch > 1) {
2456 if (nch != 3) {
Fred Drake661ea262000-10-24 19:57:45 +00002457 err_string("illegal number of nodes for 'power'");
Fred Drakeff9ea482000-04-19 13:54:15 +00002458 return (0);
2459 }
Yury Selivanov75445082015-05-11 22:57:16 -04002460 res = (validate_doublestar(CHILD(tree, 1))
2461 && validate_factor(CHILD(tree, 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002462 }
Yury Selivanov75445082015-05-11 22:57:16 -04002463
2464 return (res);
2465}
2466
2467
2468/* atom_expr:
2469 *
2470 * atom_expr: [AWAIT] atom trailer*
2471 */
2472static int
2473validate_atom_expr(node *tree)
2474{
2475 int start = 0;
2476 int nch = NCH(tree);
2477 int res;
2478 int pos;
2479
2480 res = validate_ntype(tree, atom_expr) && (nch >= 1);
2481 if (!res) {
2482 return (res);
2483 }
2484
2485 if (TYPE(CHILD(tree, 0)) == AWAIT) {
2486 start = 1;
2487 if (nch < 2) {
2488 err_string("illegal number of nodes for 'atom_expr'");
2489 return (0);
2490 }
2491 }
2492
2493 res = validate_atom(CHILD(tree, start));
2494 if (res) {
2495 pos = start + 1;
2496 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2497 res = validate_trailer(CHILD(tree, pos++));
2498 }
2499
Guido van Rossum3d602e31996-07-21 02:33:56 +00002500 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002501}
Guido van Rossum3d602e31996-07-21 02:33:56 +00002502
2503
Guido van Rossum47478871996-08-21 14:32:37 +00002504static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002505validate_atom(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002506{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002507 int pos;
2508 int nch = NCH(tree);
Fred Drakecff283c2000-08-21 22:24:43 +00002509 int res = validate_ntype(tree, atom);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002510
Fred Drakecff283c2000-08-21 22:24:43 +00002511 if (res && nch < 1)
2512 res = validate_numnodes(tree, nch+1, "atom");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002513 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002514 switch (TYPE(CHILD(tree, 0))) {
2515 case LPAR:
2516 res = ((nch <= 3)
2517 && (validate_rparen(CHILD(tree, nch - 1))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002518
Phillip J. Eby0d6615f2005-08-02 00:46:46 +00002519 if (res && (nch == 3)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002520 if (TYPE(CHILD(tree, 1))==yield_expr)
Yury Selivanov75445082015-05-11 22:57:16 -04002521 res = validate_yield_expr(CHILD(tree, 1));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002522 else
Yury Selivanov75445082015-05-11 22:57:16 -04002523 res = validate_testlist_comp(CHILD(tree, 1));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002524 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002525 break;
2526 case LSQB:
Fred Drakecff283c2000-08-21 22:24:43 +00002527 if (nch == 2)
2528 res = validate_ntype(CHILD(tree, 1), RSQB);
2529 else if (nch == 3)
Nick Coghlan650f0d02007-04-15 12:05:43 +00002530 res = (validate_testlist_comp(CHILD(tree, 1))
Fred Drakecff283c2000-08-21 22:24:43 +00002531 && validate_ntype(CHILD(tree, 2), RSQB));
2532 else {
2533 res = 0;
2534 err_string("illegal list display atom");
2535 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002536 break;
2537 case LBRACE:
2538 res = ((nch <= 3)
2539 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002540
Fred Drakeff9ea482000-04-19 13:54:15 +00002541 if (res && (nch == 3))
Nick Coghlan650f0d02007-04-15 12:05:43 +00002542 res = validate_dictorsetmaker(CHILD(tree, 1));
Fred Drakeff9ea482000-04-19 13:54:15 +00002543 break;
Fred Drakeff9ea482000-04-19 13:54:15 +00002544 case NAME:
2545 case NUMBER:
Mark Dickinsonda029fb2012-05-07 17:24:04 +01002546 case ELLIPSIS:
Fred Drakeff9ea482000-04-19 13:54:15 +00002547 res = (nch == 1);
2548 break;
2549 case STRING:
2550 for (pos = 1; res && (pos < nch); ++pos)
2551 res = validate_ntype(CHILD(tree, pos), STRING);
2552 break;
2553 default:
2554 res = 0;
2555 break;
2556 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002557 }
2558 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002559}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002560
2561
Nick Coghlan650f0d02007-04-15 12:05:43 +00002562/* testlist_comp:
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04002563 * (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
Fred Drake85bf3bb2000-08-23 15:35:26 +00002564 */
Fred Drakecff283c2000-08-21 22:24:43 +00002565static int
Nick Coghlan650f0d02007-04-15 12:05:43 +00002566validate_testlist_comp(node *tree)
Fred Drakecff283c2000-08-21 22:24:43 +00002567{
2568 int nch = NCH(tree);
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04002569 int ok;
Fred Drakecff283c2000-08-21 22:24:43 +00002570
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04002571 if (nch == 0) {
Nick Coghlan650f0d02007-04-15 12:05:43 +00002572 err_string("missing child nodes of testlist_comp");
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04002573 return 0;
Nick Coghlan650f0d02007-04-15 12:05:43 +00002574 }
Fred Drakecff283c2000-08-21 22:24:43 +00002575
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04002576 if (nch == 2 && TYPE(CHILD(tree, 1)) == comp_for) {
2577 ok = (validate_test(CHILD(tree, 0))
2578 && validate_comp_for(CHILD(tree, 1)));
2579 }
Fred Drakecff283c2000-08-21 22:24:43 +00002580 else {
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04002581 ok = validate_repeating_list(tree,
2582 testlist_comp,
2583 validate_test_or_star_expr,
2584 "testlist_comp");
Raymond Hettinger354433a2004-05-19 08:20:33 +00002585 }
2586 return ok;
2587}
Fred Drakecff283c2000-08-21 22:24:43 +00002588
Anthony Baxterc2a5a632004-08-02 06:10:11 +00002589/* decorator:
Michael W. Hudson0ccff072004-08-17 17:29:16 +00002590 * '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
Anthony Baxterc2a5a632004-08-02 06:10:11 +00002591 */
2592static int
2593validate_decorator(node *tree)
2594{
2595 int ok;
2596 int nch = NCH(tree);
2597 ok = (validate_ntype(tree, decorator) &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002598 (nch == 3 || nch == 5 || nch == 6) &&
2599 validate_at(CHILD(tree, 0)) &&
2600 validate_dotted_name(CHILD(tree, 1)) &&
2601 validate_newline(RCHILD(tree, -1)));
Anthony Baxterc2a5a632004-08-02 06:10:11 +00002602
Michael W. Hudson0ccff072004-08-17 17:29:16 +00002603 if (ok && nch != 3) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002604 ok = (validate_lparen(CHILD(tree, 2)) &&
2605 validate_rparen(RCHILD(tree, -2)));
Anthony Baxterc2a5a632004-08-02 06:10:11 +00002606
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002607 if (ok && nch == 6)
2608 ok = validate_arglist(CHILD(tree, 3));
Anthony Baxterc2a5a632004-08-02 06:10:11 +00002609 }
2610
2611 return ok;
2612}
Michael W. Hudson0ccff072004-08-17 17:29:16 +00002613
Anthony Baxterc2a5a632004-08-02 06:10:11 +00002614/* decorators:
Michael W. Hudson0ccff072004-08-17 17:29:16 +00002615 * decorator+
Anthony Baxterc2a5a632004-08-02 06:10:11 +00002616 */
2617static int
2618validate_decorators(node *tree)
2619{
Guido van Rossumfc158e22007-11-15 19:17:28 +00002620 int i, nch, ok;
Anthony Baxterc2a5a632004-08-02 06:10:11 +00002621 nch = NCH(tree);
Michael W. Hudson0ccff072004-08-17 17:29:16 +00002622 ok = validate_ntype(tree, decorators) && nch >= 1;
Anthony Baxterc2a5a632004-08-02 06:10:11 +00002623
Michael W. Hudson0ccff072004-08-17 17:29:16 +00002624 for (i = 0; ok && i < nch; ++i)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002625 ok = validate_decorator(CHILD(tree, i));
Anthony Baxterc2a5a632004-08-02 06:10:11 +00002626
2627 return ok;
Michael W. Hudson0ccff072004-08-17 17:29:16 +00002628}
Anthony Baxterc2a5a632004-08-02 06:10:11 +00002629
Georg Brandl0c315622009-05-25 21:10:36 +00002630/* with_item:
2631 * test ['as' expr]
Benjamin Peterson4469d0c2008-11-30 22:46:23 +00002632 */
2633static int
Georg Brandl0c315622009-05-25 21:10:36 +00002634validate_with_item(node *tree)
Benjamin Peterson4469d0c2008-11-30 22:46:23 +00002635{
2636 int nch = NCH(tree);
Georg Brandl0c315622009-05-25 21:10:36 +00002637 int ok = (validate_ntype(tree, with_item)
2638 && (nch == 1 || nch == 3)
2639 && validate_test(CHILD(tree, 0)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002640 if (ok && nch == 3)
Georg Brandl0c315622009-05-25 21:10:36 +00002641 ok = (validate_name(CHILD(tree, 1), "as")
2642 && validate_expr(CHILD(tree, 2)));
2643 return ok;
Benjamin Peterson4469d0c2008-11-30 22:46:23 +00002644}
2645
Georg Brandl0c315622009-05-25 21:10:36 +00002646/* with_stmt:
2647 * 0 1 ... -2 -1
2648 * 'with' with_item (',' with_item)* ':' suite
Benjamin Peterson4469d0c2008-11-30 22:46:23 +00002649 */
2650static int
2651validate_with_stmt(node *tree)
2652{
Georg Brandl0c315622009-05-25 21:10:36 +00002653 int i;
Benjamin Peterson4469d0c2008-11-30 22:46:23 +00002654 int nch = NCH(tree);
2655 int ok = (validate_ntype(tree, with_stmt)
Georg Brandl0c315622009-05-25 21:10:36 +00002656 && (nch % 2 == 0)
Benjamin Peterson4469d0c2008-11-30 22:46:23 +00002657 && validate_name(CHILD(tree, 0), "with")
Benjamin Peterson4469d0c2008-11-30 22:46:23 +00002658 && validate_colon(RCHILD(tree, -2))
2659 && validate_suite(RCHILD(tree, -1)));
Georg Brandl0c315622009-05-25 21:10:36 +00002660 for (i = 1; ok && i < nch - 2; i += 2)
2661 ok = validate_with_item(CHILD(tree, i));
2662 return ok;
Benjamin Peterson4469d0c2008-11-30 22:46:23 +00002663}
2664
Mark Dickinsonea7e9f92012-04-29 18:34:40 +01002665/* funcdef: 'def' NAME parameters ['->' test] ':' suite */
2666
Guido van Rossum47478871996-08-21 14:32:37 +00002667static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002668validate_funcdef(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002669{
Anthony Baxterc2a5a632004-08-02 06:10:11 +00002670 int nch = NCH(tree);
Mark Dickinsonea7e9f92012-04-29 18:34:40 +01002671 int res = validate_ntype(tree, funcdef);
2672 if (res) {
2673 if (nch == 5) {
2674 res = (validate_name(CHILD(tree, 0), "def")
2675 && validate_ntype(CHILD(tree, 1), NAME)
2676 && validate_parameters(CHILD(tree, 2))
2677 && validate_colon(CHILD(tree, 3))
2678 && validate_suite(CHILD(tree, 4)));
2679 }
2680 else if (nch == 7) {
2681 res = (validate_name(CHILD(tree, 0), "def")
2682 && validate_ntype(CHILD(tree, 1), NAME)
2683 && validate_parameters(CHILD(tree, 2))
2684 && validate_rarrow(CHILD(tree, 3))
2685 && validate_test(CHILD(tree, 4))
2686 && validate_colon(CHILD(tree, 5))
2687 && validate_suite(CHILD(tree, 6)));
2688 }
2689 else {
2690 res = 0;
2691 err_string("illegal number of children for funcdef");
2692 }
2693 }
2694 return res;
Fred Drakeff9ea482000-04-19 13:54:15 +00002695}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002696
Yury Selivanov75445082015-05-11 22:57:16 -04002697/* async_funcdef: ASYNC funcdef */
2698
2699static int
2700validate_async_funcdef(node *tree)
2701{
2702 int nch = NCH(tree);
2703 int res = validate_ntype(tree, async_funcdef);
2704 if (res) {
2705 if (nch == 2) {
2706 res = (validate_ntype(CHILD(tree, 0), ASYNC)
2707 && validate_funcdef(CHILD(tree, 1)));
2708 }
2709 else {
2710 res = 0;
2711 err_string("illegal number of children for async_funcdef");
2712 }
2713 }
2714 return res;
2715}
2716
2717
2718/* async_stmt: ASYNC (funcdef | with_stmt | for_stmt) */
2719
2720static int
2721validate_async_stmt(node *tree)
2722{
2723 int nch = NCH(tree);
2724 int res = (validate_ntype(tree, async_stmt)
2725 && validate_ntype(CHILD(tree, 0), ASYNC));
2726
2727 if (nch != 2) {
2728 res = 0;
2729 err_string("illegal number of children for async_stmt");
2730 } else {
2731 if (TYPE(CHILD(tree, 1)) == funcdef) {
2732 res = validate_funcdef(CHILD(tree, 1));
2733 }
2734 else if (TYPE(CHILD(tree, 1)) == with_stmt) {
2735 res = validate_with_stmt(CHILD(tree, 1));
2736 }
2737 else if (TYPE(CHILD(tree, 1)) == for_stmt) {
2738 res = validate_for(CHILD(tree, 1));
2739 }
2740 }
2741
2742 return res;
2743}
2744
2745
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002746
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002747/* decorated
2748 * decorators (classdef | funcdef)
2749 */
2750static int
2751validate_decorated(node *tree)
2752{
Mark Dickinson2bd61a92010-07-04 16:37:31 +00002753 int nch = NCH(tree);
2754 int ok = (validate_ntype(tree, decorated)
2755 && (nch == 2)
2756 && validate_decorators(RCHILD(tree, -2)));
2757 if (TYPE(RCHILD(tree, -1)) == funcdef)
2758 ok = ok && validate_funcdef(RCHILD(tree, -1));
2759 else
2760 ok = ok && validate_class(RCHILD(tree, -1));
2761 return ok;
Guido van Rossumd59da4b2007-05-22 18:11:13 +00002762}
2763
Guido van Rossum47478871996-08-21 14:32:37 +00002764static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002765validate_lambdef(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002766{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002767 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002768 int res = (validate_ntype(tree, lambdef)
Fred Drakeff9ea482000-04-19 13:54:15 +00002769 && ((nch == 3) || (nch == 4))
2770 && validate_name(CHILD(tree, 0), "lambda")
2771 && validate_colon(CHILD(tree, nch - 2))
2772 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002773
Guido van Rossum3d602e31996-07-21 02:33:56 +00002774 if (res && (nch == 4))
Fred Drakeff9ea482000-04-19 13:54:15 +00002775 res = validate_varargslist(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002776 else if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00002777 (void) validate_numnodes(tree, 3, "lambdef");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002778
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002779 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002780}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002781
2782
Thomas Wouterse2dd78c2006-02-27 16:25:11 +00002783static int
Nick Coghlan650f0d02007-04-15 12:05:43 +00002784validate_lambdef_nocond(node *tree)
Thomas Wouterse2dd78c2006-02-27 16:25:11 +00002785{
2786 int nch = NCH(tree);
Nick Coghlan650f0d02007-04-15 12:05:43 +00002787 int res = (validate_ntype(tree, lambdef_nocond)
Thomas Wouterse2dd78c2006-02-27 16:25:11 +00002788 && ((nch == 3) || (nch == 4))
2789 && validate_name(CHILD(tree, 0), "lambda")
2790 && validate_colon(CHILD(tree, nch - 2))
2791 && validate_test(CHILD(tree, nch - 1)));
2792
2793 if (res && (nch == 4))
2794 res = validate_varargslist(CHILD(tree, 1));
2795 else if (!res && !PyErr_Occurred())
Nick Coghlan650f0d02007-04-15 12:05:43 +00002796 (void) validate_numnodes(tree, 3, "lambdef_nocond");
Thomas Wouterse2dd78c2006-02-27 16:25:11 +00002797
2798 return (res);
2799}
2800
2801
Guido van Rossum3d602e31996-07-21 02:33:56 +00002802/* arglist:
2803 *
Fred Drakecff283c2000-08-21 22:24:43 +00002804 * (argument ',')* (argument [','] | '*' test [',' '**' test] | '**' test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002805 */
Guido van Rossum47478871996-08-21 14:32:37 +00002806static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002807validate_arglist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002808{
Fred Drakee7ab64e2000-04-25 04:14:46 +00002809 int nch = NCH(tree);
Fred Drakecff283c2000-08-21 22:24:43 +00002810 int i = 0;
2811 int ok = 1;
Fred Drakee7ab64e2000-04-25 04:14:46 +00002812
2813 if (nch <= 0)
2814 /* raise the right error from having an invalid number of children */
2815 return validate_numnodes(tree, nch + 1, "arglist");
2816
Raymond Hettinger354433a2004-05-19 08:20:33 +00002817 if (nch > 1) {
2818 for (i=0; i<nch; i++) {
2819 if (TYPE(CHILD(tree, i)) == argument) {
2820 node *ch = CHILD(tree, i);
Nick Coghlan650f0d02007-04-15 12:05:43 +00002821 if (NCH(ch) == 2 && TYPE(CHILD(ch, 1)) == comp_for) {
Raymond Hettinger354433a2004-05-19 08:20:33 +00002822 err_string("need '(', ')' for generator expression");
2823 return 0;
2824 }
2825 }
2826 }
2827 }
2828
Fred Drakecff283c2000-08-21 22:24:43 +00002829 while (ok && nch-i >= 2) {
2830 /* skip leading (argument ',') */
2831 ok = (validate_argument(CHILD(tree, i))
2832 && validate_comma(CHILD(tree, i+1)));
2833 if (ok)
2834 i += 2;
2835 else
2836 PyErr_Clear();
2837 }
2838 ok = 1;
2839 if (nch-i > 0) {
Fred Drakecff283c2000-08-21 22:24:43 +00002840 int sym = TYPE(CHILD(tree, i));
2841
2842 if (sym == argument) {
2843 ok = validate_argument(CHILD(tree, i));
2844 if (ok && i+1 != nch) {
2845 err_string("illegal arglist specification"
2846 " (extra stuff on end)");
2847 ok = 0;
Fred Drakee7ab64e2000-04-25 04:14:46 +00002848 }
Fred Drakecff283c2000-08-21 22:24:43 +00002849 }
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04002850 else {
Fred Drakecff283c2000-08-21 22:24:43 +00002851 err_string("illegal arglist specification");
2852 ok = 0;
2853 }
Fred Drakee7ab64e2000-04-25 04:14:46 +00002854 }
2855 return (ok);
Fred Drakeff9ea482000-04-19 13:54:15 +00002856}
Guido van Rossum3d602e31996-07-21 02:33:56 +00002857
2858
2859
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04002860/* argument: ( test [comp_for] |
2861 * test '=' test |
Yury Selivanov14acf5f2015-08-05 17:54:10 -04002862 * '**' test |
2863 * '*' test )
Guido van Rossum3d602e31996-07-21 02:33:56 +00002864 */
Guido van Rossum47478871996-08-21 14:32:37 +00002865static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002866validate_argument(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002867{
2868 int nch = NCH(tree);
2869 int res = (validate_ntype(tree, argument)
Nick Coghlan1f7ce622012-01-13 21:43:40 +10002870 && ((nch == 1) || (nch == 2) || (nch == 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002871
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04002872 if (res) {
2873 if (TYPE(CHILD(tree, 0)) == DOUBLESTAR) {
Benjamin Petersonde12b792015-05-16 09:44:45 -04002874 res = validate_test(CHILD(tree, 1));
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04002875 }
Yury Selivanov14acf5f2015-08-05 17:54:10 -04002876 else if (TYPE(CHILD(tree, 0)) == STAR) {
2877 res = validate_test(CHILD(tree, 1));
2878 }
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04002879 else if (nch == 1) {
Yury Selivanov14acf5f2015-08-05 17:54:10 -04002880 res = validate_test(CHILD(tree, 0));
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04002881 }
2882 else if (nch == 2) {
2883 res = (validate_test(CHILD(tree, 0))
2884 && validate_comp_for(CHILD(tree, 1)));
2885 }
2886 else if (res && (nch == 3)) {
2887 res = (validate_test(CHILD(tree, 0))
2888 && validate_equal(CHILD(tree, 1))
2889 && validate_test(CHILD(tree, 2)));
2890 }
2891 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002892 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002893}
Guido van Rossum3d602e31996-07-21 02:33:56 +00002894
2895
2896
2897/* trailer:
2898 *
Guido van Rossum47478871996-08-21 14:32:37 +00002899 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002900 */
Guido van Rossum47478871996-08-21 14:32:37 +00002901static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002902validate_trailer(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002903{
2904 int nch = NCH(tree);
2905 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002906
2907 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002908 switch (TYPE(CHILD(tree, 0))) {
2909 case LPAR:
2910 res = validate_rparen(CHILD(tree, nch - 1));
2911 if (res && (nch == 3))
2912 res = validate_arglist(CHILD(tree, 1));
2913 break;
2914 case LSQB:
2915 res = (validate_numnodes(tree, 3, "trailer")
2916 && validate_subscriptlist(CHILD(tree, 1))
2917 && validate_ntype(CHILD(tree, 2), RSQB));
2918 break;
2919 case DOT:
2920 res = (validate_numnodes(tree, 2, "trailer")
2921 && validate_ntype(CHILD(tree, 1), NAME));
2922 break;
2923 default:
2924 res = 0;
2925 break;
2926 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002927 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002928 else {
2929 (void) validate_numnodes(tree, 2, "trailer");
2930 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002931 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002932}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002933
2934
Guido van Rossum47478871996-08-21 14:32:37 +00002935/* subscriptlist:
2936 *
2937 * subscript (',' subscript)* [',']
2938 */
2939static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002940validate_subscriptlist(node *tree)
Guido van Rossum47478871996-08-21 14:32:37 +00002941{
2942 return (validate_repeating_list(tree, subscriptlist,
Fred Drakeff9ea482000-04-19 13:54:15 +00002943 validate_subscript, "subscriptlist"));
2944}
Guido van Rossum47478871996-08-21 14:32:37 +00002945
2946
Guido van Rossum3d602e31996-07-21 02:33:56 +00002947/* subscript:
2948 *
Guido van Rossum47478871996-08-21 14:32:37 +00002949 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002950 */
Guido van Rossum47478871996-08-21 14:32:37 +00002951static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002952validate_subscript(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002953{
Guido van Rossum47478871996-08-21 14:32:37 +00002954 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002955 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002956 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002957
Guido van Rossum47478871996-08-21 14:32:37 +00002958 if (!res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002959 if (!PyErr_Occurred())
2960 err_string("invalid number of arguments for subscript node");
2961 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002962 }
Guido van Rossum47478871996-08-21 14:32:37 +00002963 if (TYPE(CHILD(tree, 0)) == DOT)
Fred Drakeff9ea482000-04-19 13:54:15 +00002964 /* take care of ('.' '.' '.') possibility */
2965 return (validate_numnodes(tree, 3, "subscript")
2966 && validate_dot(CHILD(tree, 0))
2967 && validate_dot(CHILD(tree, 1))
2968 && validate_dot(CHILD(tree, 2)));
Guido van Rossum47478871996-08-21 14:32:37 +00002969 if (nch == 1) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002970 if (TYPE(CHILD(tree, 0)) == test)
2971 res = validate_test(CHILD(tree, 0));
2972 else
2973 res = validate_colon(CHILD(tree, 0));
2974 return (res);
Guido van Rossum47478871996-08-21 14:32:37 +00002975 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002976 /* Must be [test] ':' [test] [sliceop],
2977 * but at least one of the optional components will
2978 * be present, but we don't know which yet.
Guido van Rossum47478871996-08-21 14:32:37 +00002979 */
2980 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002981 res = validate_test(CHILD(tree, 0));
2982 offset = 1;
Guido van Rossum47478871996-08-21 14:32:37 +00002983 }
2984 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00002985 res = validate_colon(CHILD(tree, offset));
Guido van Rossum47478871996-08-21 14:32:37 +00002986 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002987 int rem = nch - ++offset;
2988 if (rem) {
2989 if (TYPE(CHILD(tree, offset)) == test) {
2990 res = validate_test(CHILD(tree, offset));
2991 ++offset;
2992 --rem;
2993 }
2994 if (res && rem)
2995 res = validate_sliceop(CHILD(tree, offset));
2996 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002997 }
2998 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002999}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003000
3001
Guido van Rossum47478871996-08-21 14:32:37 +00003002static int
Fred Drakeff9ea482000-04-19 13:54:15 +00003003validate_sliceop(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00003004{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003005 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00003006 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
Fred Drakeff9ea482000-04-19 13:54:15 +00003007 && validate_ntype(tree, sliceop);
Guido van Rossum47478871996-08-21 14:32:37 +00003008 if (!res && !PyErr_Occurred()) {
Fred Drakeff9ea482000-04-19 13:54:15 +00003009 res = validate_numnodes(tree, 1, "sliceop");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003010 }
Guido van Rossum47478871996-08-21 14:32:37 +00003011 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00003012 res = validate_colon(CHILD(tree, 0));
Guido van Rossum47478871996-08-21 14:32:37 +00003013 if (res && (nch == 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00003014 res = validate_test(CHILD(tree, 1));
Guido van Rossum47478871996-08-21 14:32:37 +00003015
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003016 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00003017}
Guido van Rossum47478871996-08-21 14:32:37 +00003018
3019
3020static int
Benjamin Peterson4905e802009-09-27 02:43:28 +00003021validate_test_or_star_expr(node *n)
3022{
3023 if (TYPE(n) == test)
3024 return validate_test(n);
3025 return validate_star_expr(n);
3026}
3027
3028static int
3029validate_expr_or_star_expr(node *n)
3030{
3031 if (TYPE(n) == expr)
3032 return validate_expr(n);
3033 return validate_star_expr(n);
3034}
3035
3036
3037static int
Fred Drakeff9ea482000-04-19 13:54:15 +00003038validate_exprlist(node *tree)
Guido van Rossum47478871996-08-21 14:32:37 +00003039{
3040 return (validate_repeating_list(tree, exprlist,
Benjamin Peterson4905e802009-09-27 02:43:28 +00003041 validate_expr_or_star_expr, "exprlist"));
Fred Drakeff9ea482000-04-19 13:54:15 +00003042}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003043
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04003044/* Incrementing validate functions returns nonzero iff success (like other
3045 * validate functions, and advance *i by the length of the matched pattern. */
3046
3047/* test ':' test */
3048static int
3049validate_test_colon_test_inc(node *tree, int *i)
3050{
3051 return (validate_test(CHILD(tree, (*i)++))
3052 && validate_colon(CHILD(tree, (*i)++))
3053 && validate_test(CHILD(tree, (*i)++)));
3054}
3055
3056/* test ':' test | '**' expr */
3057static int
3058validate_dict_element_inc(node *tree, int *i)
3059{
3060 int nch = NCH(tree);
3061 int res = 0;
3062 if (nch - *i >= 2) {
3063 if (TYPE(CHILD(tree, *i+1)) == COLON) {
3064 /* test ':' test */
3065 res = validate_test_colon_test_inc(tree, i);
3066 } else {
3067 /* '**' expr */
3068 res = (validate_doublestar(CHILD(tree, (*i)++))
3069 && validate_expr(CHILD(tree, (*i)++)));
3070 }
3071 }
3072 return res;
3073}
3074
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003075/*
3076 * dictorsetmaker:
3077 *
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04003078 * ( ((test ':' test | '**' expr)
3079 * (comp_for | (',' (test ':' test | '**' expr))* [','])) |
3080 * ((test | '*' test)
3081 * (comp_for | (',' (test | '*' test))* [','])) )
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003082 */
Guido van Rossum47478871996-08-21 14:32:37 +00003083static int
Nick Coghlan650f0d02007-04-15 12:05:43 +00003084validate_dictorsetmaker(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00003085{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003086 int nch = NCH(tree);
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003087 int res;
3088 int i = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003089
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003090 res = validate_ntype(tree, dictorsetmaker);
3091 if (!res)
3092 return 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00003093
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003094 if (nch - i < 1) {
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04003095 /* Unconditionally raise. */
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003096 (void) validate_numnodes(tree, 1, "dictorsetmaker");
3097 return 0;
3098 }
3099
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04003100 if (nch - i >= 2
3101 && ((TYPE(CHILD(tree, i+1)) == COLON) ||
3102 (TYPE(CHILD(tree, i)) == DOUBLESTAR))) {
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003103 /* Dictionary display or dictionary comprehension. */
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04003104 if (nch - i >= 4 && TYPE(CHILD(tree, i+3)) == comp_for) {
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003105 /* Dictionary comprehension. */
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04003106 res = (validate_test_colon_test_inc(tree, &i)
3107 && validate_comp_for(CHILD(tree, i++)));
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003108 if (!res)
3109 return 0;
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04003110 } else {
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003111 /* Dictionary display. */
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04003112 return validate_repeating_list_variable(
3113 tree,
3114 dictorsetmaker,
3115 validate_dict_element_inc,
3116 &i,
3117 "dictorsetmaker");
Fred Drakeff9ea482000-04-19 13:54:15 +00003118 }
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04003119 } else {
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003120 /* Set display or set comprehension. */
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04003121 if (nch - i >= 2 && TYPE(CHILD(tree, i + 1)) == comp_for) {
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003122 /* Set comprehension. */
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04003123 res = (validate_test(CHILD(tree, i++))
3124 && validate_comp_for(CHILD(tree, i++)));
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003125 if (!res)
3126 return 0;
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04003127 } else {
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003128 /* Set display. */
Benjamin Peterson025e9eb2015-05-05 20:16:41 -04003129 return validate_repeating_list(tree,
3130 dictorsetmaker,
3131 validate_test_or_star_expr,
3132 "dictorsetmaker");
Mark Dickinson11c1dee2012-05-07 16:34:34 +01003133 }
3134 }
3135
3136 if (nch - i > 0) {
3137 err_string("Illegal trailing nodes for dictorsetmaker.");
3138 return 0;
3139 }
3140
3141 return 1;
Fred Drakeff9ea482000-04-19 13:54:15 +00003142}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003143
3144
Guido van Rossum47478871996-08-21 14:32:37 +00003145static int
Fred Drakeff9ea482000-04-19 13:54:15 +00003146validate_eval_input(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00003147{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003148 int pos;
3149 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00003150 int res = (validate_ntype(tree, eval_input)
Fred Drakeff9ea482000-04-19 13:54:15 +00003151 && (nch >= 2)
3152 && validate_testlist(CHILD(tree, 0))
3153 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003154
Guido van Rossum3d602e31996-07-21 02:33:56 +00003155 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Fred Drakeff9ea482000-04-19 13:54:15 +00003156 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00003157
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003158 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00003159}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003160
3161
Guido van Rossum47478871996-08-21 14:32:37 +00003162static int
Fred Drakeff9ea482000-04-19 13:54:15 +00003163validate_node(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00003164{
Fred Drakeff9ea482000-04-19 13:54:15 +00003165 int nch = 0; /* num. children on current node */
3166 int res = 1; /* result value */
3167 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00003168
Martin v. Löwisb28f6e72001-06-23 19:55:38 +00003169 while (res && (tree != 0)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00003170 nch = NCH(tree);
3171 next = 0;
3172 switch (TYPE(tree)) {
3173 /*
3174 * Definition nodes.
3175 */
Yury Selivanov75445082015-05-11 22:57:16 -04003176 case async_funcdef:
3177 res = validate_async_funcdef(tree);
3178 break;
3179 case async_stmt:
3180 res = validate_async_stmt(tree);
3181 break;
Fred Drakeff9ea482000-04-19 13:54:15 +00003182 case funcdef:
3183 res = validate_funcdef(tree);
3184 break;
Benjamin Peterson4469d0c2008-11-30 22:46:23 +00003185 case with_stmt:
3186 res = validate_with_stmt(tree);
3187 break;
Fred Drakeff9ea482000-04-19 13:54:15 +00003188 case classdef:
3189 res = validate_class(tree);
3190 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003191 case decorated:
3192 res = validate_decorated(tree);
3193 break;
Fred Drakeff9ea482000-04-19 13:54:15 +00003194 /*
3195 * "Trivial" parse tree nodes.
3196 * (Why did I call these trivial?)
3197 */
3198 case stmt:
3199 res = validate_stmt(tree);
3200 break;
3201 case small_stmt:
3202 /*
Mark Dickinson407b3bd2012-04-29 22:18:31 +01003203 * expr_stmt | del_stmt | pass_stmt | flow_stmt |
3204 * import_stmt | global_stmt | nonlocal_stmt | assert_stmt
Fred Drakeff9ea482000-04-19 13:54:15 +00003205 */
3206 res = validate_small_stmt(tree);
3207 break;
3208 case flow_stmt:
3209 res = (validate_numnodes(tree, 1, "flow_stmt")
3210 && ((TYPE(CHILD(tree, 0)) == break_stmt)
3211 || (TYPE(CHILD(tree, 0)) == continue_stmt)
Fred Drake02126f22001-07-17 02:59:15 +00003212 || (TYPE(CHILD(tree, 0)) == yield_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00003213 || (TYPE(CHILD(tree, 0)) == return_stmt)
3214 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
3215 if (res)
3216 next = CHILD(tree, 0);
3217 else if (nch == 1)
Fred Drake661ea262000-10-24 19:57:45 +00003218 err_string("illegal flow_stmt type");
Fred Drakeff9ea482000-04-19 13:54:15 +00003219 break;
Fred Drake02126f22001-07-17 02:59:15 +00003220 case yield_stmt:
3221 res = validate_yield_stmt(tree);
3222 break;
Fred Drakeff9ea482000-04-19 13:54:15 +00003223 /*
3224 * Compound statements.
3225 */
3226 case simple_stmt:
3227 res = validate_simple_stmt(tree);
3228 break;
3229 case compound_stmt:
3230 res = validate_compound_stmt(tree);
3231 break;
3232 /*
Thomas Wouters7e474022000-07-16 12:04:32 +00003233 * Fundamental statements.
Fred Drakeff9ea482000-04-19 13:54:15 +00003234 */
3235 case expr_stmt:
3236 res = validate_expr_stmt(tree);
3237 break;
Fred Drakeff9ea482000-04-19 13:54:15 +00003238 case del_stmt:
3239 res = validate_del_stmt(tree);
3240 break;
3241 case pass_stmt:
3242 res = (validate_numnodes(tree, 1, "pass")
3243 && validate_name(CHILD(tree, 0), "pass"));
3244 break;
3245 case break_stmt:
3246 res = (validate_numnodes(tree, 1, "break")
3247 && validate_name(CHILD(tree, 0), "break"));
3248 break;
3249 case continue_stmt:
3250 res = (validate_numnodes(tree, 1, "continue")
3251 && validate_name(CHILD(tree, 0), "continue"));
3252 break;
3253 case return_stmt:
3254 res = validate_return_stmt(tree);
3255 break;
3256 case raise_stmt:
3257 res = validate_raise_stmt(tree);
3258 break;
3259 case import_stmt:
3260 res = validate_import_stmt(tree);
3261 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003262 case import_name:
3263 res = validate_import_name(tree);
3264 break;
3265 case import_from:
3266 res = validate_import_from(tree);
3267 break;
Fred Drakeff9ea482000-04-19 13:54:15 +00003268 case global_stmt:
3269 res = validate_global_stmt(tree);
3270 break;
Mark Dickinson407b3bd2012-04-29 22:18:31 +01003271 case nonlocal_stmt:
3272 res = validate_nonlocal_stmt(tree);
3273 break;
Fred Drakeff9ea482000-04-19 13:54:15 +00003274 case assert_stmt:
3275 res = validate_assert_stmt(tree);
3276 break;
3277 case if_stmt:
3278 res = validate_if(tree);
3279 break;
3280 case while_stmt:
3281 res = validate_while(tree);
3282 break;
3283 case for_stmt:
3284 res = validate_for(tree);
3285 break;
3286 case try_stmt:
3287 res = validate_try(tree);
3288 break;
3289 case suite:
3290 res = validate_suite(tree);
3291 break;
3292 /*
3293 * Expression nodes.
3294 */
3295 case testlist:
3296 res = validate_testlist(tree);
3297 break;
Phillip J. Eby0d6615f2005-08-02 00:46:46 +00003298 case yield_expr:
3299 res = validate_yield_expr(tree);
3300 break;
Fred Drakeff9ea482000-04-19 13:54:15 +00003301 case test:
3302 res = validate_test(tree);
3303 break;
3304 case and_test:
3305 res = validate_and_test(tree);
3306 break;
3307 case not_test:
3308 res = validate_not_test(tree);
3309 break;
3310 case comparison:
3311 res = validate_comparison(tree);
3312 break;
3313 case exprlist:
3314 res = validate_exprlist(tree);
3315 break;
3316 case comp_op:
3317 res = validate_comp_op(tree);
3318 break;
3319 case expr:
3320 res = validate_expr(tree);
3321 break;
3322 case xor_expr:
3323 res = validate_xor_expr(tree);
3324 break;
3325 case and_expr:
3326 res = validate_and_expr(tree);
3327 break;
3328 case shift_expr:
3329 res = validate_shift_expr(tree);
3330 break;
3331 case arith_expr:
3332 res = validate_arith_expr(tree);
3333 break;
3334 case term:
3335 res = validate_term(tree);
3336 break;
3337 case factor:
3338 res = validate_factor(tree);
3339 break;
3340 case power:
3341 res = validate_power(tree);
3342 break;
3343 case atom:
3344 res = validate_atom(tree);
3345 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00003346
Fred Drakeff9ea482000-04-19 13:54:15 +00003347 default:
3348 /* Hopefully never reached! */
Fred Drake661ea262000-10-24 19:57:45 +00003349 err_string("unrecognized node type");
Fred Drakeff9ea482000-04-19 13:54:15 +00003350 res = 0;
3351 break;
3352 }
3353 tree = next;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003354 }
3355 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00003356}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003357
3358
Guido van Rossum47478871996-08-21 14:32:37 +00003359static int
Fred Drakeff9ea482000-04-19 13:54:15 +00003360validate_expr_tree(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00003361{
3362 int res = validate_eval_input(tree);
3363
3364 if (!res && !PyErr_Occurred())
Fred Drake661ea262000-10-24 19:57:45 +00003365 err_string("could not validate expression tuple");
Guido van Rossum3d602e31996-07-21 02:33:56 +00003366
3367 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00003368}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003369
3370
Guido van Rossum3d602e31996-07-21 02:33:56 +00003371/* file_input:
Fred Drakeff9ea482000-04-19 13:54:15 +00003372 * (NEWLINE | stmt)* ENDMARKER
Guido van Rossum3d602e31996-07-21 02:33:56 +00003373 */
Guido van Rossum47478871996-08-21 14:32:37 +00003374static int
Fred Drakeff9ea482000-04-19 13:54:15 +00003375validate_file_input(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00003376{
Fred Drakec2683dd2001-07-17 19:32:05 +00003377 int j;
Guido van Rossum3d602e31996-07-21 02:33:56 +00003378 int nch = NCH(tree) - 1;
3379 int res = ((nch >= 0)
Fred Drakeff9ea482000-04-19 13:54:15 +00003380 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003381
Fred Drakec2683dd2001-07-17 19:32:05 +00003382 for (j = 0; res && (j < nch); ++j) {
Fred Drakeff9ea482000-04-19 13:54:15 +00003383 if (TYPE(CHILD(tree, j)) == stmt)
3384 res = validate_stmt(CHILD(tree, j));
3385 else
3386 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003387 }
Thomas Wouters7e474022000-07-16 12:04:32 +00003388 /* This stays in to prevent any internal failures from getting to the
Fred Drakeff9ea482000-04-19 13:54:15 +00003389 * user. Hopefully, this won't be needed. If a user reports getting
3390 * this, we have some debugging to do.
Guido van Rossum3d602e31996-07-21 02:33:56 +00003391 */
3392 if (!res && !PyErr_Occurred())
Fred Drake661ea262000-10-24 19:57:45 +00003393 err_string("VALIDATION FAILURE: report this to the maintainer!");
Guido van Rossum3d602e31996-07-21 02:33:56 +00003394
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003395 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00003396}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003397
Michael W. Hudsondf1252d2003-02-08 18:05:10 +00003398static int
3399validate_encoding_decl(node *tree)
3400{
3401 int nch = NCH(tree);
3402 int res = ((nch == 1)
3403 && validate_file_input(CHILD(tree, 0)));
3404
3405 if (!res && !PyErr_Occurred())
3406 err_string("Error Parsing encoding_decl");
3407
3408 return res;
3409}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003410
Fred Drake43f8f9b1998-04-13 16:25:46 +00003411static PyObject*
3412pickle_constructor = NULL;
3413
3414
3415static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +00003416parser__pickler(PyObject *self, PyObject *args)
Fred Drake43f8f9b1998-04-13 16:25:46 +00003417{
Fred Drake268397f1998-04-29 14:16:32 +00003418 NOTE(ARGUNUSED(self))
Fred Drake43f8f9b1998-04-13 16:25:46 +00003419 PyObject *result = NULL;
Fred Drakec2683dd2001-07-17 19:32:05 +00003420 PyObject *st = NULL;
Fred Drake2a6875e1999-09-20 22:32:18 +00003421 PyObject *empty_dict = NULL;
Fred Drake43f8f9b1998-04-13 16:25:46 +00003422
Fred Drakec2683dd2001-07-17 19:32:05 +00003423 if (PyArg_ParseTuple(args, "O!:_pickler", &PyST_Type, &st)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00003424 PyObject *newargs;
3425 PyObject *tuple;
Fred Drake43f8f9b1998-04-13 16:25:46 +00003426
Fred Drake2a6875e1999-09-20 22:32:18 +00003427 if ((empty_dict = PyDict_New()) == NULL)
3428 goto finally;
Fred Drakec2683dd2001-07-17 19:32:05 +00003429 if ((newargs = Py_BuildValue("Oi", st, 1)) == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +00003430 goto finally;
Fred Drakec2683dd2001-07-17 19:32:05 +00003431 tuple = parser_st2tuple((PyST_Object*)NULL, newargs, empty_dict);
Fred Drakeff9ea482000-04-19 13:54:15 +00003432 if (tuple != NULL) {
3433 result = Py_BuildValue("O(O)", pickle_constructor, tuple);
3434 Py_DECREF(tuple);
3435 }
Fred Drake2a6875e1999-09-20 22:32:18 +00003436 Py_DECREF(empty_dict);
Fred Drakeff9ea482000-04-19 13:54:15 +00003437 Py_DECREF(newargs);
Fred Drake43f8f9b1998-04-13 16:25:46 +00003438 }
3439 finally:
Fred Drake2a6875e1999-09-20 22:32:18 +00003440 Py_XDECREF(empty_dict);
3441
Fred Drake43f8f9b1998-04-13 16:25:46 +00003442 return (result);
Fred Drakeff9ea482000-04-19 13:54:15 +00003443}
Fred Drake43f8f9b1998-04-13 16:25:46 +00003444
3445
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003446/* Functions exported by this module. Most of this should probably
Fred Drakec2683dd2001-07-17 19:32:05 +00003447 * be converted into an ST object with methods, but that is better
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003448 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00003449 * We'd really have to write a wrapper around it all anyway to allow
3450 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003451 */
3452static PyMethodDef parser_functions[] = {
Fred Drakec2683dd2001-07-17 19:32:05 +00003453 {"compilest", (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE,
Neal Norwitz200788c2002-08-13 22:20:41 +00003454 PyDoc_STR("Compiles an ST object into a code object.")},
Fred Drakec2683dd2001-07-17 19:32:05 +00003455 {"expr", (PyCFunction)parser_expr, PUBLIC_METHOD_TYPE,
Neal Norwitz200788c2002-08-13 22:20:41 +00003456 PyDoc_STR("Creates an ST object from an expression.")},
Fred Drakec2683dd2001-07-17 19:32:05 +00003457 {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
Neal Norwitz200788c2002-08-13 22:20:41 +00003458 PyDoc_STR("Determines if an ST object was created from an expression.")},
Fred Drakec2683dd2001-07-17 19:32:05 +00003459 {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
Neal Norwitz200788c2002-08-13 22:20:41 +00003460 PyDoc_STR("Determines if an ST object was created from a suite.")},
Fred Drakec2683dd2001-07-17 19:32:05 +00003461 {"suite", (PyCFunction)parser_suite, PUBLIC_METHOD_TYPE,
Neal Norwitz200788c2002-08-13 22:20:41 +00003462 PyDoc_STR("Creates an ST object from a suite.")},
Fred Drakec2683dd2001-07-17 19:32:05 +00003463 {"sequence2st", (PyCFunction)parser_tuple2st, PUBLIC_METHOD_TYPE,
Neal Norwitz200788c2002-08-13 22:20:41 +00003464 PyDoc_STR("Creates an ST object from a tree representation.")},
Fred Drakec2683dd2001-07-17 19:32:05 +00003465 {"st2tuple", (PyCFunction)parser_st2tuple, PUBLIC_METHOD_TYPE,
Neal Norwitz200788c2002-08-13 22:20:41 +00003466 PyDoc_STR("Creates a tuple-tree representation of an ST.")},
Fred Drakec2683dd2001-07-17 19:32:05 +00003467 {"st2list", (PyCFunction)parser_st2list, PUBLIC_METHOD_TYPE,
Neal Norwitz200788c2002-08-13 22:20:41 +00003468 PyDoc_STR("Creates a list-tree representation of an ST.")},
Fred Drakec2683dd2001-07-17 19:32:05 +00003469 {"tuple2st", (PyCFunction)parser_tuple2st, PUBLIC_METHOD_TYPE,
Neal Norwitz200788c2002-08-13 22:20:41 +00003470 PyDoc_STR("Creates an ST object from a tree representation.")},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003471
Fred Drake43f8f9b1998-04-13 16:25:46 +00003472 /* private stuff: support pickle module */
Fred Drake13130bc2001-08-15 16:44:56 +00003473 {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS,
Neal Norwitz200788c2002-08-13 22:20:41 +00003474 PyDoc_STR("Returns the pickle magic to allow ST objects to be pickled.")},
Fred Drake43f8f9b1998-04-13 16:25:46 +00003475
Fred Drake268397f1998-04-29 14:16:32 +00003476 {NULL, NULL, 0, NULL}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003477 };
3478
3479
Martin v. Löwis1a214512008-06-11 05:26:20 +00003480
3481static struct PyModuleDef parsermodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003482 PyModuleDef_HEAD_INIT,
3483 "parser",
3484 NULL,
3485 -1,
3486 parser_functions,
3487 NULL,
3488 NULL,
3489 NULL,
3490 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00003491};
3492
3493PyMODINIT_FUNC PyInit_parser(void); /* supply a prototype */
Fred Drake28f739a2000-08-25 22:42:40 +00003494
Mark Hammond62b1ab12002-07-23 06:31:15 +00003495PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00003496PyInit_parser(void)
Fred Drake28f739a2000-08-25 22:42:40 +00003497{
Fred Drake13130bc2001-08-15 16:44:56 +00003498 PyObject *module, *copyreg;
Fred Drakec2683dd2001-07-17 19:32:05 +00003499
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +00003500 if (PyType_Ready(&PyST_Type) < 0)
3501 return NULL;
Martin v. Löwis1a214512008-06-11 05:26:20 +00003502 module = PyModule_Create(&parsermodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00003503 if (module == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003504 return NULL;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003505
Fred Drake7a15ba51999-09-09 14:21:52 +00003506 if (parser_error == 0)
3507 parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003508
Tim Peters6a627252003-07-21 14:25:23 +00003509 if (parser_error == 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00003510 return NULL;
Tim Peters6a627252003-07-21 14:25:23 +00003511 /* CAUTION: The code next used to skip bumping the refcount on
Martin v. Löwis1a214512008-06-11 05:26:20 +00003512 * parser_error. That's a disaster if PyInit_parser() gets called more
Tim Peters6a627252003-07-21 14:25:23 +00003513 * than once. By incref'ing, we ensure that each module dict that
3514 * gets created owns its reference to the shared parser_error object,
3515 * and the file static parser_error vrbl owns a reference too.
3516 */
3517 Py_INCREF(parser_error);
3518 if (PyModule_AddObject(module, "ParserError", parser_error) != 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00003519 return NULL;
Tim Peters6a627252003-07-21 14:25:23 +00003520
Fred Drakec2683dd2001-07-17 19:32:05 +00003521 Py_INCREF(&PyST_Type);
Fred Drake13130bc2001-08-15 16:44:56 +00003522 PyModule_AddObject(module, "STType", (PyObject*)&PyST_Type);
Guido van Rossum3d602e31996-07-21 02:33:56 +00003523
Fred Drake13130bc2001-08-15 16:44:56 +00003524 PyModule_AddStringConstant(module, "__copyright__",
3525 parser_copyright_string);
3526 PyModule_AddStringConstant(module, "__doc__",
3527 parser_doc_string);
3528 PyModule_AddStringConstant(module, "__version__",
3529 parser_version_string);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00003530
Fred Drake78bdb9b2001-07-19 20:17:15 +00003531 /* Register to support pickling.
3532 * If this fails, the import of this module will fail because an
3533 * exception will be raised here; should we clear the exception?
3534 */
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00003535 copyreg = PyImport_ImportModuleNoBlock("copyreg");
Fred Drake13130bc2001-08-15 16:44:56 +00003536 if (copyreg != NULL) {
Fred Drakeff9ea482000-04-19 13:54:15 +00003537 PyObject *func, *pickler;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02003538 _Py_IDENTIFIER(pickle);
3539 _Py_IDENTIFIER(sequence2st);
3540 _Py_IDENTIFIER(_pickler);
Fred Drake43f8f9b1998-04-13 16:25:46 +00003541
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02003542 func = _PyObject_GetAttrId(copyreg, &PyId_pickle);
3543 pickle_constructor = _PyObject_GetAttrId(module, &PyId_sequence2st);
3544 pickler = _PyObject_GetAttrId(module, &PyId__pickler);
Fred Drakeff9ea482000-04-19 13:54:15 +00003545 Py_XINCREF(pickle_constructor);
3546 if ((func != NULL) && (pickle_constructor != NULL)
3547 && (pickler != NULL)) {
3548 PyObject *res;
Fred Drake43f8f9b1998-04-13 16:25:46 +00003549
Thomas Wouters477c8d52006-05-27 19:21:47 +00003550 res = PyObject_CallFunctionObjArgs(func, &PyST_Type, pickler,
3551 pickle_constructor, NULL);
Fred Drakeff9ea482000-04-19 13:54:15 +00003552 Py_XDECREF(res);
3553 }
3554 Py_XDECREF(func);
Fred Drake13130bc2001-08-15 16:44:56 +00003555 Py_XDECREF(pickle_constructor);
3556 Py_XDECREF(pickler);
3557 Py_DECREF(copyreg);
Fred Drake43f8f9b1998-04-13 16:25:46 +00003558 }
Martin v. Löwis1a214512008-06-11 05:26:20 +00003559 return module;
Fred Drakeff9ea482000-04-19 13:54:15 +00003560}