blob: 6e7d889ccd6d5184872629e3d57a1be88bb46a7e [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.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000020 */
21
22#include "Python.h" /* general Python API */
23#include "graminit.h" /* symbols defined in the grammar */
24#include "node.h" /* internal parser structure */
25#include "token.h" /* token definitions */
26 /* ISTERMINAL() / ISNONTERMINAL() */
Guido van Rossum3d602e31996-07-21 02:33:56 +000027#include "compile.h" /* PyNode_Compile() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000028
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000029
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000030/* String constants used to initialize module attributes.
31 *
32 */
33static char*
34parser_copyright_string
Guido van Rossum2a288461996-08-21 21:55:43 +000035= "Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
36University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
37Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\
38Centrum, Amsterdam, The Netherlands.";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000039
40
41static char*
42parser_doc_string
43= "This is an interface to Python's internal parser.";
44
45static char*
Guido van Rossum47478871996-08-21 14:32:37 +000046parser_version_string = "0.4";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000047
48
Guido van Rossum2a288461996-08-21 21:55:43 +000049typedef PyObject* (*SeqMaker) Py_PROTO((int length));
50typedef void (*SeqInserter) Py_PROTO((PyObject* sequence,
51 int index,
52 PyObject* element));
Guido van Rossum47478871996-08-21 14:32:37 +000053
Guido van Rossum3d602e31996-07-21 02:33:56 +000054/* The function below is copyrigthed by Stichting Mathematisch Centrum. The
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000055 * original copyright statement is included below, and continues to apply
56 * in full to the function immediately following. All other material is
57 * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
58 * Institute and State University. Changes were made to comply with the
Guido van Rossum2a288461996-08-21 21:55:43 +000059 * new naming conventions. Added arguments to provide support for creating
60 * lists as well as tuples, and optionally including the line numbers.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000061 */
62
Guido van Rossum52f2c051993-11-10 12:53:24 +000063/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +000064Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
65The Netherlands.
Guido van Rossum52f2c051993-11-10 12:53:24 +000066
67 All Rights Reserved
68
Guido van Rossum3d602e31996-07-21 02:33:56 +000069Permission to use, copy, modify, and distribute this software and its
70documentation for any purpose and without fee is hereby granted,
Guido van Rossum52f2c051993-11-10 12:53:24 +000071provided that the above copyright notice appear in all copies and that
Guido van Rossum3d602e31996-07-21 02:33:56 +000072both that copyright notice and this permission notice appear in
Guido van Rossum52f2c051993-11-10 12:53:24 +000073supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000074Centrum or CWI or Corporation for National Research Initiatives or
75CNRI not be used in advertising or publicity pertaining to
76distribution of the software without specific, written prior
77permission.
Guido van Rossum52f2c051993-11-10 12:53:24 +000078
Guido van Rossumd266eb41996-10-25 14:44:06 +000079While CWI is the initial source for this software, a modified version
80is made available by the Corporation for National Research Initiatives
81(CNRI) at the Internet address ftp://ftp.python.org.
82
83STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
84REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
85MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
86CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
87DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
88PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
89TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
90PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum52f2c051993-11-10 12:53:24 +000091
92******************************************************************/
93
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000094static PyObject*
Guido van Rossum47478871996-08-21 14:32:37 +000095node2tuple(n, mkseq, addelem, lineno)
96 node *n; /* node to convert */
97 SeqMaker mkseq; /* create sequence */
98 SeqInserter addelem; /* func. to add elem. in seq. */
99 int lineno; /* include line numbers? */
100{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000101 if (n == NULL) {
102 Py_INCREF(Py_None);
103 return Py_None;
104 }
105 if (ISNONTERMINAL(TYPE(n))) {
106 int i;
107 PyObject *v, *w;
Guido van Rossum47478871996-08-21 14:32:37 +0000108 v = mkseq(1 + NCH(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000109 if (v == NULL)
110 return v;
111 w = PyInt_FromLong(TYPE(n));
112 if (w == NULL) {
113 Py_DECREF(v);
114 return NULL;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000115 }
Guido van Rossum47478871996-08-21 14:32:37 +0000116 addelem(v, 0, w);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000117 for (i = 0; i < NCH(n); i++) {
Guido van Rossum47478871996-08-21 14:32:37 +0000118 w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000119 if (w == NULL) {
120 Py_DECREF(v);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000121 return NULL;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000122 }
Guido van Rossum47478871996-08-21 14:32:37 +0000123 addelem(v, i+1, w);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000124 }
Guido van Rossum47478871996-08-21 14:32:37 +0000125 return (v);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000126 }
127 else if (ISTERMINAL(TYPE(n))) {
Guido van Rossum47478871996-08-21 14:32:37 +0000128 PyObject *result = mkseq(2 + lineno);
129 if (result != NULL) {
130 addelem(result, 0, PyInt_FromLong(TYPE(n)));
131 addelem(result, 1, PyString_FromString(STR(n)));
132 if (lineno == 1)
133 addelem(result, 2, PyInt_FromLong(n->n_lineno));
134 }
135 return (result);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000136 }
137 else {
138 PyErr_SetString(PyExc_SystemError,
139 "unrecognized parse tree node type");
140 return NULL;
141 }
Guido van Rossum47478871996-08-21 14:32:37 +0000142} /* node2tuple() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000143/*
144 * End of material copyrighted by Stichting Mathematisch Centrum.
145 */
Guido van Rossum52f2c051993-11-10 12:53:24 +0000146
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000147
148
149/* There are two types of intermediate objects we're interested in:
150 * 'eval' and 'exec' types. These constants can be used in the ast_type
151 * field of the object type to identify which any given object represents.
152 * These should probably go in an external header to allow other extensions
153 * to use them, but then, we really should be using C++ too. ;-)
154 *
Guido van Rossum3d602e31996-07-21 02:33:56 +0000155 * The PyAST_FRAGMENT type is not currently supported. Maybe not useful?
156 * Haven't decided yet.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000157 */
158
159#define PyAST_EXPR 1
160#define PyAST_SUITE 2
161#define PyAST_FRAGMENT 3
162
163
164/* These are the internal objects and definitions required to implement the
165 * AST type. Most of the internal names are more reminiscent of the 'old'
166 * naming style, but the code uses the new naming convention.
167 */
168
169static PyObject*
170parser_error = 0;
171
172
173typedef struct _PyAST_Object {
174
175 PyObject_HEAD /* standard object header */
176 node* ast_node; /* the node* returned by the parser */
177 int ast_type; /* EXPR or SUITE ? */
178
179} PyAST_Object;
180
181
Guido van Rossum2a288461996-08-21 21:55:43 +0000182staticforward void parser_free Py_PROTO((PyAST_Object *ast));
183staticforward int parser_compare Py_PROTO((PyAST_Object *left,
184 PyAST_Object *right));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000185
Fred Drake503d8d61998-04-13 18:45:18 +0000186staticforward PyObject *parser_getattr Py_PROTO((PyObject *self, char *name));
187
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000188
189/* static */
190PyTypeObject PyAST_Type = {
191
Guido van Rossumf2b2dac1997-01-23 23:29:44 +0000192 PyObject_HEAD_INIT(NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000193 0,
194 "ast", /* tp_name */
195 sizeof(PyAST_Object), /* tp_basicsize */
196 0, /* tp_itemsize */
197 (destructor)parser_free, /* tp_dealloc */
198 0, /* tp_print */
Fred Drake503d8d61998-04-13 18:45:18 +0000199 parser_getattr, /* tp_getattr */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000200 0, /* tp_setattr */
201 (cmpfunc)parser_compare, /* tp_compare */
202 0, /* tp_repr */
203 0, /* tp_as_number */
204 0, /* tp_as_sequence */
205 0, /* tp_as_mapping */
206 0, /* tp_hash */
207 0, /* tp_call */
Fred Drake69b9ae41997-05-23 04:04:17 +0000208 0, /* tp_str */
209 0, /* tp_getattro */
210 0, /* tp_setattro */
211
212 /* Functions to access object as input/output buffer */
213 0, /* tp_as_buffer */
214
215 /* Space for future expansion */
216 0, /* tp_xxx4 */
217
218 /* __doc__ */
219 "Intermediate representation of a Python parse tree."
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000220
221}; /* PyAST_Type */
222
223
224static int
225parser_compare_nodes(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000226 node *left;
227 node *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000228{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000229 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000230
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000231 if (TYPE(left) < TYPE(right))
232 return (-1);
233
234 if (TYPE(right) < TYPE(left))
235 return (1);
236
237 if (ISTERMINAL(TYPE(left)))
238 return (strcmp(STR(left), STR(right)));
239
240 if (NCH(left) < NCH(right))
241 return (-1);
242
243 if (NCH(right) < NCH(left))
244 return (1);
245
246 for (j = 0; j < NCH(left); ++j) {
247 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
248
249 if (v)
250 return (v);
251 }
252 return (0);
253
254} /* parser_compare_nodes() */
255
256
257/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
258 *
259 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
260 * This really just wraps a call to parser_compare_nodes() with some easy
261 * checks and protection code.
262 *
263 */
264static int
265parser_compare(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000266 PyAST_Object *left;
267 PyAST_Object *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000268{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000269 if (left == right)
270 return (0);
271
272 if ((left == 0) || (right == 0))
273 return (-1);
274
275 return (parser_compare_nodes(left->ast_node, right->ast_node));
276
277} /* parser_compare() */
278
279
280/* parser_newastobject(node* ast)
281 *
282 * Allocates a new Python object representing an AST. This is simply the
283 * 'wrapper' object that holds a node* and allows it to be passed around in
284 * Python code.
285 *
286 */
287static PyObject*
288parser_newastobject(ast, type)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000289 node *ast;
290 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000291{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000292 PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
293
294 if (o != 0) {
295 o->ast_node = ast;
296 o->ast_type = type;
297 }
298 return ((PyObject*)o);
299
300} /* parser_newastobject() */
301
302
303/* void parser_free(PyAST_Object* ast)
304 *
305 * This is called by a del statement that reduces the reference count to 0.
306 *
307 */
308static void
309parser_free(ast)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000310 PyAST_Object *ast;
Guido van Rossum47478871996-08-21 14:32:37 +0000311{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000312 PyNode_Free(ast->ast_node);
313 PyMem_DEL(ast);
314
315} /* parser_free() */
316
317
318/* parser_ast2tuple(PyObject* self, PyObject* args)
319 *
320 * This provides conversion from a node* to a tuple object that can be
321 * returned to the Python-level caller. The AST object is not modified.
322 *
323 */
324static PyObject*
325parser_ast2tuple(self, args)
Fred Drake503d8d61998-04-13 18:45:18 +0000326 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000327 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000328{
Guido van Rossum47478871996-08-21 14:32:37 +0000329 PyObject *line_option = 0;
330 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000331 int ok;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000332
Fred Drake503d8d61998-04-13 18:45:18 +0000333 if (self == NULL)
334 ok = PyArg_ParseTuple(
335 args, "O!|O:ast2tuple", &PyAST_Type, &self, &line_option);
336 else
337 ok = PyArg_ParseTuple(args, "|O:totuple", &line_option);
338 if (ok) {
Guido van Rossum47478871996-08-21 14:32:37 +0000339 int lineno = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000340 if (line_option != NULL) {
341 lineno = PyObject_IsTrue(line_option) ? 1 : 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000342 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000343 /*
344 * Convert AST into a tuple representation. Use Guido's function,
345 * since it's known to work already.
346 */
Fred Drake503d8d61998-04-13 18:45:18 +0000347 res = node2tuple(((PyAST_Object*)self)->ast_node,
Guido van Rossum47478871996-08-21 14:32:37 +0000348 PyTuple_New, PyTuple_SetItem, lineno);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000349 }
350 return (res);
351
352} /* parser_ast2tuple() */
353
354
Guido van Rossum47478871996-08-21 14:32:37 +0000355/* parser_ast2tuple(PyObject* self, PyObject* args)
356 *
357 * This provides conversion from a node* to a tuple object that can be
358 * returned to the Python-level caller. The AST object is not modified.
359 *
360 */
361static PyObject*
362parser_ast2list(self, args)
Fred Drake503d8d61998-04-13 18:45:18 +0000363 PyAST_Object *self;
Guido van Rossum47478871996-08-21 14:32:37 +0000364 PyObject *args;
365{
Guido van Rossum47478871996-08-21 14:32:37 +0000366 PyObject *line_option = 0;
367 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000368 int ok;
Guido van Rossum47478871996-08-21 14:32:37 +0000369
Fred Drake503d8d61998-04-13 18:45:18 +0000370 if (self == NULL)
371 ok = PyArg_ParseTuple(
372 args, "O!|O:ast2list", &PyAST_Type, &self, &line_option);
373 else
374 ok = PyArg_ParseTuple(args, "|O:tolist", &line_option);
375 if (ok) {
Guido van Rossum47478871996-08-21 14:32:37 +0000376 int lineno = 0;
377 if (line_option != 0) {
Fred Drake503d8d61998-04-13 18:45:18 +0000378 lineno = PyObject_IsTrue(line_option) ? 1 : 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000379 }
380 /*
381 * Convert AST into a tuple representation. Use Guido's function,
382 * since it's known to work already.
383 */
Fred Drake503d8d61998-04-13 18:45:18 +0000384 res = node2tuple(((PyAST_Object *)self)->ast_node,
Guido van Rossum47478871996-08-21 14:32:37 +0000385 PyList_New, PyList_SetItem, lineno);
386 }
387 return (res);
388
389} /* parser_ast2list() */
390
391
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000392/* parser_compileast(PyObject* self, PyObject* args)
393 *
394 * This function creates code objects from the parse tree represented by
395 * the passed-in data object. An optional file name is passed in as well.
396 *
397 */
398static PyObject*
399parser_compileast(self, args)
Fred Drake503d8d61998-04-13 18:45:18 +0000400 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000401 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000402{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000403 PyObject* res = 0;
404 char* str = "<ast>";
Fred Drake503d8d61998-04-13 18:45:18 +0000405 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000406
Fred Drake503d8d61998-04-13 18:45:18 +0000407 if (self == NULL)
408 ok = PyArg_ParseTuple(
409 args, "O!|s:compileast", &PyAST_Type, &self, &str);
410 else
411 ok = PyArg_ParseTuple(args, "|s:compile", &str);
412
413 if (ok)
414 res = (PyObject *)PyNode_Compile(self->ast_node, str);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000415
416 return (res);
417
418} /* parser_compileast() */
419
420
421/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
422 * PyObject* parser_issuite(PyObject* self, PyObject* args)
423 *
424 * Checks the passed-in AST object to determine if it is an expression or
425 * a statement suite, respectively. The return is a Python truth value.
426 *
427 */
428static PyObject*
429parser_isexpr(self, args)
Fred Drake503d8d61998-04-13 18:45:18 +0000430 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000431 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000432{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000433 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000434 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000435
Fred Drake503d8d61998-04-13 18:45:18 +0000436 if (self == NULL)
437 ok = PyArg_ParseTuple(args, "O!:isexpr", &PyAST_Type, &self);
438 else
439 ok = PyArg_ParseTuple(args, ":isexpr");
440
441 if (ok) {
442 /* Check to see if the AST represents an expression or not. */
443 res = (self->ast_type == PyAST_EXPR) ? Py_True : Py_False;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000444 Py_INCREF(res);
445 }
446 return (res);
447
448} /* parser_isexpr() */
449
450
451static PyObject*
452parser_issuite(self, args)
Fred Drake503d8d61998-04-13 18:45:18 +0000453 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000454 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000455{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000456 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000457 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000458
Fred Drake503d8d61998-04-13 18:45:18 +0000459 if (self == NULL)
460 ok = PyArg_ParseTuple(args, "O!:issuite", &PyAST_Type, &self);
461 else
462 ok = PyArg_ParseTuple(args, ":issuite");
463
464 if (ok) {
465 /* Check to see if the AST represents an expression or not. */
466 res = (self->ast_type == PyAST_EXPR) ? Py_False : Py_True;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000467 Py_INCREF(res);
468 }
469 return (res);
470
471} /* parser_issuite() */
472
473
Fred Drake503d8d61998-04-13 18:45:18 +0000474static PyMethodDef
475parser_methods[] = {
476 {"compile", parser_compileast, METH_VARARGS},
477 {"isexpr", parser_isexpr, METH_VARARGS},
478 {"issuite", parser_issuite, METH_VARARGS},
479 {"tolist", parser_ast2list, METH_VARARGS},
480 {"totuple", parser_ast2tuple, METH_VARARGS},
481
482 {NULL}
483};
484
485static PyObject*
486parser_method_list = NULL;
487
488
489static PyObject*
490parser_getattr(self, name)
491 PyObject *self;
492 char *name;
493{
494 if (strcmp(name, "__methods__") == 0) {
495 Py_INCREF(parser_method_list);
496 return (parser_method_list);
497 }
498 return (Py_FindMethod(parser_methods, self, name));
499
500} /* parser_getattr() */
501
502
Guido van Rossum3d602e31996-07-21 02:33:56 +0000503/* err_string(char* message)
504 *
505 * Sets the error string for an exception of type ParserError.
506 *
507 */
508static void
509err_string(message)
510 char *message;
Guido van Rossum47478871996-08-21 14:32:37 +0000511{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000512 PyErr_SetString(parser_error, message);
513
514} /* err_string() */
515
516
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000517/* PyObject* parser_do_parse(PyObject* args, int type)
518 *
519 * Internal function to actually execute the parse and return the result if
520 * successful, or set an exception if not.
521 *
522 */
523static PyObject*
524parser_do_parse(args, type)
525 PyObject *args;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000526 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000527{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000528 char* string = 0;
529 PyObject* res = 0;
530
531 if (PyArg_ParseTuple(args, "s", &string)) {
532 node* n = PyParser_SimpleParseString(string,
533 (type == PyAST_EXPR)
534 ? eval_input : file_input);
535
536 if (n != 0)
537 res = parser_newastobject(n, type);
538 else
Guido van Rossum3d602e31996-07-21 02:33:56 +0000539 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000540 }
541 return (res);
542
543} /* parser_do_parse() */
544
545
546/* PyObject* parser_expr(PyObject* self, PyObject* args)
547 * PyObject* parser_suite(PyObject* self, PyObject* args)
548 *
549 * External interfaces to the parser itself. Which is called determines if
550 * the parser attempts to recognize an expression ('eval' form) or statement
551 * suite ('exec' form). The real work is done by parser_do_parse() above.
552 *
553 */
554static PyObject*
555parser_expr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000556 PyObject *self;
557 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000558{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000559 return (parser_do_parse(args, PyAST_EXPR));
560
561} /* parser_expr() */
562
563
564static PyObject*
565parser_suite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000566 PyObject *self;
567 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000568{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000569 return (parser_do_parse(args, PyAST_SUITE));
570
571} /* parser_suite() */
572
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
Guido van Rossum2a288461996-08-21 21:55:43 +0000592staticforward node* build_node_tree Py_PROTO((PyObject *tuple));
593staticforward int validate_expr_tree Py_PROTO((node *tree));
594staticforward int validate_file_input Py_PROTO((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*
611parser_tuple2ast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000612 PyObject *self;
613 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000614{
615 PyObject *ast = 0;
616 PyObject *tuple = 0;
617 PyObject *temp = 0;
618 int ok;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000619 int start_sym = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000620
Guido van Rossum47478871996-08-21 14:32:37 +0000621 if (!PyArg_ParseTuple(args, "O:tuple2ast", &tuple))
622 return (0);
623 if (!PySequence_Check(tuple)) {
624 PyErr_SetString(PyExc_ValueError,
625 "tuple2ast() requires a single sequence argument");
626 return (0);
627 }
628 /*
629 * This mess of tests is written this way so we can use the abstract
630 * object interface (AOI). Unfortunately, the AOI increments reference
631 * counts, which requires that we store a pointer to retrieved object
632 * so we can DECREF it after the check. But we really should accept
633 * lists as well as tuples at the very least.
634 */
635 ok = PyObject_Length(tuple) >= 2;
636 if (ok) {
637 temp = PySequence_GetItem(tuple, 0);
638 ok = (temp != NULL) && PyInt_Check(temp);
639 if (ok)
640 /* this is used after the initial checks: */
641 start_sym = PyInt_AsLong(temp);
642 Py_XDECREF(temp);
643 }
644 if (ok) {
645 temp = PySequence_GetItem(tuple, 1);
646 ok = (temp != NULL) && PySequence_Check(temp);
647 Py_XDECREF(temp);
648 }
649 if (ok) {
650 temp = PySequence_GetItem(tuple, 1);
651 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
652 if (ok) {
653 PyObject *temp2 = PySequence_GetItem(temp, 0);
654 if (temp2 != NULL) {
655 ok = PyInt_Check(temp2);
656 Py_DECREF(temp2);
657 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000658 }
Guido van Rossum47478871996-08-21 14:32:37 +0000659 Py_XDECREF(temp);
660 }
661 /* If we've failed at some point, get out of here. */
662 if (!ok) {
663 err_string("malformed sequence for tuple2ast()");
664 return (0);
665 }
666 /*
667 * This might be a valid parse tree, but let's do a quick check
668 * before we jump the gun.
669 */
670 if (start_sym == eval_input) {
671 /* Might be an eval form. */
672 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000673
Guido van Rossum47478871996-08-21 14:32:37 +0000674 if ((expression != 0) && validate_expr_tree(expression))
675 ast = parser_newastobject(expression, PyAST_EXPR);
676 }
677 else if (start_sym == file_input) {
678 /* This looks like an exec form so far. */
679 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000680
Guido van Rossum47478871996-08-21 14:32:37 +0000681 if ((suite_tree != 0) && validate_file_input(suite_tree))
682 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000683 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000684 else
Guido van Rossum47478871996-08-21 14:32:37 +0000685 /* This is a fragment, and is not yet supported. Maybe they
686 * will be if I find a use for them.
687 */
688 err_string("Fragmentary parse trees not supported.");
689
690 /* Make sure we throw an exception on all errors. We should never
691 * get this, but we'd do well to be sure something is done.
692 */
693 if ((ast == 0) && !PyErr_Occurred())
694 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000695
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000696 return (ast);
697
698} /* parser_tuple2ast() */
699
700
701/* int check_terminal_tuple()
702 *
Guido van Rossum47478871996-08-21 14:32:37 +0000703 * Check a tuple to determine that it is indeed a valid terminal
704 * node. The node is known to be required as a terminal, so we throw
705 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000706 *
Guido van Rossum47478871996-08-21 14:32:37 +0000707 * The format of an acceptable terminal tuple is "(is[i])": the fact
708 * that elem is a tuple and the integer is a valid terminal symbol
709 * has been established before this function is called. We must
710 * check the length of the tuple and the type of the second element
711 * and optional third element. We do *NOT* check the actual text of
712 * the string element, which we could do in many cases. This is done
713 * by the validate_*() functions which operate on the internal
714 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000715 */
716static int
Guido van Rossum47478871996-08-21 14:32:37 +0000717check_terminal_tuple(elem)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000718 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)) {
725 PyObject *temp = PySequence_GetItem(elem, 1);
726 res = PyString_Check(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000727 str = "Illegal terminal symbol; expected a string.";
Guido van Rossum47478871996-08-21 14:32:37 +0000728 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);
735 }
736 else {
737 res = 0;
738 }
739 if (!res) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000740 elem = Py_BuildValue("(os)", elem, str);
741 PyErr_SetObject(parser_error, elem);
742 }
743 return (res);
744
745} /* check_terminal_tuple() */
746
747
748/* node* build_node_children()
749 *
750 * Iterate across the children of the current non-terminal node and build
751 * their structures. If successful, return the root of this portion of
752 * the tree, otherwise, 0. Any required exception will be specified already,
753 * and no memory will have been deallocated.
754 *
755 */
756static node*
757build_node_children(tuple, root, line_num)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000758 PyObject *tuple;
759 node *root;
760 int *line_num;
Guido van Rossum47478871996-08-21 14:32:37 +0000761{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000762 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000763 int i;
764
765 for (i = 1; i < len; ++i) {
766 /* elem must always be a tuple, however simple */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000767 PyObject* elem = PySequence_GetItem(tuple, i);
Guido van Rossum47478871996-08-21 14:32:37 +0000768 int ok = elem != NULL;
769 long type = 0;
770 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000771
Guido van Rossum47478871996-08-21 14:32:37 +0000772 if (ok)
773 ok = PySequence_Check(elem);
774 if (ok) {
775 PyObject *temp = PySequence_GetItem(elem, 0);
776 if (temp == NULL)
777 ok = 0;
778 else {
779 ok = PyInt_Check(temp);
780 if (ok)
781 type = PyInt_AsLong(temp);
782 Py_DECREF(temp);
783 }
784 }
785 if (!ok) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000786 PyErr_SetObject(parser_error,
787 Py_BuildValue("(os)", elem,
788 "Illegal node construct."));
Guido van Rossum47478871996-08-21 14:32:37 +0000789 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000790 return (0);
791 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000792 if (ISTERMINAL(type)) {
Guido van Rossum47478871996-08-21 14:32:37 +0000793 if (check_terminal_tuple(elem)) {
794 PyObject *temp = PySequence_GetItem(elem, 1);
795
Fred Draked49266e1997-10-09 16:29:31 +0000796 /* check_terminal_tuple() already verified it's a string */
797 strn = (char *)malloc(PyString_GET_SIZE(temp) + 1);
798 if (strn != NULL)
799 strcpy(strn, PyString_AS_STRING(temp));
Guido van Rossum47478871996-08-21 14:32:37 +0000800 Py_XDECREF(temp);
801
802 if (PyObject_Length(elem) == 3) {
803 PyObject* temp = PySequence_GetItem(elem, 2);
804 *line_num = PyInt_AsLong(temp);
805 Py_DECREF(temp);
806 }
807 }
808 else {
809 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000810 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000811 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000812 }
813 else if (!ISNONTERMINAL(type)) {
814 /*
815 * It has to be one or the other; this is an error.
816 * Throw an exception.
817 */
818 PyErr_SetObject(parser_error,
819 Py_BuildValue("(os)", elem,
820 "Unknown node type."));
Guido van Rossum47478871996-08-21 14:32:37 +0000821 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000822 return (0);
823 }
824 PyNode_AddChild(root, type, strn, *line_num);
825
826 if (ISNONTERMINAL(type)) {
827 node* new_child = CHILD(root, i - 1);
828
Guido van Rossum47478871996-08-21 14:32:37 +0000829 if (new_child != build_node_children(elem, new_child, line_num)) {
830 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000831 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000832 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000833 }
Guido van Rossum47478871996-08-21 14:32:37 +0000834 else if (type == NEWLINE) { /* It's true: we increment the */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000835 ++(*line_num); /* line number *after* the newline! */
Guido van Rossum47478871996-08-21 14:32:37 +0000836 }
837 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000838 }
839 return (root);
840
841} /* build_node_children() */
842
843
844static node*
845build_node_tree(tuple)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000846 PyObject *tuple;
Guido van Rossum47478871996-08-21 14:32:37 +0000847{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000848 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000849 PyObject *temp = PySequence_GetItem(tuple, 0);
850 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000851
Guido van Rossum47478871996-08-21 14:32:37 +0000852 if (temp != NULL)
853 num = PyInt_AsLong(temp);
854 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000855 if (ISTERMINAL(num)) {
856 /*
857 * The tuple is simple, but it doesn't start with a start symbol.
858 * Throw an exception now and be done with it.
859 */
860 tuple = Py_BuildValue("(os)", tuple,
Guido van Rossum3d602e31996-07-21 02:33:56 +0000861 "Illegal ast tuple; cannot start with terminal symbol.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000862 PyErr_SetObject(parser_error, tuple);
863 }
864 else if (ISNONTERMINAL(num)) {
865 /*
866 * Not efficient, but that can be handled later.
867 */
868 int line_num = 0;
869
870 res = PyNode_New(num);
871 if (res != build_node_children(tuple, res, &line_num)) {
872 PyNode_Free(res);
873 res = 0;
874 }
875 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000876 else
877 /* The tuple is illegal -- if the number is neither TERMINAL nor
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000878 * NONTERMINAL, we can't use it.
879 */
880 PyErr_SetObject(parser_error,
881 Py_BuildValue("(os)", tuple,
882 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000883
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000884 return (res);
885
886} /* build_node_tree() */
887
888
Guido van Rossum360a9341996-08-21 19:04:10 +0000889#ifdef HAVE_OLD_CPP
Guido van Rossum2a288461996-08-21 21:55:43 +0000890#define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000891#else
Guido van Rossum2a288461996-08-21 21:55:43 +0000892#define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000893#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000894
895
896/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000897 * Validation routines used within the validation section:
898 */
Guido van Rossum2a288461996-08-21 21:55:43 +0000899staticforward int validate_terminal Py_PROTO((node *terminal,
900 int type, char *string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000901
902#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
903#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
904#define validate_colon(ch) validate_terminal(ch, COLON, ":")
905#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
906#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
907#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000908#define validate_indent(ch) validate_terminal(ch, INDENT, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000909#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000910#define validate_newline(ch) validate_terminal(ch, NEWLINE, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000911#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
912#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
913#define validate_star(ch) validate_terminal(ch, STAR, "*")
914#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000915#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
Guido van Rossum47478871996-08-21 14:32:37 +0000916#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000917#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000918
Guido van Rossum3d602e31996-07-21 02:33:56 +0000919VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000920VALIDATER(class); VALIDATER(node);
921VALIDATER(parameters); VALIDATER(suite);
922VALIDATER(testlist); VALIDATER(varargslist);
923VALIDATER(fpdef); VALIDATER(fplist);
924VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000925VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000926VALIDATER(print_stmt); VALIDATER(del_stmt);
927VALIDATER(return_stmt);
928VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000929VALIDATER(global_stmt);
Guido van Rossum925e5471997-04-02 05:32:13 +0000930VALIDATER(assert_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000931VALIDATER(exec_stmt); VALIDATER(compound_stmt);
932VALIDATER(while); VALIDATER(for);
933VALIDATER(try); VALIDATER(except_clause);
934VALIDATER(test); VALIDATER(and_test);
935VALIDATER(not_test); VALIDATER(comparison);
936VALIDATER(comp_op); VALIDATER(expr);
937VALIDATER(xor_expr); VALIDATER(and_expr);
938VALIDATER(shift_expr); VALIDATER(arith_expr);
939VALIDATER(term); VALIDATER(factor);
940VALIDATER(atom); VALIDATER(lambdef);
941VALIDATER(trailer); VALIDATER(subscript);
Guido van Rossum47478871996-08-21 14:32:37 +0000942VALIDATER(subscriptlist); VALIDATER(sliceop);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000943VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000944VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000945
946
947#define is_even(n) (((n) & 1) == 0)
948#define is_odd(n) (((n) & 1) == 1)
949
950
951static int
952validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000953 node *n;
954 int t;
Guido van Rossum47478871996-08-21 14:32:37 +0000955{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000956 int res = (TYPE(n) == t);
957
958 if (!res) {
959 char buffer[128];
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000960 sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000961 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000962 }
963 return (res);
964
965} /* validate_ntype() */
966
967
968static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000969validate_numnodes(n, num, name)
970 node *n;
971 int num;
972 const char *const name;
Guido van Rossum47478871996-08-21 14:32:37 +0000973{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000974 if (NCH(n) != num) {
975 char buff[60];
976 sprintf(buff, "Illegal number of children for %s node.", name);
977 err_string(buff);
978 }
979 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000980
Guido van Rossum3d602e31996-07-21 02:33:56 +0000981} /* validate_numnodes() */
982
983
984static int
985validate_terminal(terminal, type, string)
986 node *terminal;
987 int type;
988 char *string;
Guido van Rossum47478871996-08-21 14:32:37 +0000989{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000990 int res = (validate_ntype(terminal, type)
991 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
992
993 if (!res && !PyErr_Occurred()) {
994 char buffer[60];
995 sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
996 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000997 }
998 return (res);
999
1000} /* validate_terminal() */
1001
1002
Guido van Rossum47478871996-08-21 14:32:37 +00001003/* X (',' X) [',']
1004 */
1005static int
1006validate_repeating_list(tree, ntype, vfunc, name)
1007 node *tree;
1008 int ntype;
1009 int (*vfunc)();
1010 const char *const name;
1011{
1012 int nch = NCH(tree);
1013 int res = (nch && validate_ntype(tree, ntype)
1014 && vfunc(CHILD(tree, 0)));
1015
1016 if (!res && !PyErr_Occurred())
1017 validate_numnodes(tree, 1, name);
1018 else {
1019 if (is_even(nch))
1020 res = validate_comma(CHILD(tree, --nch));
1021 if (res && nch > 1) {
1022 int pos = 1;
1023 for ( ; res && pos < nch; pos += 2)
1024 res = (validate_comma(CHILD(tree, pos))
1025 && vfunc(CHILD(tree, pos + 1)));
1026 }
1027 }
1028 return (res);
1029
1030} /* validate_repeating_list() */
1031
1032
Guido van Rossum3d602e31996-07-21 02:33:56 +00001033/* VALIDATE(class)
1034 *
1035 * classdef:
1036 * 'class' NAME ['(' testlist ')'] ':' suite
1037 */
Guido van Rossum47478871996-08-21 14:32:37 +00001038static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001039validate_class(tree)
1040 node *tree;
1041{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001042 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001043 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001044
Guido van Rossum3d602e31996-07-21 02:33:56 +00001045 if (res) {
1046 res = (validate_name(CHILD(tree, 0), "class")
1047 && validate_ntype(CHILD(tree, 1), NAME)
1048 && validate_colon(CHILD(tree, nch - 2))
1049 && validate_suite(CHILD(tree, nch - 1)));
1050 }
1051 else
1052 validate_numnodes(tree, 4, "class");
1053 if (res && (nch == 7)) {
1054 res = (validate_lparen(CHILD(tree, 2))
1055 && validate_testlist(CHILD(tree, 3))
1056 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001057 }
1058 return (res);
1059
1060} /* validate_class() */
1061
1062
Guido van Rossum3d602e31996-07-21 02:33:56 +00001063/* if_stmt:
1064 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1065 */
Guido van Rossum47478871996-08-21 14:32:37 +00001066static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001067validate_if(tree)
1068 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001069{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001070 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001071 int res = (validate_ntype(tree, if_stmt)
1072 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001073 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +00001074 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001075 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001076 && validate_suite(CHILD(tree, 3)));
1077
1078 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001079 /* ... 'else' ':' suite */
1080 res = (validate_name(CHILD(tree, nch - 3), "else")
1081 && validate_colon(CHILD(tree, nch - 2))
1082 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001083 nch -= 3;
1084 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001085 else if (!res && !PyErr_Occurred())
1086 validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001087 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001088 /* Will catch the case for nch < 4 */
1089 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001090 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001091 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001092 int j = 4;
1093 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001094 res = (validate_name(CHILD(tree, j), "elif")
1095 && validate_colon(CHILD(tree, j + 2))
1096 && validate_test(CHILD(tree, j + 1))
1097 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001098 j += 4;
1099 }
1100 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001101 return (res);
1102
1103} /* validate_if() */
1104
1105
Guido van Rossum3d602e31996-07-21 02:33:56 +00001106/* parameters:
1107 * '(' [varargslist] ')'
1108 *
1109 */
Guido van Rossum47478871996-08-21 14:32:37 +00001110static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001111validate_parameters(tree)
1112 node *tree;
1113{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001114 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001115 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001116
Guido van Rossum3d602e31996-07-21 02:33:56 +00001117 if (res) {
1118 res = (validate_lparen(CHILD(tree, 0))
1119 && validate_rparen(CHILD(tree, nch - 1)));
1120 if (res && (nch == 3))
1121 res = validate_varargslist(CHILD(tree, 1));
1122 }
1123 else
1124 validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001125
1126 return (res);
1127
1128} /* validate_parameters() */
1129
1130
Guido van Rossum3d602e31996-07-21 02:33:56 +00001131/* VALIDATE(suite)
1132 *
1133 * suite:
1134 * simple_stmt
1135 * | NEWLINE INDENT stmt+ DEDENT
1136 */
Guido van Rossum47478871996-08-21 14:32:37 +00001137static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001138validate_suite(tree)
1139 node *tree;
1140{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001141 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001142 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001143
Guido van Rossum3d602e31996-07-21 02:33:56 +00001144 if (res && (nch == 1))
1145 res = validate_simple_stmt(CHILD(tree, 0));
1146 else if (res) {
1147 /* NEWLINE INDENT stmt+ DEDENT */
1148 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001149 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001150 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001151 && validate_dedent(CHILD(tree, nch - 1)));
1152
Guido van Rossum3d602e31996-07-21 02:33:56 +00001153 if (res && (nch > 4)) {
1154 int i = 3;
1155 --nch; /* forget the DEDENT */
1156 for ( ; res && (i < nch); ++i)
1157 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001158 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001159 else if (nch < 4)
1160 validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001161 }
1162 return (res);
1163
1164} /* validate_suite() */
1165
1166
Guido van Rossum47478871996-08-21 14:32:37 +00001167static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001168validate_testlist(tree)
1169 node *tree;
1170{
Guido van Rossum47478871996-08-21 14:32:37 +00001171 return (validate_repeating_list(tree, testlist,
1172 validate_test, "testlist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001173
1174} /* validate_testlist() */
1175
1176
Guido van Rossum3d602e31996-07-21 02:33:56 +00001177/* VALIDATE(varargslist)
1178 *
1179 * varargslist:
1180 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1181 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1182 *
1183 * (fpdef ['=' test] ',')*
1184 * ('*' NAME [',' ('**'|'*' '*') NAME]
1185 * | ('**'|'*' '*') NAME)
1186 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1187 *
1188 */
Guido van Rossum47478871996-08-21 14:32:37 +00001189static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001190validate_varargslist(tree)
1191 node *tree;
1192{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001193 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001194 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001195
Guido van Rossum3d602e31996-07-21 02:33:56 +00001196 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1197 /* (fpdef ['=' test] ',')*
1198 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1199 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001200 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001201 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001202
Guido van Rossum3d602e31996-07-21 02:33:56 +00001203 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1204 res = validate_fpdef(CHILD(tree, pos));
1205 if (res) {
1206 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1207 res = validate_test(CHILD(tree, pos + 2));
1208 pos += 2;
1209 }
1210 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001211 pos += 2;
1212 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001213 }
1214 if (res) {
1215 remaining = nch - pos;
1216 res = ((remaining == 2) || (remaining == 3)
1217 || (remaining == 5) || (remaining == 6));
1218 if (!res)
1219 validate_numnodes(tree, 2, "varargslist");
1220 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1221 return ((remaining == 2)
1222 && validate_ntype(CHILD(tree, pos+1), NAME));
1223 else {
1224 res = validate_star(CHILD(tree, pos++));
1225 --remaining;
1226 }
1227 }
1228 if (res) {
1229 if (remaining == 2) {
1230 res = (validate_star(CHILD(tree, pos))
1231 && validate_ntype(CHILD(tree, pos + 1), NAME));
1232 }
1233 else {
1234 res = validate_ntype(CHILD(tree, pos++), NAME);
1235 if (res && (remaining >= 4)) {
1236 res = validate_comma(CHILD(tree, pos));
1237 if (--remaining == 3)
Fred Drakee1607a81996-09-11 21:58:26 +00001238 res = (validate_star(CHILD(tree, pos + 1))
1239 && validate_star(CHILD(tree, pos + 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001240 else
1241 validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1242 }
1243 }
1244 }
1245 if (!res && !PyErr_Occurred())
1246 err_string("Incorrect validation of variable arguments list.");
1247 }
1248 else if (res) {
1249 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1250 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1251 --nch;
1252
1253 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1254 res = (is_odd(nch)
1255 && validate_fpdef(CHILD(tree, 0)));
1256
1257 if (res && (nch > 1)) {
1258 int pos = 1;
1259 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1260 res = validate_test(CHILD(tree, 2));
1261 pos += 2;
1262 }
1263 /* ... (',' fpdef ['=' test])* */
1264 for ( ; res && (pos < nch); pos += 2) {
1265 /* ',' fpdef */
1266 res = (validate_comma(CHILD(tree, pos))
1267 && validate_fpdef(CHILD(tree, pos + 1)));
1268 if (res
1269 && ((nch - pos) > 2)
1270 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1271 /* ['=' test] */
1272 res = validate_test(CHILD(tree, pos + 3));
1273 pos += 2;
1274 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001275 }
1276 }
1277 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001278 else
1279 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001280
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001281 return (res);
1282
1283} /* validate_varargslist() */
1284
1285
Guido van Rossum3d602e31996-07-21 02:33:56 +00001286/* VALIDATE(fpdef)
1287 *
1288 * fpdef:
1289 * NAME
1290 * | '(' fplist ')'
1291 */
Guido van Rossum47478871996-08-21 14:32:37 +00001292static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001293validate_fpdef(tree)
1294 node *tree;
1295{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001296 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001297 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001298
Guido van Rossum3d602e31996-07-21 02:33:56 +00001299 if (res) {
1300 if (nch == 1)
1301 res = validate_ntype(CHILD(tree, 0), NAME);
1302 else if (nch == 3)
1303 res = (validate_lparen(CHILD(tree, 0))
1304 && validate_fplist(CHILD(tree, 1))
1305 && validate_rparen(CHILD(tree, 2)));
1306 else
1307 validate_numnodes(tree, 1, "fpdef");
1308 }
1309 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001310
1311} /* validate_fpdef() */
1312
1313
Guido van Rossum47478871996-08-21 14:32:37 +00001314static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001315validate_fplist(tree)
1316 node *tree;
1317{
Guido van Rossum47478871996-08-21 14:32:37 +00001318 return (validate_repeating_list(tree, fplist,
1319 validate_fpdef, "fplist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001320
1321} /* validate_fplist() */
1322
1323
Guido van Rossum3d602e31996-07-21 02:33:56 +00001324/* simple_stmt | compound_stmt
1325 *
1326 */
Guido van Rossum47478871996-08-21 14:32:37 +00001327static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001328validate_stmt(tree)
1329 node *tree;
1330{
1331 int res = (validate_ntype(tree, stmt)
1332 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001333
Guido van Rossum3d602e31996-07-21 02:33:56 +00001334 if (res) {
1335 tree = CHILD(tree, 0);
1336
1337 if (TYPE(tree) == simple_stmt)
1338 res = validate_simple_stmt(tree);
1339 else
1340 res = validate_compound_stmt(tree);
1341 }
1342 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001343
1344} /* validate_stmt() */
1345
1346
Guido van Rossum3d602e31996-07-21 02:33:56 +00001347/* small_stmt (';' small_stmt)* [';'] NEWLINE
1348 *
1349 */
Guido van Rossum47478871996-08-21 14:32:37 +00001350static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001351validate_simple_stmt(tree)
1352 node *tree;
1353{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001354 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001355 int res = (validate_ntype(tree, simple_stmt)
1356 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001357 && validate_small_stmt(CHILD(tree, 0))
1358 && validate_newline(CHILD(tree, nch - 1)));
1359
Guido van Rossum3d602e31996-07-21 02:33:56 +00001360 if (nch < 2)
1361 res = validate_numnodes(tree, 2, "simple_stmt");
1362 --nch; /* forget the NEWLINE */
1363 if (res && is_even(nch))
1364 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001365 if (res && (nch > 2)) {
1366 int i;
1367
Guido van Rossum3d602e31996-07-21 02:33:56 +00001368 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001369 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001370 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001371 }
1372 return (res);
1373
1374} /* validate_simple_stmt() */
1375
1376
Guido van Rossum47478871996-08-21 14:32:37 +00001377static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001378validate_small_stmt(tree)
1379 node *tree;
1380{
1381 int nch = NCH(tree);
1382 int res = (validate_numnodes(tree, 1, "small_stmt")
1383 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1384 || (TYPE(CHILD(tree, 0)) == print_stmt)
1385 || (TYPE(CHILD(tree, 0)) == del_stmt)
1386 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1387 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1388 || (TYPE(CHILD(tree, 0)) == import_stmt)
1389 || (TYPE(CHILD(tree, 0)) == global_stmt)
Guido van Rossum925e5471997-04-02 05:32:13 +00001390 || (TYPE(CHILD(tree, 0)) == assert_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001391 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1392
1393 if (res)
1394 res = validate_node(CHILD(tree, 0));
1395 else if (nch == 1) {
1396 char buffer[60];
1397 sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1398 TYPE(CHILD(tree, 0)));
1399 err_string(buffer);
1400 }
1401 return (res);
1402
1403} /* validate_small_stmt */
1404
1405
1406/* compound_stmt:
1407 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1408 */
Guido van Rossum47478871996-08-21 14:32:37 +00001409static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001410validate_compound_stmt(tree)
1411 node *tree;
1412{
1413 int res = (validate_ntype(tree, compound_stmt)
1414 && validate_numnodes(tree, 1, "compound_stmt"));
1415
1416 if (!res)
1417 return (0);
1418
1419 tree = CHILD(tree, 0);
1420 res = ((TYPE(tree) == if_stmt)
1421 || (TYPE(tree) == while_stmt)
1422 || (TYPE(tree) == for_stmt)
1423 || (TYPE(tree) == try_stmt)
1424 || (TYPE(tree) == funcdef)
1425 || (TYPE(tree) == classdef));
1426 if (res)
1427 res = validate_node(tree);
1428 else {
1429 char buffer[60];
1430 sprintf(buffer, "Illegal compound statement type: %d.", TYPE(tree));
1431 err_string(buffer);
1432 }
1433 return (res);
1434
1435} /* validate_compound_stmt() */
1436
1437
Guido van Rossum47478871996-08-21 14:32:37 +00001438static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001439validate_expr_stmt(tree)
1440 node *tree;
1441{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001442 int j;
1443 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001444 int res = (validate_ntype(tree, expr_stmt)
1445 && is_odd(nch)
1446 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001447
Guido van Rossum3d602e31996-07-21 02:33:56 +00001448 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001449 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001450 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001451
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001452 return (res);
1453
1454} /* validate_expr_stmt() */
1455
1456
Guido van Rossum3d602e31996-07-21 02:33:56 +00001457/* print_stmt:
1458 *
1459 * 'print' (test ',')* [test]
1460 *
1461 */
Guido van Rossum47478871996-08-21 14:32:37 +00001462static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001463validate_print_stmt(tree)
1464 node *tree;
1465{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001466 int j;
1467 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001468 int res = (validate_ntype(tree, print_stmt)
1469 && (nch != 0)
1470 && validate_name(CHILD(tree, 0), "print"));
1471
1472 if (res && is_even(nch)) {
1473 res = validate_test(CHILD(tree, nch - 1));
1474 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001475 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001476 else if (!res && !PyErr_Occurred())
1477 validate_numnodes(tree, 1, "print_stmt");
1478 for (j = 1; res && (j < nch); j += 2)
1479 res = (validate_test(CHILD(tree, j))
1480 && validate_ntype(CHILD(tree, j + 1), COMMA));
1481
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001482 return (res);
1483
1484} /* validate_print_stmt() */
1485
1486
Guido van Rossum47478871996-08-21 14:32:37 +00001487static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001488validate_del_stmt(tree)
1489 node *tree;
1490{
1491 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001492 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001493 && validate_exprlist(CHILD(tree, 1)));
1494
1495} /* validate_del_stmt() */
1496
1497
Guido van Rossum47478871996-08-21 14:32:37 +00001498static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001499validate_return_stmt(tree)
1500 node *tree;
1501{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001502 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001503 int res = (validate_ntype(tree, return_stmt)
1504 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001505 && validate_name(CHILD(tree, 0), "return"));
1506
Guido van Rossum3d602e31996-07-21 02:33:56 +00001507 if (res && (nch == 2))
1508 res = validate_testlist(CHILD(tree, 1));
1509
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001510 return (res);
1511
1512} /* validate_return_stmt() */
1513
1514
Guido van Rossum47478871996-08-21 14:32:37 +00001515static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001516validate_raise_stmt(tree)
1517 node *tree;
1518{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001519 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001520 int res = (validate_ntype(tree, raise_stmt)
Fred Drakec542bc71998-04-10 04:43:28 +00001521 && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001522
Guido van Rossum3d602e31996-07-21 02:33:56 +00001523 if (res) {
Fred Drakec542bc71998-04-10 04:43:28 +00001524 res = validate_name(CHILD(tree, 0), "raise");
1525 if (res && (nch >= 2))
1526 res = validate_test(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001527 if (res && nch > 2) {
1528 res = (validate_comma(CHILD(tree, 2))
1529 && validate_test(CHILD(tree, 3)));
1530 if (res && (nch > 4))
1531 res = (validate_comma(CHILD(tree, 4))
1532 && validate_test(CHILD(tree, 5)));
1533 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001534 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001535 else
1536 validate_numnodes(tree, 2, "raise");
1537 if (res && (nch == 4))
1538 res = (validate_comma(CHILD(tree, 2))
1539 && validate_test(CHILD(tree, 3)));
1540
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001541 return (res);
1542
1543} /* validate_raise_stmt() */
1544
1545
Guido van Rossum3d602e31996-07-21 02:33:56 +00001546/* import_stmt:
1547 *
1548 * 'import' dotted_name (',' dotted_name)*
1549 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1550 */
Guido van Rossum47478871996-08-21 14:32:37 +00001551static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001552validate_import_stmt(tree)
1553 node *tree;
1554{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001555 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001556 int res = (validate_ntype(tree, import_stmt)
1557 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001558 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001559 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001560
1561 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001562 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001563
Guido van Rossum3d602e31996-07-21 02:33:56 +00001564 for (j = 2; res && (j < nch); j += 2)
1565 res = (validate_comma(CHILD(tree, j))
1566 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001567 }
1568 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001569 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001570 && validate_name(CHILD(tree, 2), "import"));
1571 if (nch == 4) {
1572 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001573 || (TYPE(CHILD(tree, 3)) == STAR));
1574 if (!res)
1575 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001576 }
1577 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001578 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001579 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001580 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001581 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001582 res = (validate_comma(CHILD(tree, j))
1583 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001584 }
1585 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001586 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001587 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001588
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001589 return (res);
1590
1591} /* validate_import_stmt() */
1592
1593
Guido van Rossum47478871996-08-21 14:32:37 +00001594static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001595validate_global_stmt(tree)
1596 node *tree;
1597{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001598 int j;
1599 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001600 int res = (validate_ntype(tree, global_stmt)
1601 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001602
Guido van Rossum3d602e31996-07-21 02:33:56 +00001603 if (res)
1604 res = (validate_name(CHILD(tree, 0), "global")
1605 && validate_ntype(CHILD(tree, 1), NAME));
1606 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001607 res = (validate_comma(CHILD(tree, j))
1608 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001609
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001610 return (res);
1611
1612} /* validate_global_stmt() */
1613
1614
Guido van Rossum3d602e31996-07-21 02:33:56 +00001615/* exec_stmt:
1616 *
1617 * 'exec' expr ['in' test [',' test]]
1618 */
Guido van Rossum47478871996-08-21 14:32:37 +00001619static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001620validate_exec_stmt(tree)
1621 node *tree;
1622{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001623 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001624 int res = (validate_ntype(tree, exec_stmt)
1625 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001626 && validate_name(CHILD(tree, 0), "exec")
1627 && validate_expr(CHILD(tree, 1)));
1628
Guido van Rossum3d602e31996-07-21 02:33:56 +00001629 if (!res && !PyErr_Occurred())
1630 err_string("Illegal exec statement.");
1631 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001632 res = (validate_name(CHILD(tree, 2), "in")
1633 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001634 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001635 res = (validate_comma(CHILD(tree, 4))
1636 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001637
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001638 return (res);
1639
1640} /* validate_exec_stmt() */
1641
1642
Guido van Rossum925e5471997-04-02 05:32:13 +00001643/* assert_stmt:
1644 *
1645 * 'assert' test [',' test]
1646 */
1647static int
1648validate_assert_stmt(tree)
1649 node *tree;
1650{
1651 int nch = NCH(tree);
1652 int res = (validate_ntype(tree, assert_stmt)
1653 && ((nch == 2) || (nch == 4))
1654 && (validate_name(CHILD(tree, 0), "__assert__") ||
1655 validate_name(CHILD(tree, 0), "assert"))
1656 && validate_test(CHILD(tree, 1)));
1657
1658 if (!res && !PyErr_Occurred())
1659 err_string("Illegal assert statement.");
1660 if (res && (nch > 2))
1661 res = (validate_comma(CHILD(tree, 2))
1662 && validate_test(CHILD(tree, 3)));
1663
1664 return (res);
1665
1666} /* validate_assert_stmt() */
1667
1668
Guido van Rossum47478871996-08-21 14:32:37 +00001669static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001670validate_while(tree)
1671 node *tree;
1672{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001673 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001674 int res = (validate_ntype(tree, while_stmt)
1675 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001676 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001677 && validate_test(CHILD(tree, 1))
1678 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001679 && validate_suite(CHILD(tree, 3)));
1680
Guido van Rossum3d602e31996-07-21 02:33:56 +00001681 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001682 res = (validate_name(CHILD(tree, 4), "else")
1683 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001684 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001685
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001686 return (res);
1687
1688} /* validate_while() */
1689
1690
Guido van Rossum47478871996-08-21 14:32:37 +00001691static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001692validate_for(tree)
1693 node *tree;
1694{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001695 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001696 int res = (validate_ntype(tree, for_stmt)
1697 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001698 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001699 && validate_exprlist(CHILD(tree, 1))
1700 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001701 && validate_testlist(CHILD(tree, 3))
1702 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001703 && validate_suite(CHILD(tree, 5)));
1704
Guido van Rossum3d602e31996-07-21 02:33:56 +00001705 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001706 res = (validate_name(CHILD(tree, 6), "else")
1707 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001708 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001709
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001710 return (res);
1711
1712} /* validate_for() */
1713
1714
Guido van Rossum3d602e31996-07-21 02:33:56 +00001715/* try_stmt:
1716 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1717 * | 'try' ':' suite 'finally' ':' suite
1718 *
1719 */
Guido van Rossum47478871996-08-21 14:32:37 +00001720static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001721validate_try(tree)
1722 node *tree;
1723{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001724 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001725 int pos = 3;
1726 int res = (validate_ntype(tree, try_stmt)
1727 && (nch >= 6) && ((nch % 3) == 0));
1728
1729 if (res)
1730 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001731 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001732 && validate_suite(CHILD(tree, 2))
1733 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001734 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001735 else {
1736 const char* name = "execpt";
1737 char buffer[60];
1738 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1739 name = STR(CHILD(tree, nch - 3));
1740 sprintf(buffer, "Illegal number of children for try/%s node.", name);
1741 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001742 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001743 /* Skip past except_clause sections: */
1744 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1745 res = (validate_except_clause(CHILD(tree, pos))
1746 && validate_colon(CHILD(tree, pos + 1))
1747 && validate_suite(CHILD(tree, pos + 2)));
1748 pos += 3;
1749 }
1750 if (res && (pos < nch)) {
1751 res = validate_ntype(CHILD(tree, pos), NAME);
1752 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1753 res = (validate_numnodes(tree, 6, "try/finally")
1754 && validate_colon(CHILD(tree, 4))
1755 && validate_suite(CHILD(tree, 5)));
Guido van Rossum730806d1998-04-10 22:27:42 +00001756 else if (res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001757 if (nch == (pos + 3)) {
1758 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1759 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1760 if (!res)
1761 err_string("Illegal trailing triple in try statement.");
1762 }
Guido van Rossum730806d1998-04-10 22:27:42 +00001763 else if (nch == (pos + 6)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001764 res = (validate_name(CHILD(tree, pos), "except")
1765 && validate_colon(CHILD(tree, pos + 1))
1766 && validate_suite(CHILD(tree, pos + 2))
1767 && validate_name(CHILD(tree, pos + 3), "else"));
Guido van Rossum730806d1998-04-10 22:27:42 +00001768 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001769 else
1770 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossum730806d1998-04-10 22:27:42 +00001771 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001772 }
1773 return (res);
1774
1775} /* validate_try() */
1776
1777
Guido van Rossum47478871996-08-21 14:32:37 +00001778static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001779validate_except_clause(tree)
1780 node *tree;
1781{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001782 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001783 int res = (validate_ntype(tree, except_clause)
1784 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001785 && validate_name(CHILD(tree, 0), "except"));
1786
Guido van Rossum3d602e31996-07-21 02:33:56 +00001787 if (res && (nch > 1))
1788 res = validate_test(CHILD(tree, 1));
1789 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001790 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001791 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001792
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001793 return (res);
1794
1795} /* validate_except_clause() */
1796
1797
Guido van Rossum47478871996-08-21 14:32:37 +00001798static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001799validate_test(tree)
1800 node *tree;
1801{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001802 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001803 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001804
Guido van Rossum3d602e31996-07-21 02:33:56 +00001805 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001806 res = ((nch == 1)
1807 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001808 else if (res) {
1809 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001810 res = validate_and_test(CHILD(tree, 0));
1811 for (pos = 1; res && (pos < nch); pos += 2)
1812 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001813 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001814 }
1815 return (res);
1816
1817} /* validate_test() */
1818
1819
Guido van Rossum47478871996-08-21 14:32:37 +00001820static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001821validate_and_test(tree)
1822 node *tree;
1823{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001824 int pos;
1825 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001826 int res = (validate_ntype(tree, and_test)
1827 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001828 && validate_not_test(CHILD(tree, 0)));
1829
Guido van Rossum3d602e31996-07-21 02:33:56 +00001830 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001831 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001832 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001833
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001834 return (res);
1835
1836} /* validate_and_test() */
1837
1838
Guido van Rossum47478871996-08-21 14:32:37 +00001839static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001840validate_not_test(tree)
1841 node *tree;
1842{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001843 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001844 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001845
Guido van Rossum3d602e31996-07-21 02:33:56 +00001846 if (res) {
1847 if (nch == 2)
1848 res = (validate_name(CHILD(tree, 0), "not")
1849 && validate_not_test(CHILD(tree, 1)));
1850 else if (nch == 1)
1851 res = validate_comparison(CHILD(tree, 0));
1852 }
1853 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001854
1855} /* validate_not_test() */
1856
1857
Guido van Rossum47478871996-08-21 14:32:37 +00001858static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001859validate_comparison(tree)
1860 node *tree;
1861{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001862 int pos;
1863 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001864 int res = (validate_ntype(tree, comparison)
1865 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001866 && validate_expr(CHILD(tree, 0)));
1867
Guido van Rossum3d602e31996-07-21 02:33:56 +00001868 for (pos = 1; res && (pos < nch); pos += 2)
1869 res = (validate_comp_op(CHILD(tree, pos))
1870 && validate_expr(CHILD(tree, pos + 1)));
1871
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001872 return (res);
1873
1874} /* validate_comparison() */
1875
1876
Guido van Rossum47478871996-08-21 14:32:37 +00001877static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001878validate_comp_op(tree)
1879 node *tree;
1880{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001881 int res = 0;
1882 int nch = NCH(tree);
1883
Guido van Rossum3d602e31996-07-21 02:33:56 +00001884 if (!validate_ntype(tree, comp_op))
1885 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001886 if (nch == 1) {
1887 /*
1888 * Only child will be a terminal with a well-defined symbolic name
1889 * or a NAME with a string of either 'is' or 'in'
1890 */
1891 tree = CHILD(tree, 0);
1892 switch (TYPE(tree)) {
1893 case LESS:
1894 case GREATER:
1895 case EQEQUAL:
1896 case EQUAL:
1897 case LESSEQUAL:
1898 case GREATEREQUAL:
1899 case NOTEQUAL:
1900 res = 1;
1901 break;
1902 case NAME:
1903 res = ((strcmp(STR(tree), "in") == 0)
1904 || (strcmp(STR(tree), "is") == 0));
1905 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001906 char buff[128];
1907 sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1908 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001909 }
1910 break;
1911 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001912 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001913 break;
1914 }
1915 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001916 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001917 res = (validate_ntype(CHILD(tree, 0), NAME)
1918 && validate_ntype(CHILD(tree, 1), NAME)
1919 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1920 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1921 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1922 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001923 if (!res && !PyErr_Occurred())
1924 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001925 }
1926 return (res);
1927
1928} /* validate_comp_op() */
1929
1930
Guido van Rossum47478871996-08-21 14:32:37 +00001931static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001932validate_expr(tree)
1933 node *tree;
1934{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001935 int j;
1936 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001937 int res = (validate_ntype(tree, expr)
1938 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001939 && validate_xor_expr(CHILD(tree, 0)));
1940
Guido van Rossum3d602e31996-07-21 02:33:56 +00001941 for (j = 2; res && (j < nch); j += 2)
1942 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001943 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001944
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001945 return (res);
1946
1947} /* validate_expr() */
1948
1949
Guido van Rossum47478871996-08-21 14:32:37 +00001950static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001951validate_xor_expr(tree)
1952 node *tree;
1953{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001954 int j;
1955 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001956 int res = (validate_ntype(tree, xor_expr)
1957 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001958 && validate_and_expr(CHILD(tree, 0)));
1959
Guido van Rossum3d602e31996-07-21 02:33:56 +00001960 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001961 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001962 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001963
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001964 return (res);
1965
1966} /* validate_xor_expr() */
1967
1968
Guido van Rossum47478871996-08-21 14:32:37 +00001969static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001970validate_and_expr(tree)
1971 node *tree;
1972{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001973 int pos;
1974 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001975 int res = (validate_ntype(tree, and_expr)
1976 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001977 && validate_shift_expr(CHILD(tree, 0)));
1978
Guido van Rossum3d602e31996-07-21 02:33:56 +00001979 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001980 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001981 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001982
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001983 return (res);
1984
1985} /* validate_and_expr() */
1986
1987
1988static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001989validate_chain_two_ops(tree, termvalid, op1, op2)
1990 node *tree;
1991 int (*termvalid)();
1992 int op1;
1993 int op2;
1994 {
1995 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001996 int nch = NCH(tree);
1997 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001998 && (*termvalid)(CHILD(tree, 0)));
1999
Guido van Rossum3d602e31996-07-21 02:33:56 +00002000 for ( ; res && (pos < nch); pos += 2) {
2001 if (TYPE(CHILD(tree, pos)) != op1)
2002 res = validate_ntype(CHILD(tree, pos), op2);
2003 if (res)
2004 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002005 }
2006 return (res);
2007
2008} /* validate_chain_two_ops() */
2009
2010
Guido van Rossum47478871996-08-21 14:32:37 +00002011static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002012validate_shift_expr(tree)
2013 node *tree;
2014{
2015 return (validate_ntype(tree, shift_expr)
2016 && validate_chain_two_ops(tree, validate_arith_expr,
2017 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002018
2019} /* validate_shift_expr() */
2020
2021
Guido van Rossum47478871996-08-21 14:32:37 +00002022static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002023validate_arith_expr(tree)
2024 node *tree;
2025{
2026 return (validate_ntype(tree, arith_expr)
2027 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002028
2029} /* validate_arith_expr() */
2030
2031
Guido van Rossum47478871996-08-21 14:32:37 +00002032static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002033validate_term(tree)
2034 node *tree;
2035{
2036 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002037 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002038 int res = (validate_ntype(tree, term)
2039 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002040 && validate_factor(CHILD(tree, 0)));
2041
Guido van Rossum3d602e31996-07-21 02:33:56 +00002042 for ( ; res && (pos < nch); pos += 2)
2043 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002044 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002045 || (TYPE(CHILD(tree, pos)) == PERCENT))
2046 && validate_factor(CHILD(tree, pos + 1)));
2047
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002048 return (res);
2049
2050} /* validate_term() */
2051
2052
Guido van Rossum3d602e31996-07-21 02:33:56 +00002053/* factor:
2054 *
2055 * factor: ('+'|'-'|'~') factor | power
2056 */
Guido van Rossum47478871996-08-21 14:32:37 +00002057static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002058validate_factor(tree)
2059 node *tree;
2060{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002061 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002062 int res = (validate_ntype(tree, factor)
2063 && (((nch == 2)
2064 && ((TYPE(CHILD(tree, 0)) == PLUS)
2065 || (TYPE(CHILD(tree, 0)) == MINUS)
2066 || (TYPE(CHILD(tree, 0)) == TILDE))
2067 && validate_factor(CHILD(tree, 1)))
2068 || ((nch == 1)
2069 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002070 return (res);
2071
2072} /* validate_factor() */
2073
2074
Guido van Rossum3d602e31996-07-21 02:33:56 +00002075/* power:
2076 *
2077 * power: atom trailer* ('**' factor)*
2078 */
Guido van Rossum47478871996-08-21 14:32:37 +00002079static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002080validate_power(tree)
2081 node *tree;
2082{
2083 int pos = 1;
2084 int nch = NCH(tree);
2085 int res = (validate_ntype(tree, power) && (nch >= 1)
2086 && validate_atom(CHILD(tree, 0)));
2087
2088 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2089 res = validate_trailer(CHILD(tree, pos++));
2090 if (res && (pos < nch)) {
2091 if (!is_even(nch - pos)) {
2092 err_string("Illegal number of nodes for 'power'.");
2093 return (0);
2094 }
2095 for ( ; res && (pos < (nch - 1)); pos += 2)
2096 res = (validate_doublestar(CHILD(tree, pos))
2097 && validate_factor(CHILD(tree, pos + 1)));
2098 }
2099 return (res);
2100
2101} /* validate_power() */
2102
2103
Guido van Rossum47478871996-08-21 14:32:37 +00002104static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002105validate_atom(tree)
2106 node *tree;
2107{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002108 int pos;
2109 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002110 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002111
2112 if (res) {
2113 switch (TYPE(CHILD(tree, 0))) {
2114 case LPAR:
2115 res = ((nch <= 3)
2116 && (validate_rparen(CHILD(tree, nch - 1))));
2117
Guido van Rossum3d602e31996-07-21 02:33:56 +00002118 if (res && (nch == 3))
2119 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002120 break;
2121 case LSQB:
2122 res = ((nch <= 3)
2123 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2124
Guido van Rossum3d602e31996-07-21 02:33:56 +00002125 if (res && (nch == 3))
2126 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002127 break;
2128 case LBRACE:
2129 res = ((nch <= 3)
2130 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2131
Guido van Rossum3d602e31996-07-21 02:33:56 +00002132 if (res && (nch == 3))
2133 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002134 break;
2135 case BACKQUOTE:
2136 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002137 && validate_testlist(CHILD(tree, 1))
2138 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2139 break;
2140 case NAME:
2141 case NUMBER:
2142 res = (nch == 1);
2143 break;
2144 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002145 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002146 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002147 break;
2148 default:
2149 res = 0;
2150 break;
2151 }
2152 }
2153 return (res);
2154
2155} /* validate_atom() */
2156
2157
Guido van Rossum3d602e31996-07-21 02:33:56 +00002158/* funcdef:
2159 * 'def' NAME parameters ':' suite
2160 *
2161 */
Guido van Rossum47478871996-08-21 14:32:37 +00002162static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002163validate_funcdef(tree)
2164 node *tree;
2165{
2166 return (validate_ntype(tree, funcdef)
2167 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002168 && validate_name(CHILD(tree, 0), "def")
2169 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002170 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002171 && validate_parameters(CHILD(tree, 2))
2172 && validate_suite(CHILD(tree, 4)));
2173
2174} /* validate_funcdef() */
2175
2176
Guido van Rossum47478871996-08-21 14:32:37 +00002177static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002178validate_lambdef(tree)
2179 node *tree;
2180{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002181 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002182 int res = (validate_ntype(tree, lambdef)
2183 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002184 && validate_name(CHILD(tree, 0), "lambda")
2185 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002186 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002187
Guido van Rossum3d602e31996-07-21 02:33:56 +00002188 if (res && (nch == 4))
2189 res = validate_varargslist(CHILD(tree, 1));
2190 else if (!res && !PyErr_Occurred())
2191 validate_numnodes(tree, 3, "lambdef");
2192
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002193 return (res);
2194
2195} /* validate_lambdef() */
2196
2197
Guido van Rossum3d602e31996-07-21 02:33:56 +00002198/* arglist:
2199 *
2200 * argument (',' argument)* [',']
2201 */
Guido van Rossum47478871996-08-21 14:32:37 +00002202static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002203validate_arglist(tree)
2204 node *tree;
2205{
Guido van Rossum47478871996-08-21 14:32:37 +00002206 return (validate_repeating_list(tree, arglist,
2207 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002208
2209} /* validate_arglist() */
2210
2211
2212
2213/* argument:
2214 *
2215 * [test '='] test
2216 */
Guido van Rossum47478871996-08-21 14:32:37 +00002217static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002218validate_argument(tree)
2219 node *tree;
2220{
2221 int nch = NCH(tree);
2222 int res = (validate_ntype(tree, argument)
2223 && ((nch == 1) || (nch == 3))
2224 && validate_test(CHILD(tree, 0)));
2225
2226 if (res && (nch == 3))
2227 res = (validate_equal(CHILD(tree, 1))
2228 && validate_test(CHILD(tree, 2)));
2229
2230 return (res);
2231
2232} /* validate_argument() */
2233
2234
2235
2236/* trailer:
2237 *
Guido van Rossum47478871996-08-21 14:32:37 +00002238 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002239 */
Guido van Rossum47478871996-08-21 14:32:37 +00002240static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002241validate_trailer(tree)
2242 node *tree;
2243{
2244 int nch = NCH(tree);
2245 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002246
2247 if (res) {
2248 switch (TYPE(CHILD(tree, 0))) {
2249 case LPAR:
2250 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002251 if (res && (nch == 3))
2252 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002253 break;
2254 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002255 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002256 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002257 && validate_ntype(CHILD(tree, 2), RSQB));
2258 break;
2259 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002260 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002261 && validate_ntype(CHILD(tree, 1), NAME));
2262 break;
2263 default:
2264 res = 0;
2265 break;
2266 }
2267 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002268 else
2269 validate_numnodes(tree, 2, "trailer");
2270
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002271 return (res);
2272
2273} /* validate_trailer() */
2274
2275
Guido van Rossum47478871996-08-21 14:32:37 +00002276/* subscriptlist:
2277 *
2278 * subscript (',' subscript)* [',']
2279 */
2280static int
2281validate_subscriptlist(tree)
2282 node *tree;
2283{
2284 return (validate_repeating_list(tree, subscriptlist,
2285 validate_subscript, "subscriptlist"));
2286
2287} /* validate_subscriptlist() */
2288
2289
Guido van Rossum3d602e31996-07-21 02:33:56 +00002290/* subscript:
2291 *
Guido van Rossum47478871996-08-21 14:32:37 +00002292 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002293 */
Guido van Rossum47478871996-08-21 14:32:37 +00002294static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002295validate_subscript(tree)
2296 node *tree;
2297{
Guido van Rossum47478871996-08-21 14:32:37 +00002298 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002299 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002300 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002301
Guido van Rossum47478871996-08-21 14:32:37 +00002302 if (!res) {
2303 if (!PyErr_Occurred())
2304 err_string("invalid number of arguments for subscript node");
2305 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002306 }
Guido van Rossum47478871996-08-21 14:32:37 +00002307 if (TYPE(CHILD(tree, 0)) == DOT)
2308 /* take care of ('.' '.' '.') possibility */
2309 return (validate_numnodes(tree, 3, "subscript")
2310 && validate_dot(CHILD(tree, 0))
2311 && validate_dot(CHILD(tree, 1))
2312 && validate_dot(CHILD(tree, 2)));
2313 if (nch == 1) {
2314 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002315 res = validate_test(CHILD(tree, 0));
2316 else
Guido van Rossum47478871996-08-21 14:32:37 +00002317 res = validate_colon(CHILD(tree, 0));
2318 return (res);
2319 }
2320 /* Must be [test] ':' [test] [sliceop],
2321 * but at least one of the optional components will
2322 * be present, but we don't know which yet.
2323 */
2324 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2325 res = validate_test(CHILD(tree, 0));
2326 offset = 1;
2327 }
2328 if (res)
2329 res = validate_colon(CHILD(tree, offset));
2330 if (res) {
2331 int rem = nch - ++offset;
2332 if (rem) {
2333 if (TYPE(CHILD(tree, offset)) == test) {
2334 res = validate_test(CHILD(tree, offset));
2335 ++offset;
2336 --rem;
2337 }
2338 if (res && rem)
2339 res = validate_sliceop(CHILD(tree, offset));
2340 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002341 }
2342 return (res);
2343
2344} /* validate_subscript() */
2345
2346
Guido van Rossum47478871996-08-21 14:32:37 +00002347static int
2348validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002349 node *tree;
2350{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002351 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002352 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2353 && validate_ntype(tree, sliceop);
2354 if (!res && !PyErr_Occurred()) {
2355 validate_numnodes(tree, 1, "sliceop");
2356 res = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002357 }
Guido van Rossum47478871996-08-21 14:32:37 +00002358 if (res)
2359 res = validate_colon(CHILD(tree, 0));
2360 if (res && (nch == 2))
2361 res = validate_test(CHILD(tree, 1));
2362
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002363 return (res);
2364
Guido van Rossum47478871996-08-21 14:32:37 +00002365} /* validate_sliceop() */
2366
2367
2368static int
2369validate_exprlist(tree)
2370 node *tree;
2371{
2372 return (validate_repeating_list(tree, exprlist,
2373 validate_expr, "exprlist"));
2374
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002375} /* validate_exprlist() */
2376
2377
Guido van Rossum47478871996-08-21 14:32:37 +00002378static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002379validate_dictmaker(tree)
2380 node *tree;
2381{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002382 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002383 int res = (validate_ntype(tree, dictmaker)
2384 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002385 && validate_test(CHILD(tree, 0))
2386 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002387 && validate_test(CHILD(tree, 2)));
2388
Guido van Rossum3d602e31996-07-21 02:33:56 +00002389 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002390 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002391 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002392 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002393
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002394 if (res && (nch > 3)) {
2395 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002396 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002397 while (res && (pos < nch)) {
2398 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002399 && validate_test(CHILD(tree, pos + 1))
2400 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002401 && validate_test(CHILD(tree, pos + 3)));
2402 pos += 4;
2403 }
2404 }
2405 return (res);
2406
2407} /* validate_dictmaker() */
2408
2409
Guido van Rossum47478871996-08-21 14:32:37 +00002410static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002411validate_eval_input(tree)
2412 node *tree;
2413{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002414 int pos;
2415 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002416 int res = (validate_ntype(tree, eval_input)
2417 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002418 && validate_testlist(CHILD(tree, 0))
2419 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2420
Guido van Rossum3d602e31996-07-21 02:33:56 +00002421 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002422 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002423
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002424 return (res);
2425
2426} /* validate_eval_input() */
2427
2428
Guido van Rossum47478871996-08-21 14:32:37 +00002429static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002430validate_node(tree)
2431 node *tree;
2432{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002433 int nch = 0; /* num. children on current node */
2434 int res = 1; /* result value */
2435 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002436
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002437 while (res & (tree != 0)) {
2438 nch = NCH(tree);
2439 next = 0;
2440 switch (TYPE(tree)) {
2441 /*
2442 * Definition nodes.
2443 */
2444 case funcdef:
2445 res = validate_funcdef(tree);
2446 break;
2447 case classdef:
2448 res = validate_class(tree);
2449 break;
2450 /*
2451 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002452 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002453 */
2454 case stmt:
2455 res = validate_stmt(tree);
2456 break;
2457 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002458 /*
2459 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum925e5471997-04-02 05:32:13 +00002460 * | import_stmt | global_stmt | exec_stmt | assert_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002461 */
2462 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002463 break;
2464 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002465 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002466 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2467 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2468 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002469 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2470 if (res)
2471 next = CHILD(tree, 0);
2472 else if (nch == 1)
2473 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002474 break;
2475 /*
2476 * Compound statements.
2477 */
2478 case simple_stmt:
2479 res = validate_simple_stmt(tree);
2480 break;
2481 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002482 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002483 break;
2484 /*
2485 * Fundemental statements.
2486 */
2487 case expr_stmt:
2488 res = validate_expr_stmt(tree);
2489 break;
2490 case print_stmt:
2491 res = validate_print_stmt(tree);
2492 break;
2493 case del_stmt:
2494 res = validate_del_stmt(tree);
2495 break;
2496 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002497 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002498 && validate_name(CHILD(tree, 0), "pass"));
2499 break;
2500 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002501 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002502 && validate_name(CHILD(tree, 0), "break"));
2503 break;
2504 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002505 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002506 && validate_name(CHILD(tree, 0), "continue"));
2507 break;
2508 case return_stmt:
2509 res = validate_return_stmt(tree);
2510 break;
2511 case raise_stmt:
2512 res = validate_raise_stmt(tree);
2513 break;
2514 case import_stmt:
2515 res = validate_import_stmt(tree);
2516 break;
2517 case global_stmt:
2518 res = validate_global_stmt(tree);
2519 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002520 case exec_stmt:
2521 res = validate_exec_stmt(tree);
2522 break;
Guido van Rossum925e5471997-04-02 05:32:13 +00002523 case assert_stmt:
2524 res = validate_assert_stmt(tree);
2525 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002526 case if_stmt:
2527 res = validate_if(tree);
2528 break;
2529 case while_stmt:
2530 res = validate_while(tree);
2531 break;
2532 case for_stmt:
2533 res = validate_for(tree);
2534 break;
2535 case try_stmt:
2536 res = validate_try(tree);
2537 break;
2538 case suite:
2539 res = validate_suite(tree);
2540 break;
2541 /*
2542 * Expression nodes.
2543 */
2544 case testlist:
2545 res = validate_testlist(tree);
2546 break;
2547 case test:
2548 res = validate_test(tree);
2549 break;
2550 case and_test:
2551 res = validate_and_test(tree);
2552 break;
2553 case not_test:
2554 res = validate_not_test(tree);
2555 break;
2556 case comparison:
2557 res = validate_comparison(tree);
2558 break;
2559 case exprlist:
2560 res = validate_exprlist(tree);
2561 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002562 case comp_op:
2563 res = validate_comp_op(tree);
2564 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002565 case expr:
2566 res = validate_expr(tree);
2567 break;
2568 case xor_expr:
2569 res = validate_xor_expr(tree);
2570 break;
2571 case and_expr:
2572 res = validate_and_expr(tree);
2573 break;
2574 case shift_expr:
2575 res = validate_shift_expr(tree);
2576 break;
2577 case arith_expr:
2578 res = validate_arith_expr(tree);
2579 break;
2580 case term:
2581 res = validate_term(tree);
2582 break;
2583 case factor:
2584 res = validate_factor(tree);
2585 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002586 case power:
2587 res = validate_power(tree);
2588 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002589 case atom:
2590 res = validate_atom(tree);
2591 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002592
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002593 default:
2594 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002595 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002596 res = 0;
2597 break;
2598 }
2599 tree = next;
2600 }
2601 return (res);
2602
2603} /* validate_node() */
2604
2605
Guido van Rossum47478871996-08-21 14:32:37 +00002606static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002607validate_expr_tree(tree)
2608 node *tree;
2609{
2610 int res = validate_eval_input(tree);
2611
2612 if (!res && !PyErr_Occurred())
2613 err_string("Could not validate expression tuple.");
2614
2615 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002616
2617} /* validate_expr_tree() */
2618
2619
Guido van Rossum3d602e31996-07-21 02:33:56 +00002620/* file_input:
2621 * (NEWLINE | stmt)* ENDMARKER
2622 */
Guido van Rossum47478871996-08-21 14:32:37 +00002623static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002624validate_file_input(tree)
2625 node *tree;
2626{
2627 int j = 0;
2628 int nch = NCH(tree) - 1;
2629 int res = ((nch >= 0)
2630 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002631
Guido van Rossum3d602e31996-07-21 02:33:56 +00002632 for ( ; res && (j < nch); ++j) {
2633 if (TYPE(CHILD(tree, j)) == stmt)
2634 res = validate_stmt(CHILD(tree, j));
2635 else
2636 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002637 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002638 /* This stays in to prevent any internal failues from getting to the
2639 * user. Hopefully, this won't be needed. If a user reports getting
2640 * this, we have some debugging to do.
2641 */
2642 if (!res && !PyErr_Occurred())
2643 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2644
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002645 return (res);
2646
Guido van Rossum2a288461996-08-21 21:55:43 +00002647} /* validate_file_input() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002648
2649
Fred Drake43f8f9b1998-04-13 16:25:46 +00002650static PyObject*
2651pickle_constructor = NULL;
2652
2653
2654static PyObject*
2655parser__pickler(self, args)
2656 PyObject *self;
2657 PyObject *args;
2658{
2659 PyObject *result = NULL;
2660 PyObject *ast = NULL;
2661
2662 if (PyArg_ParseTuple(args, "O!:_pickler", &PyAST_Type, &ast)) {
2663 PyObject *newargs;
2664 PyObject *tuple;
2665
2666 if ((newargs = Py_BuildValue("Oi", ast, 1)) == NULL)
2667 goto finally;
2668 tuple = parser_ast2tuple(NULL, newargs);
2669 if (tuple != NULL) {
2670 result = Py_BuildValue("O(O)", pickle_constructor, tuple);
2671 Py_DECREF(tuple);
2672 }
2673 Py_XDECREF(newargs);
2674 }
2675 finally:
2676 return (result);
2677
2678} /* parser__pickler() */
2679
2680
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002681/* Functions exported by this module. Most of this should probably
2682 * be converted into an AST object with methods, but that is better
2683 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002684 * We'd really have to write a wrapper around it all anyway to allow
2685 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002686 */
2687static PyMethodDef parser_functions[] = {
Fred Drake43f8f9b1998-04-13 16:25:46 +00002688 {"ast2tuple", parser_ast2tuple, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002689 "Creates a tuple-tree representation of an AST."},
Fred Drake43f8f9b1998-04-13 16:25:46 +00002690 {"ast2list", parser_ast2list, METH_VARARGS,
Guido van Rossum47478871996-08-21 14:32:37 +00002691 "Creates a list-tree representation of an AST."},
Fred Drake43f8f9b1998-04-13 16:25:46 +00002692 {"compileast", parser_compileast, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002693 "Compiles an AST object into a code object."},
Fred Drake43f8f9b1998-04-13 16:25:46 +00002694 {"expr", parser_expr, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002695 "Creates an AST object from an expression."},
Fred Drake43f8f9b1998-04-13 16:25:46 +00002696 {"isexpr", parser_isexpr, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002697 "Determines if an AST object was created from an expression."},
Fred Drake43f8f9b1998-04-13 16:25:46 +00002698 {"issuite", parser_issuite, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002699 "Determines if an AST object was created from a suite."},
Fred Drake43f8f9b1998-04-13 16:25:46 +00002700 {"suite", parser_suite, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002701 "Creates an AST object from a suite."},
Fred Drake43f8f9b1998-04-13 16:25:46 +00002702 {"sequence2ast", parser_tuple2ast, METH_VARARGS,
Guido van Rossum47478871996-08-21 14:32:37 +00002703 "Creates an AST object from a tree representation."},
Fred Drake43f8f9b1998-04-13 16:25:46 +00002704 {"tuple2ast", parser_tuple2ast, METH_VARARGS,
Guido van Rossum47478871996-08-21 14:32:37 +00002705 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002706
Fred Drake43f8f9b1998-04-13 16:25:46 +00002707 /* private stuff: support pickle module */
2708 {"_pickler", parser__pickler, METH_VARARGS,
2709 "Returns the pickle magic to allow ast objects to be pickled."},
2710
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002711 {0, 0, 0}
2712 };
2713
2714
Guido van Rossum52f2c051993-11-10 12:53:24 +00002715void
Guido van Rossum3d602e31996-07-21 02:33:56 +00002716initparser()
2717 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002718 PyObject* module;
2719 PyObject* dict;
2720
2721 PyAST_Type.ob_type = &PyType_Type;
2722 module = Py_InitModule("parser", parser_functions);
2723 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002724
Fred Drake0225a381997-10-07 19:32:00 +00002725 parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002726
2727 if ((parser_error == 0)
2728 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2729 /*
2730 * This is serious.
2731 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002732 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002733 }
2734 /*
2735 * Nice to have, but don't cry if we fail.
2736 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002737 Py_INCREF(&PyAST_Type);
2738 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2739
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002740 PyDict_SetItemString(dict, "__copyright__",
2741 PyString_FromString(parser_copyright_string));
2742 PyDict_SetItemString(dict, "__doc__",
2743 PyString_FromString(parser_doc_string));
2744 PyDict_SetItemString(dict, "__version__",
2745 PyString_FromString(parser_version_string));
2746
Fred Drake503d8d61998-04-13 18:45:18 +00002747 parser_method_list = PyList_New(0);
2748 if (parser_method_list != NULL) {
2749 PyMethodDef *mdef = parser_methods;
2750
2751 while (mdef->ml_name != NULL) {
2752 PyObject *temp = PyString_FromString(mdef->ml_name);
2753 if (temp != NULL) {
2754 PyList_Append(parser_method_list, temp);
2755 Py_DECREF(temp);
2756 }
2757 ++mdef;
2758 }
2759 }
2760
Fred Drake43f8f9b1998-04-13 16:25:46 +00002761 /* register to support pickling */
2762 module = PyImport_ImportModule("copy_reg");
2763 if (module != NULL) {
2764 PyObject *func, *constructor, *pickler;
2765
2766 func = PyObject_GetAttrString(module, "pickle");
2767 pickle_constructor = PyDict_GetItemString(dict, "sequence2ast");
2768 pickler = PyDict_GetItemString(dict, "_pickler");
2769 Py_XINCREF(pickle_constructor);
2770 if ((func != NULL) && (pickle_constructor != NULL)
2771 && (pickler != NULL)) {
2772 PyObject *res;
2773
2774 res = PyObject_CallFunction(
2775 func, "OOO", &PyAST_Type, pickler, pickle_constructor);
2776 Py_XDECREF(res);
2777 }
2778 Py_XDECREF(func);
2779 Py_DECREF(module);
2780 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002781} /* initparser() */