blob: bec7f43422a229a640de07124b9f934330a5e5c2 [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(...)".
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000026 */
27
Fred Drakeff9ea482000-04-19 13:54:15 +000028#include "Python.h" /* general Python API */
29#include "graminit.h" /* symbols defined in the grammar */
30#include "node.h" /* internal parser structure */
31#include "token.h" /* token definitions */
32 /* ISTERMINAL() / ISNONTERMINAL() */
33#include "compile.h" /* PyNode_Compile() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000034
Fred Drake268397f1998-04-29 14:16:32 +000035#ifdef lint
36#include <note.h>
37#else
38#define NOTE(x)
39#endif
40
Guido van Rossum19efc5f1998-04-28 16:10:19 +000041#ifdef macintosh
Fred Drakeff9ea482000-04-19 13:54:15 +000042char *strdup(char *);
Guido van Rossum19efc5f1998-04-28 16:10:19 +000043#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000044
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000045/* String constants used to initialize module attributes.
46 *
47 */
48static char*
49parser_copyright_string
Guido van Rossum2a288461996-08-21 21:55:43 +000050= "Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
51University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
52Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\
53Centrum, Amsterdam, The Netherlands.";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000054
55
56static char*
57parser_doc_string
58= "This is an interface to Python's internal parser.";
59
60static char*
Guido van Rossum47478871996-08-21 14:32:37 +000061parser_version_string = "0.4";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000062
63
Fred Drakeff9ea482000-04-19 13:54:15 +000064typedef PyObject* (*SeqMaker) (int length);
65typedef int (*SeqInserter) (PyObject* sequence,
66 int index,
67 PyObject* element);
Guido van Rossum47478871996-08-21 14:32:37 +000068
Guido van Rossum3d602e31996-07-21 02:33:56 +000069/* The function below is copyrigthed by Stichting Mathematisch Centrum. The
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000070 * original copyright statement is included below, and continues to apply
71 * in full to the function immediately following. All other material is
72 * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
73 * Institute and State University. Changes were made to comply with the
Guido van Rossum2a288461996-08-21 21:55:43 +000074 * new naming conventions. Added arguments to provide support for creating
75 * lists as well as tuples, and optionally including the line numbers.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000076 */
77
Guido van Rossum52f2c051993-11-10 12:53:24 +000078/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +000079Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
80The Netherlands.
Guido van Rossum52f2c051993-11-10 12:53:24 +000081
82 All Rights Reserved
83
Guido van Rossum3d602e31996-07-21 02:33:56 +000084Permission to use, copy, modify, and distribute this software and its
85documentation for any purpose and without fee is hereby granted,
Guido van Rossum52f2c051993-11-10 12:53:24 +000086provided that the above copyright notice appear in all copies and that
Guido van Rossum3d602e31996-07-21 02:33:56 +000087both that copyright notice and this permission notice appear in
Guido van Rossum52f2c051993-11-10 12:53:24 +000088supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000089Centrum or CWI or Corporation for National Research Initiatives or
90CNRI not be used in advertising or publicity pertaining to
91distribution of the software without specific, written prior
92permission.
Guido van Rossum52f2c051993-11-10 12:53:24 +000093
Guido van Rossumd266eb41996-10-25 14:44:06 +000094While CWI is the initial source for this software, a modified version
95is made available by the Corporation for National Research Initiatives
96(CNRI) at the Internet address ftp://ftp.python.org.
97
98STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
99REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
100MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
101CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
102DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
103PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
104TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
105PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum52f2c051993-11-10 12:53:24 +0000106
107******************************************************************/
108
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000109static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000110node2tuple(node *n, /* node to convert */
111 SeqMaker mkseq, /* create sequence */
112 SeqInserter addelem, /* func. to add elem. in seq. */
113 int lineno) /* include line numbers? */
Guido van Rossum47478871996-08-21 14:32:37 +0000114{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000115 if (n == NULL) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000116 Py_INCREF(Py_None);
117 return (Py_None);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000118 }
119 if (ISNONTERMINAL(TYPE(n))) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000120 int i;
121 PyObject *v;
122 PyObject *w;
Fred Drake268397f1998-04-29 14:16:32 +0000123
Fred Drakeff9ea482000-04-19 13:54:15 +0000124 v = mkseq(1 + NCH(n));
125 if (v == NULL)
126 return (v);
127 w = PyInt_FromLong(TYPE(n));
128 if (w == NULL) {
129 Py_DECREF(v);
130 return ((PyObject*) NULL);
131 }
132 (void) addelem(v, 0, w);
133 for (i = 0; i < NCH(n); i++) {
134 w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
135 if (w == NULL) {
136 Py_DECREF(v);
137 return ((PyObject*) NULL);
138 }
139 (void) addelem(v, i+1, w);
140 }
141 return (v);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000142 }
143 else if (ISTERMINAL(TYPE(n))) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000144 PyObject *result = mkseq(2 + lineno);
145 if (result != NULL) {
146 (void) addelem(result, 0, PyInt_FromLong(TYPE(n)));
147 (void) addelem(result, 1, PyString_FromString(STR(n)));
148 if (lineno == 1)
149 (void) addelem(result, 2, PyInt_FromLong(n->n_lineno));
150 }
151 return (result);
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 }
Fred Drakeff9ea482000-04-19 13:54:15 +0000158}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000159/*
160 * End of material copyrighted by Stichting Mathematisch Centrum.
161 */
Guido van Rossum52f2c051993-11-10 12:53:24 +0000162
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000163
164
165/* There are two types of intermediate objects we're interested in:
166 * 'eval' and 'exec' types. These constants can be used in the ast_type
167 * field of the object type to identify which any given object represents.
168 * These should probably go in an external header to allow other extensions
169 * to use them, but then, we really should be using C++ too. ;-)
170 *
Guido van Rossum3d602e31996-07-21 02:33:56 +0000171 * The PyAST_FRAGMENT type is not currently supported. Maybe not useful?
172 * Haven't decided yet.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000173 */
174
Fred Drakeff9ea482000-04-19 13:54:15 +0000175#define PyAST_EXPR 1
176#define PyAST_SUITE 2
177#define PyAST_FRAGMENT 3
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000178
179
180/* These are the internal objects and definitions required to implement the
181 * AST type. Most of the internal names are more reminiscent of the 'old'
182 * naming style, but the code uses the new naming convention.
183 */
184
185static PyObject*
186parser_error = 0;
187
188
189typedef struct _PyAST_Object {
Fred Drakeff9ea482000-04-19 13:54:15 +0000190 PyObject_HEAD /* standard object header */
191 node* ast_node; /* the node* returned by the parser */
192 int ast_type; /* EXPR or SUITE ? */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000193} PyAST_Object;
194
195
Fred Drake268397f1998-04-29 14:16:32 +0000196staticforward void
Fred Drakeff9ea482000-04-19 13:54:15 +0000197parser_free(PyAST_Object *ast);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000198
Fred Drake268397f1998-04-29 14:16:32 +0000199staticforward int
Fred Drakeff9ea482000-04-19 13:54:15 +0000200parser_compare(PyAST_Object *left, PyAST_Object *right);
Fred Drake268397f1998-04-29 14:16:32 +0000201
202staticforward PyObject *
Fred Drakeff9ea482000-04-19 13:54:15 +0000203parser_getattr(PyObject *self, char *name);
Fred Drake503d8d61998-04-13 18:45:18 +0000204
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000205
Fred Drake268397f1998-04-29 14:16:32 +0000206static
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000207PyTypeObject PyAST_Type = {
Guido van Rossum3c8c5981998-05-29 02:58:20 +0000208 PyObject_HEAD_INIT(NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000209 0,
Fred Drakeff9ea482000-04-19 13:54:15 +0000210 "ast", /* tp_name */
211 (int) sizeof(PyAST_Object), /* tp_basicsize */
212 0, /* tp_itemsize */
213 (destructor)parser_free, /* tp_dealloc */
214 0, /* tp_print */
215 parser_getattr, /* tp_getattr */
216 0, /* tp_setattr */
217 (cmpfunc)parser_compare, /* tp_compare */
218 0, /* tp_repr */
219 0, /* tp_as_number */
220 0, /* tp_as_sequence */
221 0, /* tp_as_mapping */
222 0, /* tp_hash */
223 0, /* tp_call */
224 0, /* tp_str */
225 0, /* tp_getattro */
226 0, /* tp_setattro */
Fred Drake69b9ae41997-05-23 04:04:17 +0000227
228 /* Functions to access object as input/output buffer */
Fred Drakeff9ea482000-04-19 13:54:15 +0000229 0, /* tp_as_buffer */
Fred Drake69b9ae41997-05-23 04:04:17 +0000230
Fred Drakeff9ea482000-04-19 13:54:15 +0000231 Py_TPFLAGS_DEFAULT, /* tp_flags */
Fred Drake69b9ae41997-05-23 04:04:17 +0000232
233 /* __doc__ */
234 "Intermediate representation of a Python parse tree."
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000235}; /* PyAST_Type */
236
237
238static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000239parser_compare_nodes(node *left, node *right)
Guido van Rossum47478871996-08-21 14:32:37 +0000240{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000241 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000242
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000243 if (TYPE(left) < TYPE(right))
Fred Drakeff9ea482000-04-19 13:54:15 +0000244 return (-1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000245
246 if (TYPE(right) < TYPE(left))
Fred Drakeff9ea482000-04-19 13:54:15 +0000247 return (1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000248
249 if (ISTERMINAL(TYPE(left)))
Fred Drakeff9ea482000-04-19 13:54:15 +0000250 return (strcmp(STR(left), STR(right)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000251
252 if (NCH(left) < NCH(right))
Fred Drakeff9ea482000-04-19 13:54:15 +0000253 return (-1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000254
255 if (NCH(right) < NCH(left))
Fred Drakeff9ea482000-04-19 13:54:15 +0000256 return (1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000257
258 for (j = 0; j < NCH(left); ++j) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000259 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000260
Fred Drakeff9ea482000-04-19 13:54:15 +0000261 if (v != 0)
262 return (v);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000263 }
264 return (0);
Fred Drakeff9ea482000-04-19 13:54:15 +0000265}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000266
267
268/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
269 *
270 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
271 * This really just wraps a call to parser_compare_nodes() with some easy
272 * checks and protection code.
273 *
274 */
275static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000276parser_compare(PyAST_Object *left, PyAST_Object *right)
Guido van Rossum47478871996-08-21 14:32:37 +0000277{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000278 if (left == right)
Fred Drakeff9ea482000-04-19 13:54:15 +0000279 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000280
281 if ((left == 0) || (right == 0))
Fred Drakeff9ea482000-04-19 13:54:15 +0000282 return (-1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000283
284 return (parser_compare_nodes(left->ast_node, right->ast_node));
Fred Drakeff9ea482000-04-19 13:54:15 +0000285}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000286
287
288/* parser_newastobject(node* ast)
289 *
290 * Allocates a new Python object representing an AST. This is simply the
291 * 'wrapper' object that holds a node* and allows it to be passed around in
292 * Python code.
293 *
294 */
295static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000296parser_newastobject(node *ast, int type)
Guido van Rossum47478871996-08-21 14:32:37 +0000297{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000298 PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
299
300 if (o != 0) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000301 o->ast_node = ast;
302 o->ast_type = type;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000303 }
Fred Drake268397f1998-04-29 14:16:32 +0000304 else {
Fred Drakeff9ea482000-04-19 13:54:15 +0000305 PyNode_Free(ast);
Fred Drake268397f1998-04-29 14:16:32 +0000306 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000307 return ((PyObject*)o);
Fred Drakeff9ea482000-04-19 13:54:15 +0000308}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000309
310
311/* void parser_free(PyAST_Object* ast)
312 *
313 * This is called by a del statement that reduces the reference count to 0.
314 *
315 */
316static void
Fred Drakeff9ea482000-04-19 13:54:15 +0000317parser_free(PyAST_Object *ast)
Guido van Rossum47478871996-08-21 14:32:37 +0000318{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000319 PyNode_Free(ast->ast_node);
320 PyMem_DEL(ast);
Fred Drakeff9ea482000-04-19 13:54:15 +0000321}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000322
323
Fred Drake2a6875e1999-09-20 22:32:18 +0000324/* parser_ast2tuple(PyObject* self, PyObject* args, PyObject* kw)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000325 *
326 * This provides conversion from a node* to a tuple object that can be
327 * returned to the Python-level caller. The AST object is not modified.
328 *
329 */
330static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000331parser_ast2tuple(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000332{
Guido van Rossum47478871996-08-21 14:32:37 +0000333 PyObject *line_option = 0;
334 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000335 int ok;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000336
Fred Drake7a15ba51999-09-09 14:21:52 +0000337 static char *keywords[] = {"ast", "line_info", NULL};
338
Fred Drake268397f1998-04-29 14:16:32 +0000339 if (self == NULL) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000340 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:ast2tuple", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000341 &PyAST_Type, &self, &line_option);
Fred Drake268397f1998-04-29 14:16:32 +0000342 }
Fred Drake503d8d61998-04-13 18:45:18 +0000343 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000344 ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:totuple", &keywords[1],
Fred Drake7a15ba51999-09-09 14:21:52 +0000345 &line_option);
Fred Drake268397f1998-04-29 14:16:32 +0000346 if (ok != 0) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000347 int lineno = 0;
348 if (line_option != NULL) {
349 lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0;
350 }
351 /*
352 * Convert AST into a tuple representation. Use Guido's function,
353 * since it's known to work already.
354 */
355 res = node2tuple(((PyAST_Object*)self)->ast_node,
356 PyTuple_New, PyTuple_SetItem, lineno);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000357 }
358 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000359}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000360
361
Fred Drake2a6875e1999-09-20 22:32:18 +0000362/* parser_ast2list(PyObject* self, PyObject* args, PyObject* kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000363 *
Fred Drake2a6875e1999-09-20 22:32:18 +0000364 * This provides conversion from a node* to a list object that can be
Guido van Rossum47478871996-08-21 14:32:37 +0000365 * returned to the Python-level caller. The AST object is not modified.
366 *
367 */
368static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000369parser_ast2list(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000370{
Guido van Rossum47478871996-08-21 14:32:37 +0000371 PyObject *line_option = 0;
372 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000373 int ok;
Guido van Rossum47478871996-08-21 14:32:37 +0000374
Fred Drake7a15ba51999-09-09 14:21:52 +0000375 static char *keywords[] = {"ast", "line_info", NULL};
376
Fred Drake503d8d61998-04-13 18:45:18 +0000377 if (self == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000378 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:ast2list", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000379 &PyAST_Type, &self, &line_option);
Fred Drake503d8d61998-04-13 18:45:18 +0000380 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000381 ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1],
Fred Drake7a15ba51999-09-09 14:21:52 +0000382 &line_option);
Fred Drake503d8d61998-04-13 18:45:18 +0000383 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000384 int lineno = 0;
385 if (line_option != 0) {
386 lineno = PyObject_IsTrue(line_option) ? 1 : 0;
387 }
388 /*
389 * Convert AST into a tuple representation. Use Guido's function,
390 * since it's known to work already.
391 */
392 res = node2tuple(self->ast_node,
393 PyList_New, PyList_SetItem, lineno);
Guido van Rossum47478871996-08-21 14:32:37 +0000394 }
395 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000396}
Guido van Rossum47478871996-08-21 14:32:37 +0000397
398
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000399/* parser_compileast(PyObject* self, PyObject* args)
400 *
401 * This function creates code objects from the parse tree represented by
402 * the passed-in data object. An optional file name is passed in as well.
403 *
404 */
405static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000406parser_compileast(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000407{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000408 PyObject* res = 0;
Fred Drakeff9ea482000-04-19 13:54:15 +0000409 char* str = "<ast>";
Fred Drake503d8d61998-04-13 18:45:18 +0000410 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000411
Fred Drake7a15ba51999-09-09 14:21:52 +0000412 static char *keywords[] = {"ast", "filename", NULL};
413
Fred Drake503d8d61998-04-13 18:45:18 +0000414 if (self == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000415 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compileast", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000416 &PyAST_Type, &self, &str);
Fred Drake503d8d61998-04-13 18:45:18 +0000417 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000418 ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1],
Fred Drake7a15ba51999-09-09 14:21:52 +0000419 &str);
Fred Drake503d8d61998-04-13 18:45:18 +0000420
421 if (ok)
Fred Drakeff9ea482000-04-19 13:54:15 +0000422 res = (PyObject *)PyNode_Compile(self->ast_node, str);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000423
424 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000425}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000426
427
428/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
429 * PyObject* parser_issuite(PyObject* self, PyObject* args)
430 *
431 * Checks the passed-in AST object to determine if it is an expression or
432 * a statement suite, respectively. The return is a Python truth value.
433 *
434 */
435static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000436parser_isexpr(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000437{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000438 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000439 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000440
Fred Drake7a15ba51999-09-09 14:21:52 +0000441 static char *keywords[] = {"ast", NULL};
442
Fred Drake503d8d61998-04-13 18:45:18 +0000443 if (self == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000444 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000445 &PyAST_Type, &self);
Fred Drake503d8d61998-04-13 18:45:18 +0000446 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000447 ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]);
Fred Drake503d8d61998-04-13 18:45:18 +0000448
449 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000450 /* Check to see if the AST represents an expression or not. */
451 res = (self->ast_type == PyAST_EXPR) ? Py_True : Py_False;
452 Py_INCREF(res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000453 }
454 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000455}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000456
457
458static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000459parser_issuite(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000460{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000461 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000462 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000463
Fred Drake7a15ba51999-09-09 14:21:52 +0000464 static char *keywords[] = {"ast", NULL};
465
Fred Drake503d8d61998-04-13 18:45:18 +0000466 if (self == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000467 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000468 &PyAST_Type, &self);
Fred Drake503d8d61998-04-13 18:45:18 +0000469 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000470 ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]);
Fred Drake503d8d61998-04-13 18:45:18 +0000471
472 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000473 /* Check to see if the AST represents an expression or not. */
474 res = (self->ast_type == PyAST_EXPR) ? Py_False : Py_True;
475 Py_INCREF(res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000476 }
477 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000478}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000479
480
Fred Drake7a15ba51999-09-09 14:21:52 +0000481#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS)
482
Fred Drake503d8d61998-04-13 18:45:18 +0000483static PyMethodDef
484parser_methods[] = {
Fred Drakeff9ea482000-04-19 13:54:15 +0000485 {"compile", (PyCFunction)parser_compileast, PUBLIC_METHOD_TYPE,
486 "Compile this AST object into a code object."},
487 {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
488 "Determines if this AST object was created from an expression."},
489 {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
490 "Determines if this AST object was created from a suite."},
491 {"tolist", (PyCFunction)parser_ast2list, PUBLIC_METHOD_TYPE,
492 "Creates a list-tree representation of this AST."},
493 {"totuple", (PyCFunction)parser_ast2tuple, PUBLIC_METHOD_TYPE,
494 "Creates a tuple-tree representation of this AST."},
Fred Drake503d8d61998-04-13 18:45:18 +0000495
Fred Drake268397f1998-04-29 14:16:32 +0000496 {NULL, NULL, 0, NULL}
Fred Drake503d8d61998-04-13 18:45:18 +0000497};
498
Fred Drake503d8d61998-04-13 18:45:18 +0000499
500static PyObject*
501parser_getattr(self, name)
502 PyObject *self;
503 char *name;
504{
Fred Drake503d8d61998-04-13 18:45:18 +0000505 return (Py_FindMethod(parser_methods, self, name));
Fred Drakeff9ea482000-04-19 13:54:15 +0000506}
Fred Drake503d8d61998-04-13 18:45:18 +0000507
508
Guido van Rossum3d602e31996-07-21 02:33:56 +0000509/* err_string(char* message)
510 *
511 * Sets the error string for an exception of type ParserError.
512 *
513 */
514static void
515err_string(message)
516 char *message;
Guido van Rossum47478871996-08-21 14:32:37 +0000517{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000518 PyErr_SetString(parser_error, message);
Fred Drakeff9ea482000-04-19 13:54:15 +0000519}
Guido van Rossum3d602e31996-07-21 02:33:56 +0000520
521
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000522/* PyObject* parser_do_parse(PyObject* args, int type)
523 *
524 * Internal function to actually execute the parse and return the result if
525 * successful, or set an exception if not.
526 *
527 */
528static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000529parser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type)
Guido van Rossum47478871996-08-21 14:32:37 +0000530{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000531 char* string = 0;
532 PyObject* res = 0;
533
Fred Drake7a15ba51999-09-09 14:21:52 +0000534 static char *keywords[] = {"source", NULL};
535
536 if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000537 node* n = PyParser_SimpleParseString(string,
538 (type == PyAST_EXPR)
539 ? eval_input : file_input);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000540
Fred Drakeff9ea482000-04-19 13:54:15 +0000541 if (n != 0)
542 res = parser_newastobject(n, type);
543 else
544 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000545 }
546 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000547}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000548
549
550/* PyObject* parser_expr(PyObject* self, PyObject* args)
551 * PyObject* parser_suite(PyObject* self, PyObject* args)
552 *
553 * External interfaces to the parser itself. Which is called determines if
554 * the parser attempts to recognize an expression ('eval' form) or statement
555 * suite ('exec' form). The real work is done by parser_do_parse() above.
556 *
557 */
558static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000559parser_expr(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000560{
Fred Drake268397f1998-04-29 14:16:32 +0000561 NOTE(ARGUNUSED(self))
Fred Drake7a15ba51999-09-09 14:21:52 +0000562 return (parser_do_parse(args, kw, "s:expr", PyAST_EXPR));
Fred Drakeff9ea482000-04-19 13:54:15 +0000563}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000564
565
566static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000567parser_suite(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000568{
Fred Drake268397f1998-04-29 14:16:32 +0000569 NOTE(ARGUNUSED(self))
Fred Drake7a15ba51999-09-09 14:21:52 +0000570 return (parser_do_parse(args, kw, "s:suite", PyAST_SUITE));
Fred Drakeff9ea482000-04-19 13:54:15 +0000571}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000572
573
574
575/* This is the messy part of the code. Conversion from a tuple to an AST
576 * object requires that the input tuple be valid without having to rely on
577 * catching an exception from the compiler. This is done to allow the
578 * compiler itself to remain fast, since most of its input will come from
579 * the parser directly, and therefore be known to be syntactically correct.
580 * This validation is done to ensure that we don't core dump the compile
581 * phase, returning an exception instead.
582 *
583 * Two aspects can be broken out in this code: creating a node tree from
584 * the tuple passed in, and verifying that it is indeed valid. It may be
585 * advantageous to expand the number of AST types to include funcdefs and
586 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
587 * here. They are not necessary, and not quite as useful in a raw form.
588 * For now, let's get expressions and suites working reliably.
589 */
590
591
Fred Drakeff9ea482000-04-19 13:54:15 +0000592staticforward node* build_node_tree(PyObject *tuple);
593staticforward int validate_expr_tree(node *tree);
594staticforward int validate_file_input(node *tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000595
596
597/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
598 *
599 * This is the public function, called from the Python code. It receives a
600 * single tuple object from the caller, and creates an AST object if the
601 * tuple can be validated. It does this by checking the first code of the
602 * tuple, and, if acceptable, builds the internal representation. If this
603 * step succeeds, the internal representation is validated as fully as
604 * possible with the various validate_*() routines defined below.
605 *
606 * This function must be changed if support is to be added for PyAST_FRAGMENT
607 * AST objects.
608 *
609 */
610static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000611parser_tuple2ast(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000612{
Fred Drake268397f1998-04-29 14:16:32 +0000613 NOTE(ARGUNUSED(self))
Guido van Rossum47478871996-08-21 14:32:37 +0000614 PyObject *ast = 0;
615 PyObject *tuple = 0;
616 PyObject *temp = 0;
617 int ok;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000618 int start_sym = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000619
Fred Drake7a15ba51999-09-09 14:21:52 +0000620 static char *keywords[] = {"sequence", NULL};
621
622 if (!PyArg_ParseTupleAndKeywords(args, kw, "O:tuple2ast", keywords,
623 &tuple))
Fred Drakeff9ea482000-04-19 13:54:15 +0000624 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000625 if (!PySequence_Check(tuple)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000626 PyErr_SetString(PyExc_ValueError,
627 "tuple2ast() requires a single sequence argument");
628 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000629 }
630 /*
Fred Drakeff9ea482000-04-19 13:54:15 +0000631 * This mess of tests is written this way so we can use the abstract
632 * object interface (AOI). Unfortunately, the AOI increments reference
633 * counts, which requires that we store a pointer to retrieved object
634 * so we can DECREF it after the check. But we really should accept
635 * lists as well as tuples at the very least.
Guido van Rossum47478871996-08-21 14:32:37 +0000636 */
637 ok = PyObject_Length(tuple) >= 2;
638 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000639 temp = PySequence_GetItem(tuple, 0);
640 ok = (temp != NULL) && PyInt_Check(temp);
641 if (ok)
642 /* this is used after the initial checks: */
643 start_sym = PyInt_AS_LONG(temp);
644 Py_XDECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000645 }
646 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000647 temp = PySequence_GetItem(tuple, 1);
648 ok = (temp != NULL) && PySequence_Check(temp);
649 Py_XDECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000650 }
651 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000652 temp = PySequence_GetItem(tuple, 1);
653 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
654 if (ok) {
655 PyObject *temp2 = PySequence_GetItem(temp, 0);
656 if (temp2 != NULL) {
657 ok = PyInt_Check(temp2);
658 Py_DECREF(temp2);
659 }
660 }
661 Py_XDECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000662 }
663 /* If we've failed at some point, get out of here. */
664 if (!ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000665 err_string("malformed sequence for tuple2ast()");
666 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000667 }
668 /*
669 * This might be a valid parse tree, but let's do a quick check
670 * before we jump the gun.
671 */
672 if (start_sym == eval_input) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000673 /* Might be an eval form. */
674 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000675
Fred Drakeff9ea482000-04-19 13:54:15 +0000676 if ((expression != 0) && validate_expr_tree(expression))
677 ast = parser_newastobject(expression, PyAST_EXPR);
Guido van Rossum47478871996-08-21 14:32:37 +0000678 }
679 else if (start_sym == file_input) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000680 /* This looks like an exec form so far. */
681 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000682
Fred Drakeff9ea482000-04-19 13:54:15 +0000683 if ((suite_tree != 0) && validate_file_input(suite_tree))
684 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000685 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000686 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000687 /* This is a fragment, and is not yet supported. Maybe they
688 * will be if I find a use for them.
689 */
690 err_string("Fragmentary parse trees not supported.");
Guido van Rossum47478871996-08-21 14:32:37 +0000691
692 /* Make sure we throw an exception on all errors. We should never
693 * get this, but we'd do well to be sure something is done.
694 */
695 if ((ast == 0) && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +0000696 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000697
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000698 return (ast);
Fred Drakeff9ea482000-04-19 13:54:15 +0000699}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000700
701
702/* int check_terminal_tuple()
703 *
Guido van Rossum47478871996-08-21 14:32:37 +0000704 * Check a tuple to determine that it is indeed a valid terminal
705 * node. The node is known to be required as a terminal, so we throw
706 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000707 *
Guido van Rossum47478871996-08-21 14:32:37 +0000708 * The format of an acceptable terminal tuple is "(is[i])": the fact
709 * that elem is a tuple and the integer is a valid terminal symbol
710 * has been established before this function is called. We must
711 * check the length of the tuple and the type of the second element
712 * and optional third element. We do *NOT* check the actual text of
713 * the string element, which we could do in many cases. This is done
714 * by the validate_*() functions which operate on the internal
715 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000716 */
717static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000718check_terminal_tuple(PyObject *elem)
Guido van Rossum47478871996-08-21 14:32:37 +0000719{
720 int len = PyObject_Length(elem);
721 int res = 1;
722 char* str = "Illegal terminal symbol; bad node length.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000723
Guido van Rossum47478871996-08-21 14:32:37 +0000724 if ((len == 2) || (len == 3)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000725 PyObject *temp = PySequence_GetItem(elem, 1);
726 res = PyString_Check(temp);
727 str = "Illegal terminal symbol; expected a string.";
728 if (res && (len == 3)) {
729 PyObject* third = PySequence_GetItem(elem, 2);
730 res = PyInt_Check(third);
731 str = "Invalid third element of terminal node.";
732 Py_XDECREF(third);
733 }
734 Py_XDECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000735 }
736 else {
Fred Drakeff9ea482000-04-19 13:54:15 +0000737 res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000738 }
739 if (!res) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000740 elem = Py_BuildValue("(os)", elem, str);
741 PyErr_SetObject(parser_error, elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000742 }
743 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000744}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000745
746
747/* node* build_node_children()
748 *
749 * Iterate across the children of the current non-terminal node and build
750 * their structures. If successful, return the root of this portion of
751 * the tree, otherwise, 0. Any required exception will be specified already,
752 * and no memory will have been deallocated.
753 *
754 */
755static node*
Fred Drakeff9ea482000-04-19 13:54:15 +0000756build_node_children(PyObject *tuple, node *root, int *line_num)
Guido van Rossum47478871996-08-21 14:32:37 +0000757{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000758 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000759 int i;
760
761 for (i = 1; i < len; ++i) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000762 /* elem must always be a tuple, however simple */
763 PyObject* elem = PySequence_GetItem(tuple, i);
764 int ok = elem != NULL;
765 long type = 0;
766 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000767
Fred Drakeff9ea482000-04-19 13:54:15 +0000768 if (ok)
769 ok = PySequence_Check(elem);
770 if (ok) {
771 PyObject *temp = PySequence_GetItem(elem, 0);
772 if (temp == NULL)
773 ok = 0;
774 else {
775 ok = PyInt_Check(temp);
776 if (ok)
777 type = PyInt_AS_LONG(temp);
778 Py_DECREF(temp);
779 }
780 }
781 if (!ok) {
782 PyErr_SetObject(parser_error,
783 Py_BuildValue("(os)", elem,
784 "Illegal node construct."));
785 Py_XDECREF(elem);
786 return (0);
787 }
788 if (ISTERMINAL(type)) {
789 if (check_terminal_tuple(elem)) {
790 PyObject *temp = PySequence_GetItem(elem, 1);
Guido van Rossum47478871996-08-21 14:32:37 +0000791
Fred Drakeff9ea482000-04-19 13:54:15 +0000792 /* check_terminal_tuple() already verified it's a string */
793 strn = (char *)malloc(PyString_GET_SIZE(temp) + 1);
794 if (strn != NULL)
795 (void) strcpy(strn, PyString_AS_STRING(temp));
796 Py_XDECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000797
Fred Drakeff9ea482000-04-19 13:54:15 +0000798 if (PyObject_Length(elem) == 3) {
799 PyObject* temp = PySequence_GetItem(elem, 2);
800 *line_num = PyInt_AsLong(temp);
801 Py_DECREF(temp);
802 }
803 }
804 else {
805 Py_XDECREF(elem);
806 return (0);
807 }
808 }
809 else if (!ISNONTERMINAL(type)) {
810 /*
811 * It has to be one or the other; this is an error.
812 * Throw an exception.
813 */
814 PyErr_SetObject(parser_error,
815 Py_BuildValue("(os)", elem,
816 "Unknown node type."));
817 Py_XDECREF(elem);
818 return (0);
819 }
820 PyNode_AddChild(root, type, strn, *line_num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000821
Fred Drakeff9ea482000-04-19 13:54:15 +0000822 if (ISNONTERMINAL(type)) {
823 node* new_child = CHILD(root, i - 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000824
Fred Drakeff9ea482000-04-19 13:54:15 +0000825 if (new_child != build_node_children(elem, new_child, line_num)) {
826 Py_XDECREF(elem);
827 return (0);
828 }
829 }
830 else if (type == NEWLINE) { /* It's true: we increment the */
831 ++(*line_num); /* line number *after* the newline! */
832 }
833 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000834 }
835 return (root);
Fred Drakeff9ea482000-04-19 13:54:15 +0000836}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000837
838
839static node*
Fred Drakeff9ea482000-04-19 13:54:15 +0000840build_node_tree(PyObject *tuple)
Guido van Rossum47478871996-08-21 14:32:37 +0000841{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000842 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000843 PyObject *temp = PySequence_GetItem(tuple, 0);
844 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000845
Guido van Rossum47478871996-08-21 14:32:37 +0000846 if (temp != NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000847 num = PyInt_AsLong(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000848 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000849 if (ISTERMINAL(num)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000850 /*
851 * The tuple is simple, but it doesn't start with a start symbol.
852 * Throw an exception now and be done with it.
853 */
854 tuple = Py_BuildValue("(os)", tuple,
855 "Illegal ast tuple; cannot start with terminal symbol.");
856 PyErr_SetObject(parser_error, tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000857 }
858 else if (ISNONTERMINAL(num)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000859 /*
860 * Not efficient, but that can be handled later.
861 */
862 int line_num = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000863
Fred Drakeff9ea482000-04-19 13:54:15 +0000864 res = PyNode_New(num);
865 if (res != build_node_children(tuple, res, &line_num)) {
866 PyNode_Free(res);
867 res = 0;
868 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000869 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000870 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000871 /* The tuple is illegal -- if the number is neither TERMINAL nor
872 * NONTERMINAL, we can't use it.
873 */
874 PyErr_SetObject(parser_error,
875 Py_BuildValue("(os)", tuple,
876 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000877
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000878 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000879}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000880
881
Guido van Rossum360a9341996-08-21 19:04:10 +0000882#ifdef HAVE_OLD_CPP
Fred Drakeff9ea482000-04-19 13:54:15 +0000883#define VALIDATER(n) static int validate_/**/n(node *tree)
Guido van Rossum360a9341996-08-21 19:04:10 +0000884#else
Fred Drakeff9ea482000-04-19 13:54:15 +0000885#define VALIDATER(n) static int validate_##n(node *tree)
Guido van Rossum360a9341996-08-21 19:04:10 +0000886#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000887
888
889/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000890 * Validation routines used within the validation section:
891 */
Fred Drakeff9ea482000-04-19 13:54:15 +0000892staticforward int validate_terminal(node *terminal, int type, char *string);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000893
Fred Drakeff9ea482000-04-19 13:54:15 +0000894#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
895#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
896#define validate_colon(ch) validate_terminal(ch, COLON, ":")
897#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
898#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
899#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
900#define validate_indent(ch) validate_terminal(ch, INDENT, (char*)NULL)
901#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
902#define validate_newline(ch) validate_terminal(ch, NEWLINE, (char*)NULL)
903#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
904#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
905#define validate_star(ch) validate_terminal(ch, STAR, "*")
906#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
907#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
908#define validate_dot(ch) validate_terminal(ch, DOT, ".")
909#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000910
Fred Drakeff9ea482000-04-19 13:54:15 +0000911VALIDATER(node); VALIDATER(small_stmt);
912VALIDATER(class); VALIDATER(node);
913VALIDATER(parameters); VALIDATER(suite);
914VALIDATER(testlist); VALIDATER(varargslist);
915VALIDATER(fpdef); VALIDATER(fplist);
916VALIDATER(stmt); VALIDATER(simple_stmt);
917VALIDATER(expr_stmt); VALIDATER(power);
918VALIDATER(print_stmt); VALIDATER(del_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000919VALIDATER(return_stmt);
Fred Drakeff9ea482000-04-19 13:54:15 +0000920VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000921VALIDATER(global_stmt);
Guido van Rossum925e5471997-04-02 05:32:13 +0000922VALIDATER(assert_stmt);
Fred Drakeff9ea482000-04-19 13:54:15 +0000923VALIDATER(exec_stmt); VALIDATER(compound_stmt);
924VALIDATER(while); VALIDATER(for);
925VALIDATER(try); VALIDATER(except_clause);
926VALIDATER(test); VALIDATER(and_test);
927VALIDATER(not_test); VALIDATER(comparison);
928VALIDATER(comp_op); VALIDATER(expr);
929VALIDATER(xor_expr); VALIDATER(and_expr);
930VALIDATER(shift_expr); VALIDATER(arith_expr);
931VALIDATER(term); VALIDATER(factor);
932VALIDATER(atom); VALIDATER(lambdef);
933VALIDATER(trailer); VALIDATER(subscript);
934VALIDATER(subscriptlist); VALIDATER(sliceop);
935VALIDATER(exprlist); VALIDATER(dictmaker);
936VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000937
938
Fred Drakeff9ea482000-04-19 13:54:15 +0000939#define is_even(n) (((n) & 1) == 0)
940#define is_odd(n) (((n) & 1) == 1)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000941
942
943static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000944validate_ntype(node *n, int t)
Guido van Rossum47478871996-08-21 14:32:37 +0000945{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000946 int res = (TYPE(n) == t);
947
948 if (!res) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000949 char buffer[128];
950 (void) sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
951 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000952 }
953 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000954}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000955
956
957static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000958validate_numnodes(node *n, int num, const char *const name)
Guido van Rossum47478871996-08-21 14:32:37 +0000959{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000960 if (NCH(n) != num) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000961 char buff[60];
962 (void) sprintf(buff, "Illegal number of children for %s node.", name);
963 err_string(buff);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000964 }
965 return (NCH(n) == num);
Fred Drakeff9ea482000-04-19 13:54:15 +0000966}
Guido van Rossum3d602e31996-07-21 02:33:56 +0000967
968
969static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000970validate_terminal(node *terminal, int type, char *string)
Guido van Rossum47478871996-08-21 14:32:37 +0000971{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000972 int res = (validate_ntype(terminal, type)
Fred Drakeff9ea482000-04-19 13:54:15 +0000973 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000974
975 if (!res && !PyErr_Occurred()) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000976 char buffer[60];
977 (void) sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
978 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000979 }
980 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000981}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000982
983
Guido van Rossum47478871996-08-21 14:32:37 +0000984/* X (',' X) [',']
985 */
986static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000987validate_repeating_list(node *tree, int ntype, int (*vfunc)(),
988 const char *const name)
Guido van Rossum47478871996-08-21 14:32:37 +0000989{
990 int nch = NCH(tree);
991 int res = (nch && validate_ntype(tree, ntype)
Fred Drakeff9ea482000-04-19 13:54:15 +0000992 && vfunc(CHILD(tree, 0)));
Guido van Rossum47478871996-08-21 14:32:37 +0000993
994 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +0000995 (void) validate_numnodes(tree, 1, name);
Guido van Rossum47478871996-08-21 14:32:37 +0000996 else {
Fred Drakeff9ea482000-04-19 13:54:15 +0000997 if (is_even(nch))
998 res = validate_comma(CHILD(tree, --nch));
999 if (res && nch > 1) {
1000 int pos = 1;
1001 for ( ; res && pos < nch; pos += 2)
1002 res = (validate_comma(CHILD(tree, pos))
1003 && vfunc(CHILD(tree, pos + 1)));
1004 }
Guido van Rossum47478871996-08-21 14:32:37 +00001005 }
1006 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001007}
Guido van Rossum47478871996-08-21 14:32:37 +00001008
1009
Guido van Rossum3d602e31996-07-21 02:33:56 +00001010/* VALIDATE(class)
1011 *
1012 * classdef:
Fred Drakeff9ea482000-04-19 13:54:15 +00001013 * 'class' NAME ['(' testlist ')'] ':' suite
Guido van Rossum3d602e31996-07-21 02:33:56 +00001014 */
Guido van Rossum47478871996-08-21 14:32:37 +00001015static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001016validate_class(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001017{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001018 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001019 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001020
Guido van Rossum3d602e31996-07-21 02:33:56 +00001021 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001022 res = (validate_name(CHILD(tree, 0), "class")
1023 && validate_ntype(CHILD(tree, 1), NAME)
1024 && validate_colon(CHILD(tree, nch - 2))
1025 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001026 }
1027 else
Fred Drakeff9ea482000-04-19 13:54:15 +00001028 (void) validate_numnodes(tree, 4, "class");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001029 if (res && (nch == 7)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001030 res = (validate_lparen(CHILD(tree, 2))
1031 && validate_testlist(CHILD(tree, 3))
1032 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001033 }
1034 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001035}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001036
1037
Guido van Rossum3d602e31996-07-21 02:33:56 +00001038/* if_stmt:
Fred Drakeff9ea482000-04-19 13:54:15 +00001039 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001040 */
Guido van Rossum47478871996-08-21 14:32:37 +00001041static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001042validate_if(node *tree)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001043{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001044 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001045 int res = (validate_ntype(tree, if_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001046 && (nch >= 4)
1047 && validate_name(CHILD(tree, 0), "if")
1048 && validate_test(CHILD(tree, 1))
1049 && validate_colon(CHILD(tree, 2))
1050 && validate_suite(CHILD(tree, 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001051
1052 if (res && ((nch % 4) == 3)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001053 /* ... 'else' ':' suite */
1054 res = (validate_name(CHILD(tree, nch - 3), "else")
1055 && validate_colon(CHILD(tree, nch - 2))
1056 && validate_suite(CHILD(tree, nch - 1)));
1057 nch -= 3;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001058 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001059 else if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00001060 (void) validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001061 if ((nch % 4) != 0)
Fred Drakeff9ea482000-04-19 13:54:15 +00001062 /* Will catch the case for nch < 4 */
1063 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001064 else if (res && (nch > 4)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001065 /* ... ('elif' test ':' suite)+ ... */
1066 int j = 4;
1067 while ((j < nch) && res) {
1068 res = (validate_name(CHILD(tree, j), "elif")
1069 && validate_colon(CHILD(tree, j + 2))
1070 && validate_test(CHILD(tree, j + 1))
1071 && validate_suite(CHILD(tree, j + 3)));
1072 j += 4;
1073 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001074 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001075 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001076}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001077
1078
Guido van Rossum3d602e31996-07-21 02:33:56 +00001079/* parameters:
Fred Drakeff9ea482000-04-19 13:54:15 +00001080 * '(' [varargslist] ')'
Guido van Rossum3d602e31996-07-21 02:33:56 +00001081 *
1082 */
Guido van Rossum47478871996-08-21 14:32:37 +00001083static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001084validate_parameters(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001085{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001086 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001087 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001088
Guido van Rossum3d602e31996-07-21 02:33:56 +00001089 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001090 res = (validate_lparen(CHILD(tree, 0))
1091 && validate_rparen(CHILD(tree, nch - 1)));
1092 if (res && (nch == 3))
1093 res = validate_varargslist(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001094 }
Fred Drakeff9ea482000-04-19 13:54:15 +00001095 else {
1096 (void) validate_numnodes(tree, 2, "parameters");
1097 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001098 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001099}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001100
1101
Guido van Rossum3d602e31996-07-21 02:33:56 +00001102/* VALIDATE(suite)
1103 *
1104 * suite:
Fred Drakeff9ea482000-04-19 13:54:15 +00001105 * simple_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00001106 * | NEWLINE INDENT stmt+ DEDENT
1107 */
Guido van Rossum47478871996-08-21 14:32:37 +00001108static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001109validate_suite(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001110{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001111 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001112 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001113
Guido van Rossum3d602e31996-07-21 02:33:56 +00001114 if (res && (nch == 1))
Fred Drakeff9ea482000-04-19 13:54:15 +00001115 res = validate_simple_stmt(CHILD(tree, 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001116 else if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001117 /* NEWLINE INDENT stmt+ DEDENT */
1118 res = (validate_newline(CHILD(tree, 0))
1119 && validate_indent(CHILD(tree, 1))
1120 && validate_stmt(CHILD(tree, 2))
1121 && validate_dedent(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001122
Fred Drakeff9ea482000-04-19 13:54:15 +00001123 if (res && (nch > 4)) {
1124 int i = 3;
1125 --nch; /* forget the DEDENT */
1126 for ( ; res && (i < nch); ++i)
1127 res = validate_stmt(CHILD(tree, i));
1128 }
1129 else if (nch < 4)
1130 res = validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001131 }
1132 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001133}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001134
1135
Guido van Rossum47478871996-08-21 14:32:37 +00001136static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001137validate_testlist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001138{
Guido van Rossum47478871996-08-21 14:32:37 +00001139 return (validate_repeating_list(tree, testlist,
Fred Drakeff9ea482000-04-19 13:54:15 +00001140 validate_test, "testlist"));
1141}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001142
1143
Guido van Rossum3d602e31996-07-21 02:33:56 +00001144/* VALIDATE(varargslist)
1145 *
1146 * varargslist:
Fred Drakeff9ea482000-04-19 13:54:15 +00001147 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001148 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1149 *
1150 * (fpdef ['=' test] ',')*
1151 * ('*' NAME [',' ('**'|'*' '*') NAME]
1152 * | ('**'|'*' '*') NAME)
1153 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1154 *
1155 */
Guido van Rossum47478871996-08-21 14:32:37 +00001156static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001157validate_varargslist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001158{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001159 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001160 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001161
Guido van Rossum3d602e31996-07-21 02:33:56 +00001162 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001163 /* (fpdef ['=' test] ',')*
1164 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1165 */
1166 int pos = 0;
1167 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001168
Fred Drakeff9ea482000-04-19 13:54:15 +00001169 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1170 res = validate_fpdef(CHILD(tree, pos));
1171 if (res) {
1172 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1173 res = validate_test(CHILD(tree, pos + 2));
1174 pos += 2;
1175 }
1176 res = res && validate_comma(CHILD(tree, pos + 1));
1177 pos += 2;
1178 }
1179 }
1180 if (res) {
1181 remaining = nch - pos;
1182 res = ((remaining == 2) || (remaining == 3)
1183 || (remaining == 5) || (remaining == 6));
1184 if (!res)
1185 (void) validate_numnodes(tree, 2, "varargslist");
1186 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1187 return ((remaining == 2)
1188 && validate_ntype(CHILD(tree, pos+1), NAME));
1189 else {
1190 res = validate_star(CHILD(tree, pos++));
1191 --remaining;
1192 }
1193 }
1194 if (res) {
1195 if (remaining == 2) {
1196 res = (validate_star(CHILD(tree, pos))
1197 && validate_ntype(CHILD(tree, pos + 1), NAME));
1198 }
1199 else {
1200 res = validate_ntype(CHILD(tree, pos++), NAME);
1201 if (res && (remaining >= 4)) {
1202 res = validate_comma(CHILD(tree, pos));
1203 if (--remaining == 3)
1204 res = (validate_star(CHILD(tree, pos + 1))
1205 && validate_star(CHILD(tree, pos + 2)));
1206 else
1207 res = validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1208 }
1209 }
1210 }
1211 if (!res && !PyErr_Occurred())
1212 err_string("Incorrect validation of variable arguments list.");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001213 }
1214 else if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001215 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1216 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1217 --nch;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001218
Fred Drakeff9ea482000-04-19 13:54:15 +00001219 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1220 res = (is_odd(nch)
1221 && validate_fpdef(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001222
Fred Drakeff9ea482000-04-19 13:54:15 +00001223 if (res && (nch > 1)) {
1224 int pos = 1;
1225 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1226 res = validate_test(CHILD(tree, 2));
1227 pos += 2;
1228 }
1229 /* ... (',' fpdef ['=' test])* */
1230 for ( ; res && (pos < nch); pos += 2) {
1231 /* ',' fpdef */
1232 res = (validate_comma(CHILD(tree, pos))
1233 && validate_fpdef(CHILD(tree, pos + 1)));
1234 if (res
1235 && ((nch - pos) > 2)
1236 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1237 /* ['=' test] */
1238 res = validate_test(CHILD(tree, pos + 3));
1239 pos += 2;
1240 }
1241 }
1242 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001243 }
Fred Drakeff9ea482000-04-19 13:54:15 +00001244 else {
1245 err_string("Improperly formed argument list.");
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
Guido van Rossum3d602e31996-07-21 02:33:56 +00001251/* VALIDATE(fpdef)
1252 *
1253 * fpdef:
Fred Drakeff9ea482000-04-19 13:54:15 +00001254 * NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00001255 * | '(' fplist ')'
1256 */
Guido van Rossum47478871996-08-21 14:32:37 +00001257static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001258validate_fpdef(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, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001262
Guido van Rossum3d602e31996-07-21 02:33:56 +00001263 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001264 if (nch == 1)
1265 res = validate_ntype(CHILD(tree, 0), NAME);
1266 else if (nch == 3)
1267 res = (validate_lparen(CHILD(tree, 0))
1268 && validate_fplist(CHILD(tree, 1))
1269 && validate_rparen(CHILD(tree, 2)));
1270 else
1271 res = validate_numnodes(tree, 1, "fpdef");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001272 }
1273 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001274}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001275
1276
Guido van Rossum47478871996-08-21 14:32:37 +00001277static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001278validate_fplist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001279{
Guido van Rossum47478871996-08-21 14:32:37 +00001280 return (validate_repeating_list(tree, fplist,
Fred Drakeff9ea482000-04-19 13:54:15 +00001281 validate_fpdef, "fplist"));
1282}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001283
1284
Guido van Rossum3d602e31996-07-21 02:33:56 +00001285/* simple_stmt | compound_stmt
1286 *
1287 */
Guido van Rossum47478871996-08-21 14:32:37 +00001288static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001289validate_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001290{
1291 int res = (validate_ntype(tree, stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001292 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001293
Guido van Rossum3d602e31996-07-21 02:33:56 +00001294 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001295 tree = CHILD(tree, 0);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001296
Fred Drakeff9ea482000-04-19 13:54:15 +00001297 if (TYPE(tree) == simple_stmt)
1298 res = validate_simple_stmt(tree);
1299 else
1300 res = validate_compound_stmt(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001301 }
1302 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001303}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001304
1305
Guido van Rossum3d602e31996-07-21 02:33:56 +00001306/* small_stmt (';' small_stmt)* [';'] NEWLINE
1307 *
1308 */
Guido van Rossum47478871996-08-21 14:32:37 +00001309static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001310validate_simple_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001311{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001312 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001313 int res = (validate_ntype(tree, simple_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001314 && (nch >= 2)
1315 && validate_small_stmt(CHILD(tree, 0))
1316 && validate_newline(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001317
Guido van Rossum3d602e31996-07-21 02:33:56 +00001318 if (nch < 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001319 res = validate_numnodes(tree, 2, "simple_stmt");
1320 --nch; /* forget the NEWLINE */
Guido van Rossum3d602e31996-07-21 02:33:56 +00001321 if (res && is_even(nch))
Fred Drakeff9ea482000-04-19 13:54:15 +00001322 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001323 if (res && (nch > 2)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001324 int i;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001325
Fred Drakeff9ea482000-04-19 13:54:15 +00001326 for (i = 1; res && (i < nch); i += 2)
1327 res = (validate_semi(CHILD(tree, i))
1328 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001329 }
1330 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001331}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001332
1333
Guido van Rossum47478871996-08-21 14:32:37 +00001334static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001335validate_small_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001336{
1337 int nch = NCH(tree);
Fred Drakeff9ea482000-04-19 13:54:15 +00001338 int res = (validate_numnodes(tree, 1, "small_stmt")
1339 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1340 || (TYPE(CHILD(tree, 0)) == print_stmt)
1341 || (TYPE(CHILD(tree, 0)) == del_stmt)
1342 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1343 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1344 || (TYPE(CHILD(tree, 0)) == import_stmt)
1345 || (TYPE(CHILD(tree, 0)) == global_stmt)
1346 || (TYPE(CHILD(tree, 0)) == assert_stmt)
1347 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001348
1349 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001350 res = validate_node(CHILD(tree, 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001351 else if (nch == 1) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001352 char buffer[60];
1353 (void) sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1354 TYPE(CHILD(tree, 0)));
1355 err_string(buffer);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001356 }
1357 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001358}
Guido van Rossum3d602e31996-07-21 02:33:56 +00001359
1360
1361/* compound_stmt:
Fred Drakeff9ea482000-04-19 13:54:15 +00001362 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
Guido van Rossum3d602e31996-07-21 02:33:56 +00001363 */
Guido van Rossum47478871996-08-21 14:32:37 +00001364static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001365validate_compound_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001366{
1367 int res = (validate_ntype(tree, compound_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001368 && validate_numnodes(tree, 1, "compound_stmt"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001369
1370 if (!res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001371 return (0);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001372
1373 tree = CHILD(tree, 0);
1374 res = ((TYPE(tree) == if_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001375 || (TYPE(tree) == while_stmt)
1376 || (TYPE(tree) == for_stmt)
1377 || (TYPE(tree) == try_stmt)
1378 || (TYPE(tree) == funcdef)
1379 || (TYPE(tree) == classdef));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001380 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001381 res = validate_node(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001382 else {
Fred Drakeff9ea482000-04-19 13:54:15 +00001383 char buffer[60];
1384 (void) sprintf(buffer, "Illegal compound statement type: %d.",
1385 TYPE(tree));
1386 err_string(buffer);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001387 }
1388 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001389}
Guido van Rossum3d602e31996-07-21 02:33:56 +00001390
1391
Guido van Rossum47478871996-08-21 14:32:37 +00001392static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001393validate_expr_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001394{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001395 int j;
1396 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001397 int res = (validate_ntype(tree, expr_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001398 && is_odd(nch)
1399 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001400
Guido van Rossum3d602e31996-07-21 02:33:56 +00001401 for (j = 1; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001402 res = (validate_equal(CHILD(tree, j))
1403 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001404
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001405 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001406}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001407
1408
Guido van Rossum3d602e31996-07-21 02:33:56 +00001409/* print_stmt:
1410 *
Fred Drakeff9ea482000-04-19 13:54:15 +00001411 * 'print' (test ',')* [test]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001412 *
1413 */
Guido van Rossum47478871996-08-21 14:32:37 +00001414static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001415validate_print_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001416{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001417 int j;
1418 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001419 int res = (validate_ntype(tree, print_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001420 && (nch != 0)
1421 && validate_name(CHILD(tree, 0), "print"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001422
1423 if (res && is_even(nch)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001424 res = validate_test(CHILD(tree, nch - 1));
1425 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001426 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001427 else if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00001428 (void) validate_numnodes(tree, 1, "print_stmt");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001429 for (j = 1; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001430 res = (validate_test(CHILD(tree, j))
1431 && validate_ntype(CHILD(tree, j + 1), COMMA));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001432
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001433 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001434}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001435
1436
Guido van Rossum47478871996-08-21 14:32:37 +00001437static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001438validate_del_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001439{
1440 return (validate_numnodes(tree, 2, "del_stmt")
Fred Drakeff9ea482000-04-19 13:54:15 +00001441 && validate_name(CHILD(tree, 0), "del")
1442 && validate_exprlist(CHILD(tree, 1)));
1443}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001444
1445
Guido van Rossum47478871996-08-21 14:32:37 +00001446static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001447validate_return_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001448{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001449 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001450 int res = (validate_ntype(tree, return_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001451 && ((nch == 1) || (nch == 2))
1452 && validate_name(CHILD(tree, 0), "return"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001453
Guido van Rossum3d602e31996-07-21 02:33:56 +00001454 if (res && (nch == 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00001455 res = validate_testlist(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001456
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001457 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001458}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001459
1460
Guido van Rossum47478871996-08-21 14:32:37 +00001461static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001462validate_raise_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001463{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001464 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001465 int res = (validate_ntype(tree, raise_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001466 && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001467
Guido van Rossum3d602e31996-07-21 02:33:56 +00001468 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001469 res = validate_name(CHILD(tree, 0), "raise");
1470 if (res && (nch >= 2))
1471 res = validate_test(CHILD(tree, 1));
1472 if (res && nch > 2) {
1473 res = (validate_comma(CHILD(tree, 2))
1474 && validate_test(CHILD(tree, 3)));
1475 if (res && (nch > 4))
1476 res = (validate_comma(CHILD(tree, 4))
1477 && validate_test(CHILD(tree, 5)));
1478 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001479 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001480 else
Fred Drakeff9ea482000-04-19 13:54:15 +00001481 (void) validate_numnodes(tree, 2, "raise");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001482 if (res && (nch == 4))
Fred Drakeff9ea482000-04-19 13:54:15 +00001483 res = (validate_comma(CHILD(tree, 2))
1484 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001485
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001486 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001487}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001488
1489
Guido van Rossum3d602e31996-07-21 02:33:56 +00001490/* import_stmt:
1491 *
1492 * 'import' dotted_name (',' dotted_name)*
1493 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1494 */
Guido van Rossum47478871996-08-21 14:32:37 +00001495static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001496validate_import_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001497{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001498 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001499 int res = (validate_ntype(tree, import_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001500 && (nch >= 2) && is_even(nch)
1501 && validate_ntype(CHILD(tree, 0), NAME)
1502 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001503
1504 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001505 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001506
Fred Drakeff9ea482000-04-19 13:54:15 +00001507 for (j = 2; res && (j < nch); j += 2)
1508 res = (validate_comma(CHILD(tree, j))
1509 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001510 }
1511 else if (res && validate_name(CHILD(tree, 0), "from")) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001512 res = ((nch >= 4) && is_even(nch)
1513 && validate_name(CHILD(tree, 2), "import"));
1514 if (nch == 4) {
1515 res = ((TYPE(CHILD(tree, 3)) == NAME)
1516 || (TYPE(CHILD(tree, 3)) == STAR));
1517 if (!res)
1518 err_string("Illegal import statement.");
1519 }
1520 else {
1521 /* 'from' NAME 'import' NAME (',' NAME)+ */
1522 int j;
1523 res = validate_ntype(CHILD(tree, 3), NAME);
1524 for (j = 4; res && (j < nch); j += 2)
1525 res = (validate_comma(CHILD(tree, j))
1526 && validate_ntype(CHILD(tree, j + 1), NAME));
1527 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001528 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001529 else
Fred Drakeff9ea482000-04-19 13:54:15 +00001530 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001531
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001532 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001533}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001534
1535
Guido van Rossum47478871996-08-21 14:32:37 +00001536static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001537validate_global_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001538{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001539 int j;
1540 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001541 int res = (validate_ntype(tree, global_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001542 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001543
Guido van Rossum3d602e31996-07-21 02:33:56 +00001544 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001545 res = (validate_name(CHILD(tree, 0), "global")
1546 && validate_ntype(CHILD(tree, 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001547 for (j = 2; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001548 res = (validate_comma(CHILD(tree, j))
1549 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001550
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001551 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001552}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001553
1554
Guido van Rossum3d602e31996-07-21 02:33:56 +00001555/* exec_stmt:
1556 *
1557 * 'exec' expr ['in' test [',' test]]
1558 */
Guido van Rossum47478871996-08-21 14:32:37 +00001559static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001560validate_exec_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001561{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001562 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001563 int res = (validate_ntype(tree, exec_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001564 && ((nch == 2) || (nch == 4) || (nch == 6))
1565 && validate_name(CHILD(tree, 0), "exec")
1566 && validate_expr(CHILD(tree, 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001567
Guido van Rossum3d602e31996-07-21 02:33:56 +00001568 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00001569 err_string("Illegal exec statement.");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001570 if (res && (nch > 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00001571 res = (validate_name(CHILD(tree, 2), "in")
1572 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001573 if (res && (nch == 6))
Fred Drakeff9ea482000-04-19 13:54:15 +00001574 res = (validate_comma(CHILD(tree, 4))
1575 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001576
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001577 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001578}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001579
1580
Guido van Rossum925e5471997-04-02 05:32:13 +00001581/* assert_stmt:
1582 *
1583 * 'assert' test [',' test]
1584 */
1585static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001586validate_assert_stmt(node *tree)
Guido van Rossum925e5471997-04-02 05:32:13 +00001587{
1588 int nch = NCH(tree);
1589 int res = (validate_ntype(tree, assert_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001590 && ((nch == 2) || (nch == 4))
1591 && (validate_name(CHILD(tree, 0), "__assert__") ||
1592 validate_name(CHILD(tree, 0), "assert"))
1593 && validate_test(CHILD(tree, 1)));
Guido van Rossum925e5471997-04-02 05:32:13 +00001594
1595 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00001596 err_string("Illegal assert statement.");
Guido van Rossum925e5471997-04-02 05:32:13 +00001597 if (res && (nch > 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00001598 res = (validate_comma(CHILD(tree, 2))
1599 && validate_test(CHILD(tree, 3)));
Guido van Rossum925e5471997-04-02 05:32:13 +00001600
1601 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001602}
Guido van Rossum925e5471997-04-02 05:32:13 +00001603
1604
Guido van Rossum47478871996-08-21 14:32:37 +00001605static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001606validate_while(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001607{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001608 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001609 int res = (validate_ntype(tree, while_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001610 && ((nch == 4) || (nch == 7))
1611 && validate_name(CHILD(tree, 0), "while")
1612 && validate_test(CHILD(tree, 1))
1613 && validate_colon(CHILD(tree, 2))
1614 && validate_suite(CHILD(tree, 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001615
Guido van Rossum3d602e31996-07-21 02:33:56 +00001616 if (res && (nch == 7))
Fred Drakeff9ea482000-04-19 13:54:15 +00001617 res = (validate_name(CHILD(tree, 4), "else")
1618 && validate_colon(CHILD(tree, 5))
1619 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001620
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001621 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001622}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001623
1624
Guido van Rossum47478871996-08-21 14:32:37 +00001625static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001626validate_for(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001627{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001628 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001629 int res = (validate_ntype(tree, for_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001630 && ((nch == 6) || (nch == 9))
1631 && validate_name(CHILD(tree, 0), "for")
1632 && validate_exprlist(CHILD(tree, 1))
1633 && validate_name(CHILD(tree, 2), "in")
1634 && validate_testlist(CHILD(tree, 3))
1635 && validate_colon(CHILD(tree, 4))
1636 && validate_suite(CHILD(tree, 5)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001637
Guido van Rossum3d602e31996-07-21 02:33:56 +00001638 if (res && (nch == 9))
Fred Drakeff9ea482000-04-19 13:54:15 +00001639 res = (validate_name(CHILD(tree, 6), "else")
1640 && validate_colon(CHILD(tree, 7))
1641 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001642
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001643 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001644}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001645
1646
Guido van Rossum3d602e31996-07-21 02:33:56 +00001647/* try_stmt:
Fred Drakeff9ea482000-04-19 13:54:15 +00001648 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001649 * | 'try' ':' suite 'finally' ':' suite
1650 *
1651 */
Guido van Rossum47478871996-08-21 14:32:37 +00001652static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001653validate_try(tree)
1654 node *tree;
1655{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001656 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001657 int pos = 3;
1658 int res = (validate_ntype(tree, try_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001659 && (nch >= 6) && ((nch % 3) == 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001660
1661 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001662 res = (validate_name(CHILD(tree, 0), "try")
1663 && validate_colon(CHILD(tree, 1))
1664 && validate_suite(CHILD(tree, 2))
1665 && validate_colon(CHILD(tree, nch - 2))
1666 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001667 else {
Fred Drakeff9ea482000-04-19 13:54:15 +00001668 const char* name = "execpt";
1669 char buffer[60];
1670 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1671 name = STR(CHILD(tree, nch - 3));
1672 (void) sprintf(buffer,
1673 "Illegal number of children for try/%s node.", name);
1674 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001675 }
Fred Drakeff9ea482000-04-19 13:54:15 +00001676 /* Skip past except_clause sections: */
Guido van Rossum3d602e31996-07-21 02:33:56 +00001677 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001678 res = (validate_except_clause(CHILD(tree, pos))
1679 && validate_colon(CHILD(tree, pos + 1))
1680 && validate_suite(CHILD(tree, pos + 2)));
1681 pos += 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001682 }
1683 if (res && (pos < nch)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001684 res = validate_ntype(CHILD(tree, pos), NAME);
1685 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1686 res = (validate_numnodes(tree, 6, "try/finally")
1687 && validate_colon(CHILD(tree, 4))
1688 && validate_suite(CHILD(tree, 5)));
1689 else if (res) {
1690 if (nch == (pos + 3)) {
1691 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1692 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1693 if (!res)
1694 err_string("Illegal trailing triple in try statement.");
1695 }
1696 else if (nch == (pos + 6)) {
1697 res = (validate_name(CHILD(tree, pos), "except")
1698 && validate_colon(CHILD(tree, pos + 1))
1699 && validate_suite(CHILD(tree, pos + 2))
1700 && validate_name(CHILD(tree, pos + 3), "else"));
1701 }
1702 else
1703 res = validate_numnodes(tree, pos + 3, "try/except");
1704 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001705 }
1706 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001707}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001708
1709
Guido van Rossum47478871996-08-21 14:32:37 +00001710static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001711validate_except_clause(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, except_clause)
Fred Drakeff9ea482000-04-19 13:54:15 +00001715 && ((nch == 1) || (nch == 2) || (nch == 4))
1716 && validate_name(CHILD(tree, 0), "except"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001717
Guido van Rossum3d602e31996-07-21 02:33:56 +00001718 if (res && (nch > 1))
Fred Drakeff9ea482000-04-19 13:54:15 +00001719 res = validate_test(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001720 if (res && (nch == 4))
Fred Drakeff9ea482000-04-19 13:54:15 +00001721 res = (validate_comma(CHILD(tree, 2))
1722 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001723
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001724 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001725}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001726
1727
Guido van Rossum47478871996-08-21 14:32:37 +00001728static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001729validate_test(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001730{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001731 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001732 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001733
Guido van Rossum3d602e31996-07-21 02:33:56 +00001734 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Fred Drakeff9ea482000-04-19 13:54:15 +00001735 res = ((nch == 1)
1736 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001737 else if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001738 int pos;
1739 res = validate_and_test(CHILD(tree, 0));
1740 for (pos = 1; res && (pos < nch); pos += 2)
1741 res = (validate_name(CHILD(tree, pos), "or")
1742 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001743 }
1744 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001745}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001746
1747
Guido van Rossum47478871996-08-21 14:32:37 +00001748static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001749validate_and_test(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001750{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001751 int pos;
1752 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001753 int res = (validate_ntype(tree, and_test)
Fred Drakeff9ea482000-04-19 13:54:15 +00001754 && is_odd(nch)
1755 && validate_not_test(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001756
Guido van Rossum3d602e31996-07-21 02:33:56 +00001757 for (pos = 1; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001758 res = (validate_name(CHILD(tree, pos), "and")
1759 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001760
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001761 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001762}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001763
1764
Guido van Rossum47478871996-08-21 14:32:37 +00001765static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001766validate_not_test(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001767{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001768 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001769 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001770
Guido van Rossum3d602e31996-07-21 02:33:56 +00001771 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001772 if (nch == 2)
1773 res = (validate_name(CHILD(tree, 0), "not")
1774 && validate_not_test(CHILD(tree, 1)));
1775 else if (nch == 1)
1776 res = validate_comparison(CHILD(tree, 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001777 }
1778 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001779}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001780
1781
Guido van Rossum47478871996-08-21 14:32:37 +00001782static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001783validate_comparison(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001784{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001785 int pos;
1786 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001787 int res = (validate_ntype(tree, comparison)
Fred Drakeff9ea482000-04-19 13:54:15 +00001788 && is_odd(nch)
1789 && validate_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001790
Guido van Rossum3d602e31996-07-21 02:33:56 +00001791 for (pos = 1; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001792 res = (validate_comp_op(CHILD(tree, pos))
1793 && validate_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001794
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001795 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001796}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001797
1798
Guido van Rossum47478871996-08-21 14:32:37 +00001799static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001800validate_comp_op(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001801{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001802 int res = 0;
1803 int nch = NCH(tree);
1804
Guido van Rossum3d602e31996-07-21 02:33:56 +00001805 if (!validate_ntype(tree, comp_op))
Fred Drakeff9ea482000-04-19 13:54:15 +00001806 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001807 if (nch == 1) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001808 /*
1809 * Only child will be a terminal with a well-defined symbolic name
1810 * or a NAME with a string of either 'is' or 'in'
1811 */
1812 tree = CHILD(tree, 0);
1813 switch (TYPE(tree)) {
1814 case LESS:
1815 case GREATER:
1816 case EQEQUAL:
1817 case EQUAL:
1818 case LESSEQUAL:
1819 case GREATEREQUAL:
1820 case NOTEQUAL:
1821 res = 1;
1822 break;
1823 case NAME:
1824 res = ((strcmp(STR(tree), "in") == 0)
1825 || (strcmp(STR(tree), "is") == 0));
1826 if (!res) {
1827 char buff[128];
1828 (void) sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1829 err_string(buff);
1830 }
1831 break;
1832 default:
1833 err_string("Illegal comparison operator type.");
1834 break;
1835 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001836 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001837 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001838 res = (validate_ntype(CHILD(tree, 0), NAME)
1839 && validate_ntype(CHILD(tree, 1), NAME)
1840 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1841 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1842 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1843 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
1844 if (!res && !PyErr_Occurred())
1845 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001846 }
1847 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001848}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001849
1850
Guido van Rossum47478871996-08-21 14:32:37 +00001851static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001852validate_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001853{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001854 int j;
1855 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001856 int res = (validate_ntype(tree, expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00001857 && is_odd(nch)
1858 && validate_xor_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001859
Guido van Rossum3d602e31996-07-21 02:33:56 +00001860 for (j = 2; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001861 res = (validate_xor_expr(CHILD(tree, j))
1862 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001863
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001864 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001865}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001866
1867
Guido van Rossum47478871996-08-21 14:32:37 +00001868static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001869validate_xor_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001870{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001871 int j;
1872 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001873 int res = (validate_ntype(tree, xor_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00001874 && is_odd(nch)
1875 && validate_and_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001876
Guido van Rossum3d602e31996-07-21 02:33:56 +00001877 for (j = 2; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001878 res = (validate_circumflex(CHILD(tree, j - 1))
1879 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001880
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001881 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001882}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001883
1884
Guido van Rossum47478871996-08-21 14:32:37 +00001885static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001886validate_and_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001887{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001888 int pos;
1889 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001890 int res = (validate_ntype(tree, and_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00001891 && is_odd(nch)
1892 && validate_shift_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001893
Guido van Rossum3d602e31996-07-21 02:33:56 +00001894 for (pos = 1; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001895 res = (validate_ampersand(CHILD(tree, pos))
1896 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001897
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001898 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001899}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001900
1901
1902static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001903validate_chain_two_ops(tree, termvalid, op1, op2)
1904 node *tree;
1905 int (*termvalid)();
1906 int op1;
1907 int op2;
1908 {
1909 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001910 int nch = NCH(tree);
1911 int res = (is_odd(nch)
Fred Drakeff9ea482000-04-19 13:54:15 +00001912 && (*termvalid)(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001913
Guido van Rossum3d602e31996-07-21 02:33:56 +00001914 for ( ; res && (pos < nch); pos += 2) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001915 if (TYPE(CHILD(tree, pos)) != op1)
1916 res = validate_ntype(CHILD(tree, pos), op2);
1917 if (res)
1918 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001919 }
1920 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001921}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001922
1923
Guido van Rossum47478871996-08-21 14:32:37 +00001924static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001925validate_shift_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001926{
1927 return (validate_ntype(tree, shift_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00001928 && validate_chain_two_ops(tree, validate_arith_expr,
1929 LEFTSHIFT, RIGHTSHIFT));
1930}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001931
1932
Guido van Rossum47478871996-08-21 14:32:37 +00001933static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001934validate_arith_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001935{
1936 return (validate_ntype(tree, arith_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00001937 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
1938}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001939
1940
Guido van Rossum47478871996-08-21 14:32:37 +00001941static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001942validate_term(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001943{
1944 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001945 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001946 int res = (validate_ntype(tree, term)
Fred Drakeff9ea482000-04-19 13:54:15 +00001947 && is_odd(nch)
1948 && validate_factor(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001949
Guido van Rossum3d602e31996-07-21 02:33:56 +00001950 for ( ; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001951 res = (((TYPE(CHILD(tree, pos)) == STAR)
1952 || (TYPE(CHILD(tree, pos)) == SLASH)
1953 || (TYPE(CHILD(tree, pos)) == PERCENT))
1954 && validate_factor(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001955
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001956 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001957}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001958
1959
Guido van Rossum3d602e31996-07-21 02:33:56 +00001960/* factor:
1961 *
1962 * factor: ('+'|'-'|'~') factor | power
1963 */
Guido van Rossum47478871996-08-21 14:32:37 +00001964static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001965validate_factor(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001966{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001967 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001968 int res = (validate_ntype(tree, factor)
Fred Drakeff9ea482000-04-19 13:54:15 +00001969 && (((nch == 2)
1970 && ((TYPE(CHILD(tree, 0)) == PLUS)
1971 || (TYPE(CHILD(tree, 0)) == MINUS)
1972 || (TYPE(CHILD(tree, 0)) == TILDE))
1973 && validate_factor(CHILD(tree, 1)))
1974 || ((nch == 1)
1975 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001976 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001977}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001978
1979
Guido van Rossum3d602e31996-07-21 02:33:56 +00001980/* power:
1981 *
1982 * power: atom trailer* ('**' factor)*
1983 */
Guido van Rossum47478871996-08-21 14:32:37 +00001984static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001985validate_power(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001986{
1987 int pos = 1;
1988 int nch = NCH(tree);
1989 int res = (validate_ntype(tree, power) && (nch >= 1)
Fred Drakeff9ea482000-04-19 13:54:15 +00001990 && validate_atom(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001991
1992 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
Fred Drakeff9ea482000-04-19 13:54:15 +00001993 res = validate_trailer(CHILD(tree, pos++));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001994 if (res && (pos < nch)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001995 if (!is_even(nch - pos)) {
1996 err_string("Illegal number of nodes for 'power'.");
1997 return (0);
1998 }
1999 for ( ; res && (pos < (nch - 1)); pos += 2)
2000 res = (validate_doublestar(CHILD(tree, pos))
2001 && validate_factor(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002002 }
2003 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002004}
Guido van Rossum3d602e31996-07-21 02:33:56 +00002005
2006
Guido van Rossum47478871996-08-21 14:32:37 +00002007static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002008validate_atom(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002009{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002010 int pos;
2011 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002012 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002013
2014 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002015 switch (TYPE(CHILD(tree, 0))) {
2016 case LPAR:
2017 res = ((nch <= 3)
2018 && (validate_rparen(CHILD(tree, nch - 1))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002019
Fred Drakeff9ea482000-04-19 13:54:15 +00002020 if (res && (nch == 3))
2021 res = validate_testlist(CHILD(tree, 1));
2022 break;
2023 case LSQB:
2024 res = ((nch <= 3)
2025 && validate_ntype(CHILD(tree, nch - 1), RSQB));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002026
Fred Drakeff9ea482000-04-19 13:54:15 +00002027 if (res && (nch == 3))
2028 res = validate_testlist(CHILD(tree, 1));
2029 break;
2030 case LBRACE:
2031 res = ((nch <= 3)
2032 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002033
Fred Drakeff9ea482000-04-19 13:54:15 +00002034 if (res && (nch == 3))
2035 res = validate_dictmaker(CHILD(tree, 1));
2036 break;
2037 case BACKQUOTE:
2038 res = ((nch == 3)
2039 && validate_testlist(CHILD(tree, 1))
2040 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2041 break;
2042 case NAME:
2043 case NUMBER:
2044 res = (nch == 1);
2045 break;
2046 case STRING:
2047 for (pos = 1; res && (pos < nch); ++pos)
2048 res = validate_ntype(CHILD(tree, pos), STRING);
2049 break;
2050 default:
2051 res = 0;
2052 break;
2053 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002054 }
2055 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002056}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002057
2058
Guido van Rossum3d602e31996-07-21 02:33:56 +00002059/* funcdef:
Fred Drakeff9ea482000-04-19 13:54:15 +00002060 * 'def' NAME parameters ':' suite
Guido van Rossum3d602e31996-07-21 02:33:56 +00002061 *
2062 */
Guido van Rossum47478871996-08-21 14:32:37 +00002063static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002064validate_funcdef(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002065{
2066 return (validate_ntype(tree, funcdef)
Fred Drakeff9ea482000-04-19 13:54:15 +00002067 && validate_numnodes(tree, 5, "funcdef")
2068 && validate_name(CHILD(tree, 0), "def")
2069 && validate_ntype(CHILD(tree, 1), NAME)
2070 && validate_colon(CHILD(tree, 3))
2071 && validate_parameters(CHILD(tree, 2))
2072 && validate_suite(CHILD(tree, 4)));
2073}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002074
2075
Guido van Rossum47478871996-08-21 14:32:37 +00002076static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002077validate_lambdef(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002078{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002079 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002080 int res = (validate_ntype(tree, lambdef)
Fred Drakeff9ea482000-04-19 13:54:15 +00002081 && ((nch == 3) || (nch == 4))
2082 && validate_name(CHILD(tree, 0), "lambda")
2083 && validate_colon(CHILD(tree, nch - 2))
2084 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002085
Guido van Rossum3d602e31996-07-21 02:33:56 +00002086 if (res && (nch == 4))
Fred Drakeff9ea482000-04-19 13:54:15 +00002087 res = validate_varargslist(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002088 else if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00002089 (void) validate_numnodes(tree, 3, "lambdef");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002090
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002091 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002092}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002093
2094
Guido van Rossum3d602e31996-07-21 02:33:56 +00002095/* arglist:
2096 *
2097 * argument (',' argument)* [',']
2098 */
Guido van Rossum47478871996-08-21 14:32:37 +00002099static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002100validate_arglist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002101{
Guido van Rossum47478871996-08-21 14:32:37 +00002102 return (validate_repeating_list(tree, arglist,
Fred Drakeff9ea482000-04-19 13:54:15 +00002103 validate_argument, "arglist"));
2104}
Guido van Rossum3d602e31996-07-21 02:33:56 +00002105
2106
2107
2108/* argument:
2109 *
2110 * [test '='] test
2111 */
Guido van Rossum47478871996-08-21 14:32:37 +00002112static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002113validate_argument(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002114{
2115 int nch = NCH(tree);
2116 int res = (validate_ntype(tree, argument)
Fred Drakeff9ea482000-04-19 13:54:15 +00002117 && ((nch == 1) || (nch == 3))
2118 && validate_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002119
2120 if (res && (nch == 3))
Fred Drakeff9ea482000-04-19 13:54:15 +00002121 res = (validate_equal(CHILD(tree, 1))
2122 && validate_test(CHILD(tree, 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002123
2124 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002125}
Guido van Rossum3d602e31996-07-21 02:33:56 +00002126
2127
2128
2129/* trailer:
2130 *
Guido van Rossum47478871996-08-21 14:32:37 +00002131 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002132 */
Guido van Rossum47478871996-08-21 14:32:37 +00002133static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002134validate_trailer(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002135{
2136 int nch = NCH(tree);
2137 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002138
2139 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002140 switch (TYPE(CHILD(tree, 0))) {
2141 case LPAR:
2142 res = validate_rparen(CHILD(tree, nch - 1));
2143 if (res && (nch == 3))
2144 res = validate_arglist(CHILD(tree, 1));
2145 break;
2146 case LSQB:
2147 res = (validate_numnodes(tree, 3, "trailer")
2148 && validate_subscriptlist(CHILD(tree, 1))
2149 && validate_ntype(CHILD(tree, 2), RSQB));
2150 break;
2151 case DOT:
2152 res = (validate_numnodes(tree, 2, "trailer")
2153 && validate_ntype(CHILD(tree, 1), NAME));
2154 break;
2155 default:
2156 res = 0;
2157 break;
2158 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002159 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002160 else {
2161 (void) validate_numnodes(tree, 2, "trailer");
2162 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002163 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002164}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002165
2166
Guido van Rossum47478871996-08-21 14:32:37 +00002167/* subscriptlist:
2168 *
2169 * subscript (',' subscript)* [',']
2170 */
2171static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002172validate_subscriptlist(node *tree)
Guido van Rossum47478871996-08-21 14:32:37 +00002173{
2174 return (validate_repeating_list(tree, subscriptlist,
Fred Drakeff9ea482000-04-19 13:54:15 +00002175 validate_subscript, "subscriptlist"));
2176}
Guido van Rossum47478871996-08-21 14:32:37 +00002177
2178
Guido van Rossum3d602e31996-07-21 02:33:56 +00002179/* subscript:
2180 *
Guido van Rossum47478871996-08-21 14:32:37 +00002181 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002182 */
Guido van Rossum47478871996-08-21 14:32:37 +00002183static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002184validate_subscript(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002185{
Guido van Rossum47478871996-08-21 14:32:37 +00002186 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002187 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002188 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002189
Guido van Rossum47478871996-08-21 14:32:37 +00002190 if (!res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002191 if (!PyErr_Occurred())
2192 err_string("invalid number of arguments for subscript node");
2193 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002194 }
Guido van Rossum47478871996-08-21 14:32:37 +00002195 if (TYPE(CHILD(tree, 0)) == DOT)
Fred Drakeff9ea482000-04-19 13:54:15 +00002196 /* take care of ('.' '.' '.') possibility */
2197 return (validate_numnodes(tree, 3, "subscript")
2198 && validate_dot(CHILD(tree, 0))
2199 && validate_dot(CHILD(tree, 1))
2200 && validate_dot(CHILD(tree, 2)));
Guido van Rossum47478871996-08-21 14:32:37 +00002201 if (nch == 1) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002202 if (TYPE(CHILD(tree, 0)) == test)
2203 res = validate_test(CHILD(tree, 0));
2204 else
2205 res = validate_colon(CHILD(tree, 0));
2206 return (res);
Guido van Rossum47478871996-08-21 14:32:37 +00002207 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002208 /* Must be [test] ':' [test] [sliceop],
2209 * but at least one of the optional components will
2210 * be present, but we don't know which yet.
Guido van Rossum47478871996-08-21 14:32:37 +00002211 */
2212 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002213 res = validate_test(CHILD(tree, 0));
2214 offset = 1;
Guido van Rossum47478871996-08-21 14:32:37 +00002215 }
2216 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00002217 res = validate_colon(CHILD(tree, offset));
Guido van Rossum47478871996-08-21 14:32:37 +00002218 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002219 int rem = nch - ++offset;
2220 if (rem) {
2221 if (TYPE(CHILD(tree, offset)) == test) {
2222 res = validate_test(CHILD(tree, offset));
2223 ++offset;
2224 --rem;
2225 }
2226 if (res && rem)
2227 res = validate_sliceop(CHILD(tree, offset));
2228 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002229 }
2230 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002231}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002232
2233
Guido van Rossum47478871996-08-21 14:32:37 +00002234static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002235validate_sliceop(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002236{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002237 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002238 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
Fred Drakeff9ea482000-04-19 13:54:15 +00002239 && validate_ntype(tree, sliceop);
Guido van Rossum47478871996-08-21 14:32:37 +00002240 if (!res && !PyErr_Occurred()) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002241 res = validate_numnodes(tree, 1, "sliceop");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002242 }
Guido van Rossum47478871996-08-21 14:32:37 +00002243 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00002244 res = validate_colon(CHILD(tree, 0));
Guido van Rossum47478871996-08-21 14:32:37 +00002245 if (res && (nch == 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00002246 res = validate_test(CHILD(tree, 1));
Guido van Rossum47478871996-08-21 14:32:37 +00002247
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002248 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002249}
Guido van Rossum47478871996-08-21 14:32:37 +00002250
2251
2252static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002253validate_exprlist(node *tree)
Guido van Rossum47478871996-08-21 14:32:37 +00002254{
2255 return (validate_repeating_list(tree, exprlist,
Fred Drakeff9ea482000-04-19 13:54:15 +00002256 validate_expr, "exprlist"));
2257}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002258
2259
Guido van Rossum47478871996-08-21 14:32:37 +00002260static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002261validate_dictmaker(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002262{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002263 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002264 int res = (validate_ntype(tree, dictmaker)
Fred Drakeff9ea482000-04-19 13:54:15 +00002265 && (nch >= 3)
2266 && validate_test(CHILD(tree, 0))
2267 && validate_colon(CHILD(tree, 1))
2268 && validate_test(CHILD(tree, 2)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002269
Guido van Rossum3d602e31996-07-21 02:33:56 +00002270 if (res && ((nch % 4) == 0))
Fred Drakeff9ea482000-04-19 13:54:15 +00002271 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002272 else if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00002273 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002274
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002275 if (res && (nch > 3)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002276 int pos = 3;
2277 /* ( ',' test ':' test )* */
2278 while (res && (pos < nch)) {
2279 res = (validate_comma(CHILD(tree, pos))
2280 && validate_test(CHILD(tree, pos + 1))
2281 && validate_colon(CHILD(tree, pos + 2))
2282 && validate_test(CHILD(tree, pos + 3)));
2283 pos += 4;
2284 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002285 }
2286 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002287}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002288
2289
Guido van Rossum47478871996-08-21 14:32:37 +00002290static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002291validate_eval_input(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002292{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002293 int pos;
2294 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002295 int res = (validate_ntype(tree, eval_input)
Fred Drakeff9ea482000-04-19 13:54:15 +00002296 && (nch >= 2)
2297 && validate_testlist(CHILD(tree, 0))
2298 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002299
Guido van Rossum3d602e31996-07-21 02:33:56 +00002300 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Fred Drakeff9ea482000-04-19 13:54:15 +00002301 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002302
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002303 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002304}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002305
2306
Guido van Rossum47478871996-08-21 14:32:37 +00002307static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002308validate_node(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002309{
Fred Drakeff9ea482000-04-19 13:54:15 +00002310 int nch = 0; /* num. children on current node */
2311 int res = 1; /* result value */
2312 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002313
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002314 while (res & (tree != 0)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002315 nch = NCH(tree);
2316 next = 0;
2317 switch (TYPE(tree)) {
2318 /*
2319 * Definition nodes.
2320 */
2321 case funcdef:
2322 res = validate_funcdef(tree);
2323 break;
2324 case classdef:
2325 res = validate_class(tree);
2326 break;
2327 /*
2328 * "Trivial" parse tree nodes.
2329 * (Why did I call these trivial?)
2330 */
2331 case stmt:
2332 res = validate_stmt(tree);
2333 break;
2334 case small_stmt:
2335 /*
2336 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
2337 * | import_stmt | global_stmt | exec_stmt | assert_stmt
2338 */
2339 res = validate_small_stmt(tree);
2340 break;
2341 case flow_stmt:
2342 res = (validate_numnodes(tree, 1, "flow_stmt")
2343 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2344 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2345 || (TYPE(CHILD(tree, 0)) == return_stmt)
2346 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2347 if (res)
2348 next = CHILD(tree, 0);
2349 else if (nch == 1)
2350 err_string("Illegal flow_stmt type.");
2351 break;
2352 /*
2353 * Compound statements.
2354 */
2355 case simple_stmt:
2356 res = validate_simple_stmt(tree);
2357 break;
2358 case compound_stmt:
2359 res = validate_compound_stmt(tree);
2360 break;
2361 /*
2362 * Fundemental statements.
2363 */
2364 case expr_stmt:
2365 res = validate_expr_stmt(tree);
2366 break;
2367 case print_stmt:
2368 res = validate_print_stmt(tree);
2369 break;
2370 case del_stmt:
2371 res = validate_del_stmt(tree);
2372 break;
2373 case pass_stmt:
2374 res = (validate_numnodes(tree, 1, "pass")
2375 && validate_name(CHILD(tree, 0), "pass"));
2376 break;
2377 case break_stmt:
2378 res = (validate_numnodes(tree, 1, "break")
2379 && validate_name(CHILD(tree, 0), "break"));
2380 break;
2381 case continue_stmt:
2382 res = (validate_numnodes(tree, 1, "continue")
2383 && validate_name(CHILD(tree, 0), "continue"));
2384 break;
2385 case return_stmt:
2386 res = validate_return_stmt(tree);
2387 break;
2388 case raise_stmt:
2389 res = validate_raise_stmt(tree);
2390 break;
2391 case import_stmt:
2392 res = validate_import_stmt(tree);
2393 break;
2394 case global_stmt:
2395 res = validate_global_stmt(tree);
2396 break;
2397 case exec_stmt:
2398 res = validate_exec_stmt(tree);
2399 break;
2400 case assert_stmt:
2401 res = validate_assert_stmt(tree);
2402 break;
2403 case if_stmt:
2404 res = validate_if(tree);
2405 break;
2406 case while_stmt:
2407 res = validate_while(tree);
2408 break;
2409 case for_stmt:
2410 res = validate_for(tree);
2411 break;
2412 case try_stmt:
2413 res = validate_try(tree);
2414 break;
2415 case suite:
2416 res = validate_suite(tree);
2417 break;
2418 /*
2419 * Expression nodes.
2420 */
2421 case testlist:
2422 res = validate_testlist(tree);
2423 break;
2424 case test:
2425 res = validate_test(tree);
2426 break;
2427 case and_test:
2428 res = validate_and_test(tree);
2429 break;
2430 case not_test:
2431 res = validate_not_test(tree);
2432 break;
2433 case comparison:
2434 res = validate_comparison(tree);
2435 break;
2436 case exprlist:
2437 res = validate_exprlist(tree);
2438 break;
2439 case comp_op:
2440 res = validate_comp_op(tree);
2441 break;
2442 case expr:
2443 res = validate_expr(tree);
2444 break;
2445 case xor_expr:
2446 res = validate_xor_expr(tree);
2447 break;
2448 case and_expr:
2449 res = validate_and_expr(tree);
2450 break;
2451 case shift_expr:
2452 res = validate_shift_expr(tree);
2453 break;
2454 case arith_expr:
2455 res = validate_arith_expr(tree);
2456 break;
2457 case term:
2458 res = validate_term(tree);
2459 break;
2460 case factor:
2461 res = validate_factor(tree);
2462 break;
2463 case power:
2464 res = validate_power(tree);
2465 break;
2466 case atom:
2467 res = validate_atom(tree);
2468 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002469
Fred Drakeff9ea482000-04-19 13:54:15 +00002470 default:
2471 /* Hopefully never reached! */
2472 err_string("Unrecogniged node type.");
2473 res = 0;
2474 break;
2475 }
2476 tree = next;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002477 }
2478 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002479}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002480
2481
Guido van Rossum47478871996-08-21 14:32:37 +00002482static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002483validate_expr_tree(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002484{
2485 int res = validate_eval_input(tree);
2486
2487 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00002488 err_string("Could not validate expression tuple.");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002489
2490 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002491}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002492
2493
Guido van Rossum3d602e31996-07-21 02:33:56 +00002494/* file_input:
Fred Drakeff9ea482000-04-19 13:54:15 +00002495 * (NEWLINE | stmt)* ENDMARKER
Guido van Rossum3d602e31996-07-21 02:33:56 +00002496 */
Guido van Rossum47478871996-08-21 14:32:37 +00002497static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002498validate_file_input(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002499{
2500 int j = 0;
2501 int nch = NCH(tree) - 1;
2502 int res = ((nch >= 0)
Fred Drakeff9ea482000-04-19 13:54:15 +00002503 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002504
Guido van Rossum3d602e31996-07-21 02:33:56 +00002505 for ( ; res && (j < nch); ++j) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002506 if (TYPE(CHILD(tree, j)) == stmt)
2507 res = validate_stmt(CHILD(tree, j));
2508 else
2509 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002510 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002511 /* This stays in to prevent any internal failues from getting to the
2512 * user. Hopefully, this won't be needed. If a user reports getting
2513 * this, we have some debugging to do.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002514 */
2515 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00002516 err_string("VALIDATION FAILURE: report this to the maintainer!.");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002517
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002518 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002519}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002520
2521
Fred Drake43f8f9b1998-04-13 16:25:46 +00002522static PyObject*
2523pickle_constructor = NULL;
2524
2525
2526static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +00002527parser__pickler(PyObject *self, PyObject *args)
Fred Drake43f8f9b1998-04-13 16:25:46 +00002528{
Fred Drake268397f1998-04-29 14:16:32 +00002529 NOTE(ARGUNUSED(self))
Fred Drake43f8f9b1998-04-13 16:25:46 +00002530 PyObject *result = NULL;
2531 PyObject *ast = NULL;
Fred Drake2a6875e1999-09-20 22:32:18 +00002532 PyObject *empty_dict = NULL;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002533
2534 if (PyArg_ParseTuple(args, "O!:_pickler", &PyAST_Type, &ast)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002535 PyObject *newargs;
2536 PyObject *tuple;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002537
Fred Drake2a6875e1999-09-20 22:32:18 +00002538 if ((empty_dict = PyDict_New()) == NULL)
2539 goto finally;
2540 if ((newargs = Py_BuildValue("Oi", ast, 1)) == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +00002541 goto finally;
2542 tuple = parser_ast2tuple((PyAST_Object*)NULL, newargs, empty_dict);
2543 if (tuple != NULL) {
2544 result = Py_BuildValue("O(O)", pickle_constructor, tuple);
2545 Py_DECREF(tuple);
2546 }
Fred Drake2a6875e1999-09-20 22:32:18 +00002547 Py_DECREF(empty_dict);
Fred Drakeff9ea482000-04-19 13:54:15 +00002548 Py_DECREF(newargs);
Fred Drake43f8f9b1998-04-13 16:25:46 +00002549 }
2550 finally:
Fred Drake2a6875e1999-09-20 22:32:18 +00002551 Py_XDECREF(empty_dict);
2552
Fred Drake43f8f9b1998-04-13 16:25:46 +00002553 return (result);
Fred Drakeff9ea482000-04-19 13:54:15 +00002554}
Fred Drake43f8f9b1998-04-13 16:25:46 +00002555
2556
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002557/* Functions exported by this module. Most of this should probably
2558 * be converted into an AST object with methods, but that is better
2559 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002560 * We'd really have to write a wrapper around it all anyway to allow
2561 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002562 */
2563static PyMethodDef parser_functions[] = {
Fred Drakeff9ea482000-04-19 13:54:15 +00002564 {"ast2tuple", (PyCFunction)parser_ast2tuple, PUBLIC_METHOD_TYPE,
2565 "Creates a tuple-tree representation of an AST."},
2566 {"ast2list", (PyCFunction)parser_ast2list, PUBLIC_METHOD_TYPE,
2567 "Creates a list-tree representation of an AST."},
2568 {"compileast", (PyCFunction)parser_compileast, PUBLIC_METHOD_TYPE,
2569 "Compiles an AST object into a code object."},
2570 {"expr", (PyCFunction)parser_expr, PUBLIC_METHOD_TYPE,
2571 "Creates an AST object from an expression."},
2572 {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
2573 "Determines if an AST object was created from an expression."},
2574 {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
2575 "Determines if an AST object was created from a suite."},
2576 {"suite", (PyCFunction)parser_suite, PUBLIC_METHOD_TYPE,
2577 "Creates an AST object from a suite."},
2578 {"sequence2ast", (PyCFunction)parser_tuple2ast, PUBLIC_METHOD_TYPE,
2579 "Creates an AST object from a tree representation."},
2580 {"tuple2ast", (PyCFunction)parser_tuple2ast, PUBLIC_METHOD_TYPE,
2581 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002582
Fred Drake43f8f9b1998-04-13 16:25:46 +00002583 /* private stuff: support pickle module */
Fred Drakeff9ea482000-04-19 13:54:15 +00002584 {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS,
Fred Drake43f8f9b1998-04-13 16:25:46 +00002585 "Returns the pickle magic to allow ast objects to be pickled."},
2586
Fred Drake268397f1998-04-29 14:16:32 +00002587 {NULL, NULL, 0, NULL}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002588 };
2589
2590
Guido van Rossum3886bb61998-12-04 18:50:17 +00002591DL_EXPORT(void)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002592initparser()
2593 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002594 PyObject* module;
2595 PyObject* dict;
Fred Drakeff9ea482000-04-19 13:54:15 +00002596
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002597 PyAST_Type.ob_type = &PyType_Type;
2598 module = Py_InitModule("parser", parser_functions);
2599 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002600
Fred Drake7a15ba51999-09-09 14:21:52 +00002601 if (parser_error == 0)
2602 parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
2603 else
2604 puts("parser module initialized more than once!");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002605
2606 if ((parser_error == 0)
Fred Drakeff9ea482000-04-19 13:54:15 +00002607 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2608 /*
2609 * This is serious.
2610 */
2611 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002612 }
2613 /*
2614 * Nice to have, but don't cry if we fail.
2615 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002616 Py_INCREF(&PyAST_Type);
2617 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2618
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002619 PyDict_SetItemString(dict, "__copyright__",
Fred Drakeff9ea482000-04-19 13:54:15 +00002620 PyString_FromString(parser_copyright_string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002621 PyDict_SetItemString(dict, "__doc__",
Fred Drakeff9ea482000-04-19 13:54:15 +00002622 PyString_FromString(parser_doc_string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002623 PyDict_SetItemString(dict, "__version__",
Fred Drakeff9ea482000-04-19 13:54:15 +00002624 PyString_FromString(parser_version_string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002625
Fred Drake43f8f9b1998-04-13 16:25:46 +00002626 /* register to support pickling */
2627 module = PyImport_ImportModule("copy_reg");
2628 if (module != NULL) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002629 PyObject *func, *pickler;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002630
Fred Drakeff9ea482000-04-19 13:54:15 +00002631 func = PyObject_GetAttrString(module, "pickle");
2632 pickle_constructor = PyDict_GetItemString(dict, "sequence2ast");
2633 pickler = PyDict_GetItemString(dict, "_pickler");
2634 Py_XINCREF(pickle_constructor);
2635 if ((func != NULL) && (pickle_constructor != NULL)
2636 && (pickler != NULL)) {
2637 PyObject *res;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002638
Fred Drakeff9ea482000-04-19 13:54:15 +00002639 res = PyObject_CallFunction(
2640 func, "OOO", &PyAST_Type, pickler, pickle_constructor);
2641 Py_XDECREF(res);
2642 }
2643 Py_XDECREF(func);
2644 Py_DECREF(module);
Fred Drake43f8f9b1998-04-13 16:25:46 +00002645 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002646}