blob: 0c12a07696f2c9e68ad1e09f904d593a0d949db6 [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[] = {
Fred Drake301b5be1998-04-21 22:31:45 +0000476 {"compile", (PyCFunction)parser_compileast, METH_VARARGS,
477 "Compile this AST object into a code object."},
478 {"isexpr", (PyCFunction)parser_isexpr, METH_VARARGS,
479 "Determines if this AST object was created from an expression."},
480 {"issuite", (PyCFunction)parser_issuite, METH_VARARGS,
481 "Determines if this AST object was created from a suite."},
482 {"tolist", (PyCFunction)parser_ast2list, METH_VARARGS,
483 "Creates a list-tree representation of this AST."},
484 {"totuple", (PyCFunction)parser_ast2tuple, METH_VARARGS,
485 "Creates a tuple-tree representation of this AST."},
Fred Drake503d8d61998-04-13 18:45:18 +0000486
487 {NULL}
488};
489
490static PyObject*
491parser_method_list = NULL;
492
493
494static PyObject*
495parser_getattr(self, name)
496 PyObject *self;
497 char *name;
498{
499 if (strcmp(name, "__methods__") == 0) {
500 Py_INCREF(parser_method_list);
501 return (parser_method_list);
502 }
503 return (Py_FindMethod(parser_methods, self, name));
504
505} /* parser_getattr() */
506
507
Guido van Rossum3d602e31996-07-21 02:33:56 +0000508/* err_string(char* message)
509 *
510 * Sets the error string for an exception of type ParserError.
511 *
512 */
513static void
514err_string(message)
515 char *message;
Guido van Rossum47478871996-08-21 14:32:37 +0000516{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000517 PyErr_SetString(parser_error, message);
518
519} /* err_string() */
520
521
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000522/* PyObject* parser_do_parse(PyObject* args, int type)
523 *
524 * Internal function to actually execute the parse and return the result if
525 * successful, or set an exception if not.
526 *
527 */
528static PyObject*
529parser_do_parse(args, type)
530 PyObject *args;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000531 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000532{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000533 char* string = 0;
534 PyObject* res = 0;
535
536 if (PyArg_ParseTuple(args, "s", &string)) {
537 node* n = PyParser_SimpleParseString(string,
538 (type == PyAST_EXPR)
539 ? eval_input : file_input);
540
541 if (n != 0)
542 res = parser_newastobject(n, type);
543 else
Guido van Rossum3d602e31996-07-21 02:33:56 +0000544 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000545 }
546 return (res);
547
548} /* parser_do_parse() */
549
550
551/* PyObject* parser_expr(PyObject* self, PyObject* args)
552 * PyObject* parser_suite(PyObject* self, PyObject* args)
553 *
554 * External interfaces to the parser itself. Which is called determines if
555 * the parser attempts to recognize an expression ('eval' form) or statement
556 * suite ('exec' form). The real work is done by parser_do_parse() above.
557 *
558 */
559static PyObject*
560parser_expr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000561 PyObject *self;
562 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000563{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000564 return (parser_do_parse(args, PyAST_EXPR));
565
566} /* parser_expr() */
567
568
569static PyObject*
570parser_suite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000571 PyObject *self;
572 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000573{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000574 return (parser_do_parse(args, PyAST_SUITE));
575
576} /* parser_suite() */
577
578
579
580/* This is the messy part of the code. Conversion from a tuple to an AST
581 * object requires that the input tuple be valid without having to rely on
582 * catching an exception from the compiler. This is done to allow the
583 * compiler itself to remain fast, since most of its input will come from
584 * the parser directly, and therefore be known to be syntactically correct.
585 * This validation is done to ensure that we don't core dump the compile
586 * phase, returning an exception instead.
587 *
588 * Two aspects can be broken out in this code: creating a node tree from
589 * the tuple passed in, and verifying that it is indeed valid. It may be
590 * advantageous to expand the number of AST types to include funcdefs and
591 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
592 * here. They are not necessary, and not quite as useful in a raw form.
593 * For now, let's get expressions and suites working reliably.
594 */
595
596
Guido van Rossum2a288461996-08-21 21:55:43 +0000597staticforward node* build_node_tree Py_PROTO((PyObject *tuple));
598staticforward int validate_expr_tree Py_PROTO((node *tree));
599staticforward int validate_file_input Py_PROTO((node *tree));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000600
601
602/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
603 *
604 * This is the public function, called from the Python code. It receives a
605 * single tuple object from the caller, and creates an AST object if the
606 * tuple can be validated. It does this by checking the first code of the
607 * tuple, and, if acceptable, builds the internal representation. If this
608 * step succeeds, the internal representation is validated as fully as
609 * possible with the various validate_*() routines defined below.
610 *
611 * This function must be changed if support is to be added for PyAST_FRAGMENT
612 * AST objects.
613 *
614 */
615static PyObject*
616parser_tuple2ast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000617 PyObject *self;
618 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000619{
620 PyObject *ast = 0;
621 PyObject *tuple = 0;
622 PyObject *temp = 0;
623 int ok;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000624 int start_sym = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000625
Guido van Rossum47478871996-08-21 14:32:37 +0000626 if (!PyArg_ParseTuple(args, "O:tuple2ast", &tuple))
627 return (0);
628 if (!PySequence_Check(tuple)) {
629 PyErr_SetString(PyExc_ValueError,
630 "tuple2ast() requires a single sequence argument");
631 return (0);
632 }
633 /*
634 * This mess of tests is written this way so we can use the abstract
635 * object interface (AOI). Unfortunately, the AOI increments reference
636 * counts, which requires that we store a pointer to retrieved object
637 * so we can DECREF it after the check. But we really should accept
638 * lists as well as tuples at the very least.
639 */
640 ok = PyObject_Length(tuple) >= 2;
641 if (ok) {
642 temp = PySequence_GetItem(tuple, 0);
643 ok = (temp != NULL) && PyInt_Check(temp);
644 if (ok)
645 /* this is used after the initial checks: */
646 start_sym = PyInt_AsLong(temp);
647 Py_XDECREF(temp);
648 }
649 if (ok) {
650 temp = PySequence_GetItem(tuple, 1);
651 ok = (temp != NULL) && PySequence_Check(temp);
652 Py_XDECREF(temp);
653 }
654 if (ok) {
655 temp = PySequence_GetItem(tuple, 1);
656 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
657 if (ok) {
658 PyObject *temp2 = PySequence_GetItem(temp, 0);
659 if (temp2 != NULL) {
660 ok = PyInt_Check(temp2);
661 Py_DECREF(temp2);
662 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000663 }
Guido van Rossum47478871996-08-21 14:32:37 +0000664 Py_XDECREF(temp);
665 }
666 /* If we've failed at some point, get out of here. */
667 if (!ok) {
668 err_string("malformed sequence for tuple2ast()");
669 return (0);
670 }
671 /*
672 * This might be a valid parse tree, but let's do a quick check
673 * before we jump the gun.
674 */
675 if (start_sym == eval_input) {
676 /* Might be an eval form. */
677 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000678
Guido van Rossum47478871996-08-21 14:32:37 +0000679 if ((expression != 0) && validate_expr_tree(expression))
680 ast = parser_newastobject(expression, PyAST_EXPR);
681 }
682 else if (start_sym == file_input) {
683 /* This looks like an exec form so far. */
684 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000685
Guido van Rossum47478871996-08-21 14:32:37 +0000686 if ((suite_tree != 0) && validate_file_input(suite_tree))
687 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000688 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000689 else
Guido van Rossum47478871996-08-21 14:32:37 +0000690 /* This is a fragment, and is not yet supported. Maybe they
691 * will be if I find a use for them.
692 */
693 err_string("Fragmentary parse trees not supported.");
694
695 /* Make sure we throw an exception on all errors. We should never
696 * get this, but we'd do well to be sure something is done.
697 */
698 if ((ast == 0) && !PyErr_Occurred())
699 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000700
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000701 return (ast);
702
703} /* parser_tuple2ast() */
704
705
706/* int check_terminal_tuple()
707 *
Guido van Rossum47478871996-08-21 14:32:37 +0000708 * Check a tuple to determine that it is indeed a valid terminal
709 * node. The node is known to be required as a terminal, so we throw
710 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000711 *
Guido van Rossum47478871996-08-21 14:32:37 +0000712 * The format of an acceptable terminal tuple is "(is[i])": the fact
713 * that elem is a tuple and the integer is a valid terminal symbol
714 * has been established before this function is called. We must
715 * check the length of the tuple and the type of the second element
716 * and optional third element. We do *NOT* check the actual text of
717 * the string element, which we could do in many cases. This is done
718 * by the validate_*() functions which operate on the internal
719 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000720 */
721static int
Guido van Rossum47478871996-08-21 14:32:37 +0000722check_terminal_tuple(elem)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000723 PyObject *elem;
Guido van Rossum47478871996-08-21 14:32:37 +0000724{
725 int len = PyObject_Length(elem);
726 int res = 1;
727 char* str = "Illegal terminal symbol; bad node length.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000728
Guido van Rossum47478871996-08-21 14:32:37 +0000729 if ((len == 2) || (len == 3)) {
730 PyObject *temp = PySequence_GetItem(elem, 1);
731 res = PyString_Check(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000732 str = "Illegal terminal symbol; expected a string.";
Guido van Rossum47478871996-08-21 14:32:37 +0000733 if (res && (len == 3)) {
734 PyObject* third = PySequence_GetItem(elem, 2);
735 res = PyInt_Check(third);
736 str = "Invalid third element of terminal node.";
737 Py_XDECREF(third);
738 }
739 Py_XDECREF(temp);
740 }
741 else {
742 res = 0;
743 }
744 if (!res) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000745 elem = Py_BuildValue("(os)", elem, str);
746 PyErr_SetObject(parser_error, elem);
747 }
748 return (res);
749
750} /* check_terminal_tuple() */
751
752
753/* node* build_node_children()
754 *
755 * Iterate across the children of the current non-terminal node and build
756 * their structures. If successful, return the root of this portion of
757 * the tree, otherwise, 0. Any required exception will be specified already,
758 * and no memory will have been deallocated.
759 *
760 */
761static node*
762build_node_children(tuple, root, line_num)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000763 PyObject *tuple;
764 node *root;
765 int *line_num;
Guido van Rossum47478871996-08-21 14:32:37 +0000766{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000767 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000768 int i;
769
770 for (i = 1; i < len; ++i) {
771 /* elem must always be a tuple, however simple */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000772 PyObject* elem = PySequence_GetItem(tuple, i);
Guido van Rossum47478871996-08-21 14:32:37 +0000773 int ok = elem != NULL;
774 long type = 0;
775 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000776
Guido van Rossum47478871996-08-21 14:32:37 +0000777 if (ok)
778 ok = PySequence_Check(elem);
779 if (ok) {
780 PyObject *temp = PySequence_GetItem(elem, 0);
781 if (temp == NULL)
782 ok = 0;
783 else {
784 ok = PyInt_Check(temp);
785 if (ok)
786 type = PyInt_AsLong(temp);
787 Py_DECREF(temp);
788 }
789 }
790 if (!ok) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000791 PyErr_SetObject(parser_error,
792 Py_BuildValue("(os)", elem,
793 "Illegal node construct."));
Guido van Rossum47478871996-08-21 14:32:37 +0000794 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000795 return (0);
796 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000797 if (ISTERMINAL(type)) {
Guido van Rossum47478871996-08-21 14:32:37 +0000798 if (check_terminal_tuple(elem)) {
799 PyObject *temp = PySequence_GetItem(elem, 1);
800
Fred Draked49266e1997-10-09 16:29:31 +0000801 /* check_terminal_tuple() already verified it's a string */
802 strn = (char *)malloc(PyString_GET_SIZE(temp) + 1);
803 if (strn != NULL)
804 strcpy(strn, PyString_AS_STRING(temp));
Guido van Rossum47478871996-08-21 14:32:37 +0000805 Py_XDECREF(temp);
806
807 if (PyObject_Length(elem) == 3) {
808 PyObject* temp = PySequence_GetItem(elem, 2);
809 *line_num = PyInt_AsLong(temp);
810 Py_DECREF(temp);
811 }
812 }
813 else {
814 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000815 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000816 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000817 }
818 else if (!ISNONTERMINAL(type)) {
819 /*
820 * It has to be one or the other; this is an error.
821 * Throw an exception.
822 */
823 PyErr_SetObject(parser_error,
824 Py_BuildValue("(os)", elem,
825 "Unknown node type."));
Guido van Rossum47478871996-08-21 14:32:37 +0000826 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000827 return (0);
828 }
829 PyNode_AddChild(root, type, strn, *line_num);
830
831 if (ISNONTERMINAL(type)) {
832 node* new_child = CHILD(root, i - 1);
833
Guido van Rossum47478871996-08-21 14:32:37 +0000834 if (new_child != build_node_children(elem, new_child, line_num)) {
835 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000836 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000837 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000838 }
Guido van Rossum47478871996-08-21 14:32:37 +0000839 else if (type == NEWLINE) { /* It's true: we increment the */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000840 ++(*line_num); /* line number *after* the newline! */
Guido van Rossum47478871996-08-21 14:32:37 +0000841 }
842 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000843 }
844 return (root);
845
846} /* build_node_children() */
847
848
849static node*
850build_node_tree(tuple)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000851 PyObject *tuple;
Guido van Rossum47478871996-08-21 14:32:37 +0000852{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000853 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000854 PyObject *temp = PySequence_GetItem(tuple, 0);
855 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000856
Guido van Rossum47478871996-08-21 14:32:37 +0000857 if (temp != NULL)
858 num = PyInt_AsLong(temp);
859 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000860 if (ISTERMINAL(num)) {
861 /*
862 * The tuple is simple, but it doesn't start with a start symbol.
863 * Throw an exception now and be done with it.
864 */
865 tuple = Py_BuildValue("(os)", tuple,
Guido van Rossum3d602e31996-07-21 02:33:56 +0000866 "Illegal ast tuple; cannot start with terminal symbol.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000867 PyErr_SetObject(parser_error, tuple);
868 }
869 else if (ISNONTERMINAL(num)) {
870 /*
871 * Not efficient, but that can be handled later.
872 */
873 int line_num = 0;
874
875 res = PyNode_New(num);
876 if (res != build_node_children(tuple, res, &line_num)) {
877 PyNode_Free(res);
878 res = 0;
879 }
880 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000881 else
882 /* The tuple is illegal -- if the number is neither TERMINAL nor
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000883 * NONTERMINAL, we can't use it.
884 */
885 PyErr_SetObject(parser_error,
886 Py_BuildValue("(os)", tuple,
887 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000888
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000889 return (res);
890
891} /* build_node_tree() */
892
893
Guido van Rossum360a9341996-08-21 19:04:10 +0000894#ifdef HAVE_OLD_CPP
Guido van Rossum2a288461996-08-21 21:55:43 +0000895#define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000896#else
Guido van Rossum2a288461996-08-21 21:55:43 +0000897#define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000898#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000899
900
901/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000902 * Validation routines used within the validation section:
903 */
Guido van Rossum2a288461996-08-21 21:55:43 +0000904staticforward int validate_terminal Py_PROTO((node *terminal,
905 int type, char *string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000906
907#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
908#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
909#define validate_colon(ch) validate_terminal(ch, COLON, ":")
910#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
911#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
912#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000913#define validate_indent(ch) validate_terminal(ch, INDENT, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000914#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000915#define validate_newline(ch) validate_terminal(ch, NEWLINE, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000916#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
917#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
918#define validate_star(ch) validate_terminal(ch, STAR, "*")
919#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000920#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
Guido van Rossum47478871996-08-21 14:32:37 +0000921#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000922#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000923
Guido van Rossum3d602e31996-07-21 02:33:56 +0000924VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000925VALIDATER(class); VALIDATER(node);
926VALIDATER(parameters); VALIDATER(suite);
927VALIDATER(testlist); VALIDATER(varargslist);
928VALIDATER(fpdef); VALIDATER(fplist);
929VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000930VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000931VALIDATER(print_stmt); VALIDATER(del_stmt);
932VALIDATER(return_stmt);
933VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000934VALIDATER(global_stmt);
Guido van Rossum925e5471997-04-02 05:32:13 +0000935VALIDATER(assert_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000936VALIDATER(exec_stmt); VALIDATER(compound_stmt);
937VALIDATER(while); VALIDATER(for);
938VALIDATER(try); VALIDATER(except_clause);
939VALIDATER(test); VALIDATER(and_test);
940VALIDATER(not_test); VALIDATER(comparison);
941VALIDATER(comp_op); VALIDATER(expr);
942VALIDATER(xor_expr); VALIDATER(and_expr);
943VALIDATER(shift_expr); VALIDATER(arith_expr);
944VALIDATER(term); VALIDATER(factor);
945VALIDATER(atom); VALIDATER(lambdef);
946VALIDATER(trailer); VALIDATER(subscript);
Guido van Rossum47478871996-08-21 14:32:37 +0000947VALIDATER(subscriptlist); VALIDATER(sliceop);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000948VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000949VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000950
951
952#define is_even(n) (((n) & 1) == 0)
953#define is_odd(n) (((n) & 1) == 1)
954
955
956static int
957validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000958 node *n;
959 int t;
Guido van Rossum47478871996-08-21 14:32:37 +0000960{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000961 int res = (TYPE(n) == t);
962
963 if (!res) {
964 char buffer[128];
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000965 sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000966 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000967 }
968 return (res);
969
970} /* validate_ntype() */
971
972
973static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000974validate_numnodes(n, num, name)
975 node *n;
976 int num;
977 const char *const name;
Guido van Rossum47478871996-08-21 14:32:37 +0000978{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000979 if (NCH(n) != num) {
980 char buff[60];
981 sprintf(buff, "Illegal number of children for %s node.", name);
982 err_string(buff);
983 }
984 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000985
Guido van Rossum3d602e31996-07-21 02:33:56 +0000986} /* validate_numnodes() */
987
988
989static int
990validate_terminal(terminal, type, string)
991 node *terminal;
992 int type;
993 char *string;
Guido van Rossum47478871996-08-21 14:32:37 +0000994{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000995 int res = (validate_ntype(terminal, type)
996 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
997
998 if (!res && !PyErr_Occurred()) {
999 char buffer[60];
1000 sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
1001 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001002 }
1003 return (res);
1004
1005} /* validate_terminal() */
1006
1007
Guido van Rossum47478871996-08-21 14:32:37 +00001008/* X (',' X) [',']
1009 */
1010static int
1011validate_repeating_list(tree, ntype, vfunc, name)
1012 node *tree;
1013 int ntype;
1014 int (*vfunc)();
1015 const char *const name;
1016{
1017 int nch = NCH(tree);
1018 int res = (nch && validate_ntype(tree, ntype)
1019 && vfunc(CHILD(tree, 0)));
1020
1021 if (!res && !PyErr_Occurred())
1022 validate_numnodes(tree, 1, name);
1023 else {
1024 if (is_even(nch))
1025 res = validate_comma(CHILD(tree, --nch));
1026 if (res && nch > 1) {
1027 int pos = 1;
1028 for ( ; res && pos < nch; pos += 2)
1029 res = (validate_comma(CHILD(tree, pos))
1030 && vfunc(CHILD(tree, pos + 1)));
1031 }
1032 }
1033 return (res);
1034
1035} /* validate_repeating_list() */
1036
1037
Guido van Rossum3d602e31996-07-21 02:33:56 +00001038/* VALIDATE(class)
1039 *
1040 * classdef:
1041 * 'class' NAME ['(' testlist ')'] ':' suite
1042 */
Guido van Rossum47478871996-08-21 14:32:37 +00001043static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001044validate_class(tree)
1045 node *tree;
1046{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001047 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001048 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001049
Guido van Rossum3d602e31996-07-21 02:33:56 +00001050 if (res) {
1051 res = (validate_name(CHILD(tree, 0), "class")
1052 && validate_ntype(CHILD(tree, 1), NAME)
1053 && validate_colon(CHILD(tree, nch - 2))
1054 && validate_suite(CHILD(tree, nch - 1)));
1055 }
1056 else
1057 validate_numnodes(tree, 4, "class");
1058 if (res && (nch == 7)) {
1059 res = (validate_lparen(CHILD(tree, 2))
1060 && validate_testlist(CHILD(tree, 3))
1061 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001062 }
1063 return (res);
1064
1065} /* validate_class() */
1066
1067
Guido van Rossum3d602e31996-07-21 02:33:56 +00001068/* if_stmt:
1069 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1070 */
Guido van Rossum47478871996-08-21 14:32:37 +00001071static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001072validate_if(tree)
1073 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001074{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001075 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001076 int res = (validate_ntype(tree, if_stmt)
1077 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001078 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +00001079 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001080 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001081 && validate_suite(CHILD(tree, 3)));
1082
1083 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001084 /* ... 'else' ':' suite */
1085 res = (validate_name(CHILD(tree, nch - 3), "else")
1086 && validate_colon(CHILD(tree, nch - 2))
1087 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001088 nch -= 3;
1089 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001090 else if (!res && !PyErr_Occurred())
1091 validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001092 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001093 /* Will catch the case for nch < 4 */
1094 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001095 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001096 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001097 int j = 4;
1098 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001099 res = (validate_name(CHILD(tree, j), "elif")
1100 && validate_colon(CHILD(tree, j + 2))
1101 && validate_test(CHILD(tree, j + 1))
1102 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001103 j += 4;
1104 }
1105 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001106 return (res);
1107
1108} /* validate_if() */
1109
1110
Guido van Rossum3d602e31996-07-21 02:33:56 +00001111/* parameters:
1112 * '(' [varargslist] ')'
1113 *
1114 */
Guido van Rossum47478871996-08-21 14:32:37 +00001115static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001116validate_parameters(tree)
1117 node *tree;
1118{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001119 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001120 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001121
Guido van Rossum3d602e31996-07-21 02:33:56 +00001122 if (res) {
1123 res = (validate_lparen(CHILD(tree, 0))
1124 && validate_rparen(CHILD(tree, nch - 1)));
1125 if (res && (nch == 3))
1126 res = validate_varargslist(CHILD(tree, 1));
1127 }
1128 else
1129 validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001130
1131 return (res);
1132
1133} /* validate_parameters() */
1134
1135
Guido van Rossum3d602e31996-07-21 02:33:56 +00001136/* VALIDATE(suite)
1137 *
1138 * suite:
1139 * simple_stmt
1140 * | NEWLINE INDENT stmt+ DEDENT
1141 */
Guido van Rossum47478871996-08-21 14:32:37 +00001142static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001143validate_suite(tree)
1144 node *tree;
1145{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001146 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001147 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001148
Guido van Rossum3d602e31996-07-21 02:33:56 +00001149 if (res && (nch == 1))
1150 res = validate_simple_stmt(CHILD(tree, 0));
1151 else if (res) {
1152 /* NEWLINE INDENT stmt+ DEDENT */
1153 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001154 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001155 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001156 && validate_dedent(CHILD(tree, nch - 1)));
1157
Guido van Rossum3d602e31996-07-21 02:33:56 +00001158 if (res && (nch > 4)) {
1159 int i = 3;
1160 --nch; /* forget the DEDENT */
1161 for ( ; res && (i < nch); ++i)
1162 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001163 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001164 else if (nch < 4)
1165 validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001166 }
1167 return (res);
1168
1169} /* validate_suite() */
1170
1171
Guido van Rossum47478871996-08-21 14:32:37 +00001172static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001173validate_testlist(tree)
1174 node *tree;
1175{
Guido van Rossum47478871996-08-21 14:32:37 +00001176 return (validate_repeating_list(tree, testlist,
1177 validate_test, "testlist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001178
1179} /* validate_testlist() */
1180
1181
Guido van Rossum3d602e31996-07-21 02:33:56 +00001182/* VALIDATE(varargslist)
1183 *
1184 * varargslist:
1185 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1186 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1187 *
1188 * (fpdef ['=' test] ',')*
1189 * ('*' NAME [',' ('**'|'*' '*') NAME]
1190 * | ('**'|'*' '*') NAME)
1191 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1192 *
1193 */
Guido van Rossum47478871996-08-21 14:32:37 +00001194static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001195validate_varargslist(tree)
1196 node *tree;
1197{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001198 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001199 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001200
Guido van Rossum3d602e31996-07-21 02:33:56 +00001201 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1202 /* (fpdef ['=' test] ',')*
1203 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1204 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001205 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001206 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001207
Guido van Rossum3d602e31996-07-21 02:33:56 +00001208 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1209 res = validate_fpdef(CHILD(tree, pos));
1210 if (res) {
1211 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1212 res = validate_test(CHILD(tree, pos + 2));
1213 pos += 2;
1214 }
1215 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001216 pos += 2;
1217 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001218 }
1219 if (res) {
1220 remaining = nch - pos;
1221 res = ((remaining == 2) || (remaining == 3)
1222 || (remaining == 5) || (remaining == 6));
1223 if (!res)
1224 validate_numnodes(tree, 2, "varargslist");
1225 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1226 return ((remaining == 2)
1227 && validate_ntype(CHILD(tree, pos+1), NAME));
1228 else {
1229 res = validate_star(CHILD(tree, pos++));
1230 --remaining;
1231 }
1232 }
1233 if (res) {
1234 if (remaining == 2) {
1235 res = (validate_star(CHILD(tree, pos))
1236 && validate_ntype(CHILD(tree, pos + 1), NAME));
1237 }
1238 else {
1239 res = validate_ntype(CHILD(tree, pos++), NAME);
1240 if (res && (remaining >= 4)) {
1241 res = validate_comma(CHILD(tree, pos));
1242 if (--remaining == 3)
Fred Drakee1607a81996-09-11 21:58:26 +00001243 res = (validate_star(CHILD(tree, pos + 1))
1244 && validate_star(CHILD(tree, pos + 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001245 else
1246 validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1247 }
1248 }
1249 }
1250 if (!res && !PyErr_Occurred())
1251 err_string("Incorrect validation of variable arguments list.");
1252 }
1253 else if (res) {
1254 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1255 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1256 --nch;
1257
1258 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1259 res = (is_odd(nch)
1260 && validate_fpdef(CHILD(tree, 0)));
1261
1262 if (res && (nch > 1)) {
1263 int pos = 1;
1264 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1265 res = validate_test(CHILD(tree, 2));
1266 pos += 2;
1267 }
1268 /* ... (',' fpdef ['=' test])* */
1269 for ( ; res && (pos < nch); pos += 2) {
1270 /* ',' fpdef */
1271 res = (validate_comma(CHILD(tree, pos))
1272 && validate_fpdef(CHILD(tree, pos + 1)));
1273 if (res
1274 && ((nch - pos) > 2)
1275 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1276 /* ['=' test] */
1277 res = validate_test(CHILD(tree, pos + 3));
1278 pos += 2;
1279 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001280 }
1281 }
1282 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001283 else
1284 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001285
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001286 return (res);
1287
1288} /* validate_varargslist() */
1289
1290
Guido van Rossum3d602e31996-07-21 02:33:56 +00001291/* VALIDATE(fpdef)
1292 *
1293 * fpdef:
1294 * NAME
1295 * | '(' fplist ')'
1296 */
Guido van Rossum47478871996-08-21 14:32:37 +00001297static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001298validate_fpdef(tree)
1299 node *tree;
1300{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001301 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001302 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001303
Guido van Rossum3d602e31996-07-21 02:33:56 +00001304 if (res) {
1305 if (nch == 1)
1306 res = validate_ntype(CHILD(tree, 0), NAME);
1307 else if (nch == 3)
1308 res = (validate_lparen(CHILD(tree, 0))
1309 && validate_fplist(CHILD(tree, 1))
1310 && validate_rparen(CHILD(tree, 2)));
1311 else
1312 validate_numnodes(tree, 1, "fpdef");
1313 }
1314 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001315
1316} /* validate_fpdef() */
1317
1318
Guido van Rossum47478871996-08-21 14:32:37 +00001319static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001320validate_fplist(tree)
1321 node *tree;
1322{
Guido van Rossum47478871996-08-21 14:32:37 +00001323 return (validate_repeating_list(tree, fplist,
1324 validate_fpdef, "fplist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001325
1326} /* validate_fplist() */
1327
1328
Guido van Rossum3d602e31996-07-21 02:33:56 +00001329/* simple_stmt | compound_stmt
1330 *
1331 */
Guido van Rossum47478871996-08-21 14:32:37 +00001332static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001333validate_stmt(tree)
1334 node *tree;
1335{
1336 int res = (validate_ntype(tree, stmt)
1337 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001338
Guido van Rossum3d602e31996-07-21 02:33:56 +00001339 if (res) {
1340 tree = CHILD(tree, 0);
1341
1342 if (TYPE(tree) == simple_stmt)
1343 res = validate_simple_stmt(tree);
1344 else
1345 res = validate_compound_stmt(tree);
1346 }
1347 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001348
1349} /* validate_stmt() */
1350
1351
Guido van Rossum3d602e31996-07-21 02:33:56 +00001352/* small_stmt (';' small_stmt)* [';'] NEWLINE
1353 *
1354 */
Guido van Rossum47478871996-08-21 14:32:37 +00001355static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001356validate_simple_stmt(tree)
1357 node *tree;
1358{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001359 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001360 int res = (validate_ntype(tree, simple_stmt)
1361 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001362 && validate_small_stmt(CHILD(tree, 0))
1363 && validate_newline(CHILD(tree, nch - 1)));
1364
Guido van Rossum3d602e31996-07-21 02:33:56 +00001365 if (nch < 2)
1366 res = validate_numnodes(tree, 2, "simple_stmt");
1367 --nch; /* forget the NEWLINE */
1368 if (res && is_even(nch))
1369 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001370 if (res && (nch > 2)) {
1371 int i;
1372
Guido van Rossum3d602e31996-07-21 02:33:56 +00001373 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001374 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001375 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001376 }
1377 return (res);
1378
1379} /* validate_simple_stmt() */
1380
1381
Guido van Rossum47478871996-08-21 14:32:37 +00001382static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001383validate_small_stmt(tree)
1384 node *tree;
1385{
1386 int nch = NCH(tree);
1387 int res = (validate_numnodes(tree, 1, "small_stmt")
1388 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1389 || (TYPE(CHILD(tree, 0)) == print_stmt)
1390 || (TYPE(CHILD(tree, 0)) == del_stmt)
1391 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1392 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1393 || (TYPE(CHILD(tree, 0)) == import_stmt)
1394 || (TYPE(CHILD(tree, 0)) == global_stmt)
Guido van Rossum925e5471997-04-02 05:32:13 +00001395 || (TYPE(CHILD(tree, 0)) == assert_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001396 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1397
1398 if (res)
1399 res = validate_node(CHILD(tree, 0));
1400 else if (nch == 1) {
1401 char buffer[60];
1402 sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1403 TYPE(CHILD(tree, 0)));
1404 err_string(buffer);
1405 }
1406 return (res);
1407
1408} /* validate_small_stmt */
1409
1410
1411/* compound_stmt:
1412 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1413 */
Guido van Rossum47478871996-08-21 14:32:37 +00001414static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001415validate_compound_stmt(tree)
1416 node *tree;
1417{
1418 int res = (validate_ntype(tree, compound_stmt)
1419 && validate_numnodes(tree, 1, "compound_stmt"));
1420
1421 if (!res)
1422 return (0);
1423
1424 tree = CHILD(tree, 0);
1425 res = ((TYPE(tree) == if_stmt)
1426 || (TYPE(tree) == while_stmt)
1427 || (TYPE(tree) == for_stmt)
1428 || (TYPE(tree) == try_stmt)
1429 || (TYPE(tree) == funcdef)
1430 || (TYPE(tree) == classdef));
1431 if (res)
1432 res = validate_node(tree);
1433 else {
1434 char buffer[60];
1435 sprintf(buffer, "Illegal compound statement type: %d.", TYPE(tree));
1436 err_string(buffer);
1437 }
1438 return (res);
1439
1440} /* validate_compound_stmt() */
1441
1442
Guido van Rossum47478871996-08-21 14:32:37 +00001443static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001444validate_expr_stmt(tree)
1445 node *tree;
1446{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001447 int j;
1448 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001449 int res = (validate_ntype(tree, expr_stmt)
1450 && is_odd(nch)
1451 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001452
Guido van Rossum3d602e31996-07-21 02:33:56 +00001453 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001454 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001455 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001456
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001457 return (res);
1458
1459} /* validate_expr_stmt() */
1460
1461
Guido van Rossum3d602e31996-07-21 02:33:56 +00001462/* print_stmt:
1463 *
1464 * 'print' (test ',')* [test]
1465 *
1466 */
Guido van Rossum47478871996-08-21 14:32:37 +00001467static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001468validate_print_stmt(tree)
1469 node *tree;
1470{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001471 int j;
1472 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001473 int res = (validate_ntype(tree, print_stmt)
1474 && (nch != 0)
1475 && validate_name(CHILD(tree, 0), "print"));
1476
1477 if (res && is_even(nch)) {
1478 res = validate_test(CHILD(tree, nch - 1));
1479 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001480 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001481 else if (!res && !PyErr_Occurred())
1482 validate_numnodes(tree, 1, "print_stmt");
1483 for (j = 1; res && (j < nch); j += 2)
1484 res = (validate_test(CHILD(tree, j))
1485 && validate_ntype(CHILD(tree, j + 1), COMMA));
1486
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001487 return (res);
1488
1489} /* validate_print_stmt() */
1490
1491
Guido van Rossum47478871996-08-21 14:32:37 +00001492static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001493validate_del_stmt(tree)
1494 node *tree;
1495{
1496 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001497 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001498 && validate_exprlist(CHILD(tree, 1)));
1499
1500} /* validate_del_stmt() */
1501
1502
Guido van Rossum47478871996-08-21 14:32:37 +00001503static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001504validate_return_stmt(tree)
1505 node *tree;
1506{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001507 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001508 int res = (validate_ntype(tree, return_stmt)
1509 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001510 && validate_name(CHILD(tree, 0), "return"));
1511
Guido van Rossum3d602e31996-07-21 02:33:56 +00001512 if (res && (nch == 2))
1513 res = validate_testlist(CHILD(tree, 1));
1514
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001515 return (res);
1516
1517} /* validate_return_stmt() */
1518
1519
Guido van Rossum47478871996-08-21 14:32:37 +00001520static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001521validate_raise_stmt(tree)
1522 node *tree;
1523{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001524 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001525 int res = (validate_ntype(tree, raise_stmt)
Fred Drakec542bc71998-04-10 04:43:28 +00001526 && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001527
Guido van Rossum3d602e31996-07-21 02:33:56 +00001528 if (res) {
Fred Drakec542bc71998-04-10 04:43:28 +00001529 res = validate_name(CHILD(tree, 0), "raise");
1530 if (res && (nch >= 2))
1531 res = validate_test(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001532 if (res && nch > 2) {
1533 res = (validate_comma(CHILD(tree, 2))
1534 && validate_test(CHILD(tree, 3)));
1535 if (res && (nch > 4))
1536 res = (validate_comma(CHILD(tree, 4))
1537 && validate_test(CHILD(tree, 5)));
1538 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001539 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001540 else
1541 validate_numnodes(tree, 2, "raise");
1542 if (res && (nch == 4))
1543 res = (validate_comma(CHILD(tree, 2))
1544 && validate_test(CHILD(tree, 3)));
1545
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001546 return (res);
1547
1548} /* validate_raise_stmt() */
1549
1550
Guido van Rossum3d602e31996-07-21 02:33:56 +00001551/* import_stmt:
1552 *
1553 * 'import' dotted_name (',' dotted_name)*
1554 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1555 */
Guido van Rossum47478871996-08-21 14:32:37 +00001556static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001557validate_import_stmt(tree)
1558 node *tree;
1559{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001560 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001561 int res = (validate_ntype(tree, import_stmt)
1562 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001563 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001564 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001565
1566 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001567 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001568
Guido van Rossum3d602e31996-07-21 02:33:56 +00001569 for (j = 2; res && (j < nch); j += 2)
1570 res = (validate_comma(CHILD(tree, j))
1571 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001572 }
1573 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001574 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001575 && validate_name(CHILD(tree, 2), "import"));
1576 if (nch == 4) {
1577 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001578 || (TYPE(CHILD(tree, 3)) == STAR));
1579 if (!res)
1580 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001581 }
1582 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001583 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001584 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001585 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001586 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001587 res = (validate_comma(CHILD(tree, j))
1588 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001589 }
1590 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001591 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001592 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001593
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001594 return (res);
1595
1596} /* validate_import_stmt() */
1597
1598
Guido van Rossum47478871996-08-21 14:32:37 +00001599static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001600validate_global_stmt(tree)
1601 node *tree;
1602{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001603 int j;
1604 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001605 int res = (validate_ntype(tree, global_stmt)
1606 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001607
Guido van Rossum3d602e31996-07-21 02:33:56 +00001608 if (res)
1609 res = (validate_name(CHILD(tree, 0), "global")
1610 && validate_ntype(CHILD(tree, 1), NAME));
1611 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001612 res = (validate_comma(CHILD(tree, j))
1613 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001614
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001615 return (res);
1616
1617} /* validate_global_stmt() */
1618
1619
Guido van Rossum3d602e31996-07-21 02:33:56 +00001620/* exec_stmt:
1621 *
1622 * 'exec' expr ['in' test [',' test]]
1623 */
Guido van Rossum47478871996-08-21 14:32:37 +00001624static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001625validate_exec_stmt(tree)
1626 node *tree;
1627{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001628 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001629 int res = (validate_ntype(tree, exec_stmt)
1630 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001631 && validate_name(CHILD(tree, 0), "exec")
1632 && validate_expr(CHILD(tree, 1)));
1633
Guido van Rossum3d602e31996-07-21 02:33:56 +00001634 if (!res && !PyErr_Occurred())
1635 err_string("Illegal exec statement.");
1636 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001637 res = (validate_name(CHILD(tree, 2), "in")
1638 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001639 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001640 res = (validate_comma(CHILD(tree, 4))
1641 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001642
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001643 return (res);
1644
1645} /* validate_exec_stmt() */
1646
1647
Guido van Rossum925e5471997-04-02 05:32:13 +00001648/* assert_stmt:
1649 *
1650 * 'assert' test [',' test]
1651 */
1652static int
1653validate_assert_stmt(tree)
1654 node *tree;
1655{
1656 int nch = NCH(tree);
1657 int res = (validate_ntype(tree, assert_stmt)
1658 && ((nch == 2) || (nch == 4))
1659 && (validate_name(CHILD(tree, 0), "__assert__") ||
1660 validate_name(CHILD(tree, 0), "assert"))
1661 && validate_test(CHILD(tree, 1)));
1662
1663 if (!res && !PyErr_Occurred())
1664 err_string("Illegal assert statement.");
1665 if (res && (nch > 2))
1666 res = (validate_comma(CHILD(tree, 2))
1667 && validate_test(CHILD(tree, 3)));
1668
1669 return (res);
1670
1671} /* validate_assert_stmt() */
1672
1673
Guido van Rossum47478871996-08-21 14:32:37 +00001674static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001675validate_while(tree)
1676 node *tree;
1677{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001678 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001679 int res = (validate_ntype(tree, while_stmt)
1680 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001681 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001682 && validate_test(CHILD(tree, 1))
1683 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001684 && validate_suite(CHILD(tree, 3)));
1685
Guido van Rossum3d602e31996-07-21 02:33:56 +00001686 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001687 res = (validate_name(CHILD(tree, 4), "else")
1688 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001689 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001690
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001691 return (res);
1692
1693} /* validate_while() */
1694
1695
Guido van Rossum47478871996-08-21 14:32:37 +00001696static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001697validate_for(tree)
1698 node *tree;
1699{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001700 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001701 int res = (validate_ntype(tree, for_stmt)
1702 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001703 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001704 && validate_exprlist(CHILD(tree, 1))
1705 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001706 && validate_testlist(CHILD(tree, 3))
1707 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001708 && validate_suite(CHILD(tree, 5)));
1709
Guido van Rossum3d602e31996-07-21 02:33:56 +00001710 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001711 res = (validate_name(CHILD(tree, 6), "else")
1712 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001713 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001714
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001715 return (res);
1716
1717} /* validate_for() */
1718
1719
Guido van Rossum3d602e31996-07-21 02:33:56 +00001720/* try_stmt:
1721 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1722 * | 'try' ':' suite 'finally' ':' suite
1723 *
1724 */
Guido van Rossum47478871996-08-21 14:32:37 +00001725static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001726validate_try(tree)
1727 node *tree;
1728{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001729 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001730 int pos = 3;
1731 int res = (validate_ntype(tree, try_stmt)
1732 && (nch >= 6) && ((nch % 3) == 0));
1733
1734 if (res)
1735 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001736 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001737 && validate_suite(CHILD(tree, 2))
1738 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001739 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001740 else {
1741 const char* name = "execpt";
1742 char buffer[60];
1743 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1744 name = STR(CHILD(tree, nch - 3));
1745 sprintf(buffer, "Illegal number of children for try/%s node.", name);
1746 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001747 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001748 /* Skip past except_clause sections: */
1749 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1750 res = (validate_except_clause(CHILD(tree, pos))
1751 && validate_colon(CHILD(tree, pos + 1))
1752 && validate_suite(CHILD(tree, pos + 2)));
1753 pos += 3;
1754 }
1755 if (res && (pos < nch)) {
1756 res = validate_ntype(CHILD(tree, pos), NAME);
1757 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1758 res = (validate_numnodes(tree, 6, "try/finally")
1759 && validate_colon(CHILD(tree, 4))
1760 && validate_suite(CHILD(tree, 5)));
Guido van Rossum730806d1998-04-10 22:27:42 +00001761 else if (res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001762 if (nch == (pos + 3)) {
1763 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1764 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1765 if (!res)
1766 err_string("Illegal trailing triple in try statement.");
1767 }
Guido van Rossum730806d1998-04-10 22:27:42 +00001768 else if (nch == (pos + 6)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001769 res = (validate_name(CHILD(tree, pos), "except")
1770 && validate_colon(CHILD(tree, pos + 1))
1771 && validate_suite(CHILD(tree, pos + 2))
1772 && validate_name(CHILD(tree, pos + 3), "else"));
Guido van Rossum730806d1998-04-10 22:27:42 +00001773 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001774 else
1775 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossum730806d1998-04-10 22:27:42 +00001776 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001777 }
1778 return (res);
1779
1780} /* validate_try() */
1781
1782
Guido van Rossum47478871996-08-21 14:32:37 +00001783static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001784validate_except_clause(tree)
1785 node *tree;
1786{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001787 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001788 int res = (validate_ntype(tree, except_clause)
1789 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001790 && validate_name(CHILD(tree, 0), "except"));
1791
Guido van Rossum3d602e31996-07-21 02:33:56 +00001792 if (res && (nch > 1))
1793 res = validate_test(CHILD(tree, 1));
1794 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001795 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001796 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001797
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001798 return (res);
1799
1800} /* validate_except_clause() */
1801
1802
Guido van Rossum47478871996-08-21 14:32:37 +00001803static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001804validate_test(tree)
1805 node *tree;
1806{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001807 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001808 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001809
Guido van Rossum3d602e31996-07-21 02:33:56 +00001810 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001811 res = ((nch == 1)
1812 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001813 else if (res) {
1814 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001815 res = validate_and_test(CHILD(tree, 0));
1816 for (pos = 1; res && (pos < nch); pos += 2)
1817 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001818 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001819 }
1820 return (res);
1821
1822} /* validate_test() */
1823
1824
Guido van Rossum47478871996-08-21 14:32:37 +00001825static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001826validate_and_test(tree)
1827 node *tree;
1828{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001829 int pos;
1830 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001831 int res = (validate_ntype(tree, and_test)
1832 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001833 && validate_not_test(CHILD(tree, 0)));
1834
Guido van Rossum3d602e31996-07-21 02:33:56 +00001835 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001836 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001837 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001838
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001839 return (res);
1840
1841} /* validate_and_test() */
1842
1843
Guido van Rossum47478871996-08-21 14:32:37 +00001844static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001845validate_not_test(tree)
1846 node *tree;
1847{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001848 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001849 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001850
Guido van Rossum3d602e31996-07-21 02:33:56 +00001851 if (res) {
1852 if (nch == 2)
1853 res = (validate_name(CHILD(tree, 0), "not")
1854 && validate_not_test(CHILD(tree, 1)));
1855 else if (nch == 1)
1856 res = validate_comparison(CHILD(tree, 0));
1857 }
1858 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001859
1860} /* validate_not_test() */
1861
1862
Guido van Rossum47478871996-08-21 14:32:37 +00001863static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001864validate_comparison(tree)
1865 node *tree;
1866{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001867 int pos;
1868 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001869 int res = (validate_ntype(tree, comparison)
1870 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001871 && validate_expr(CHILD(tree, 0)));
1872
Guido van Rossum3d602e31996-07-21 02:33:56 +00001873 for (pos = 1; res && (pos < nch); pos += 2)
1874 res = (validate_comp_op(CHILD(tree, pos))
1875 && validate_expr(CHILD(tree, pos + 1)));
1876
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001877 return (res);
1878
1879} /* validate_comparison() */
1880
1881
Guido van Rossum47478871996-08-21 14:32:37 +00001882static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001883validate_comp_op(tree)
1884 node *tree;
1885{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001886 int res = 0;
1887 int nch = NCH(tree);
1888
Guido van Rossum3d602e31996-07-21 02:33:56 +00001889 if (!validate_ntype(tree, comp_op))
1890 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001891 if (nch == 1) {
1892 /*
1893 * Only child will be a terminal with a well-defined symbolic name
1894 * or a NAME with a string of either 'is' or 'in'
1895 */
1896 tree = CHILD(tree, 0);
1897 switch (TYPE(tree)) {
1898 case LESS:
1899 case GREATER:
1900 case EQEQUAL:
1901 case EQUAL:
1902 case LESSEQUAL:
1903 case GREATEREQUAL:
1904 case NOTEQUAL:
1905 res = 1;
1906 break;
1907 case NAME:
1908 res = ((strcmp(STR(tree), "in") == 0)
1909 || (strcmp(STR(tree), "is") == 0));
1910 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001911 char buff[128];
1912 sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1913 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001914 }
1915 break;
1916 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001917 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001918 break;
1919 }
1920 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001921 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001922 res = (validate_ntype(CHILD(tree, 0), NAME)
1923 && validate_ntype(CHILD(tree, 1), NAME)
1924 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1925 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1926 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1927 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001928 if (!res && !PyErr_Occurred())
1929 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001930 }
1931 return (res);
1932
1933} /* validate_comp_op() */
1934
1935
Guido van Rossum47478871996-08-21 14:32:37 +00001936static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001937validate_expr(tree)
1938 node *tree;
1939{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001940 int j;
1941 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001942 int res = (validate_ntype(tree, expr)
1943 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001944 && validate_xor_expr(CHILD(tree, 0)));
1945
Guido van Rossum3d602e31996-07-21 02:33:56 +00001946 for (j = 2; res && (j < nch); j += 2)
1947 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001948 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001949
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001950 return (res);
1951
1952} /* validate_expr() */
1953
1954
Guido van Rossum47478871996-08-21 14:32:37 +00001955static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001956validate_xor_expr(tree)
1957 node *tree;
1958{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001959 int j;
1960 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001961 int res = (validate_ntype(tree, xor_expr)
1962 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001963 && validate_and_expr(CHILD(tree, 0)));
1964
Guido van Rossum3d602e31996-07-21 02:33:56 +00001965 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001966 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001967 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001968
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001969 return (res);
1970
1971} /* validate_xor_expr() */
1972
1973
Guido van Rossum47478871996-08-21 14:32:37 +00001974static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001975validate_and_expr(tree)
1976 node *tree;
1977{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001978 int pos;
1979 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001980 int res = (validate_ntype(tree, and_expr)
1981 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001982 && validate_shift_expr(CHILD(tree, 0)));
1983
Guido van Rossum3d602e31996-07-21 02:33:56 +00001984 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001985 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001986 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001987
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001988 return (res);
1989
1990} /* validate_and_expr() */
1991
1992
1993static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001994validate_chain_two_ops(tree, termvalid, op1, op2)
1995 node *tree;
1996 int (*termvalid)();
1997 int op1;
1998 int op2;
1999 {
2000 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002001 int nch = NCH(tree);
2002 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002003 && (*termvalid)(CHILD(tree, 0)));
2004
Guido van Rossum3d602e31996-07-21 02:33:56 +00002005 for ( ; res && (pos < nch); pos += 2) {
2006 if (TYPE(CHILD(tree, pos)) != op1)
2007 res = validate_ntype(CHILD(tree, pos), op2);
2008 if (res)
2009 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002010 }
2011 return (res);
2012
2013} /* validate_chain_two_ops() */
2014
2015
Guido van Rossum47478871996-08-21 14:32:37 +00002016static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002017validate_shift_expr(tree)
2018 node *tree;
2019{
2020 return (validate_ntype(tree, shift_expr)
2021 && validate_chain_two_ops(tree, validate_arith_expr,
2022 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002023
2024} /* validate_shift_expr() */
2025
2026
Guido van Rossum47478871996-08-21 14:32:37 +00002027static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002028validate_arith_expr(tree)
2029 node *tree;
2030{
2031 return (validate_ntype(tree, arith_expr)
2032 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002033
2034} /* validate_arith_expr() */
2035
2036
Guido van Rossum47478871996-08-21 14:32:37 +00002037static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002038validate_term(tree)
2039 node *tree;
2040{
2041 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002042 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002043 int res = (validate_ntype(tree, term)
2044 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002045 && validate_factor(CHILD(tree, 0)));
2046
Guido van Rossum3d602e31996-07-21 02:33:56 +00002047 for ( ; res && (pos < nch); pos += 2)
2048 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002049 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002050 || (TYPE(CHILD(tree, pos)) == PERCENT))
2051 && validate_factor(CHILD(tree, pos + 1)));
2052
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002053 return (res);
2054
2055} /* validate_term() */
2056
2057
Guido van Rossum3d602e31996-07-21 02:33:56 +00002058/* factor:
2059 *
2060 * factor: ('+'|'-'|'~') factor | power
2061 */
Guido van Rossum47478871996-08-21 14:32:37 +00002062static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002063validate_factor(tree)
2064 node *tree;
2065{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002066 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002067 int res = (validate_ntype(tree, factor)
2068 && (((nch == 2)
2069 && ((TYPE(CHILD(tree, 0)) == PLUS)
2070 || (TYPE(CHILD(tree, 0)) == MINUS)
2071 || (TYPE(CHILD(tree, 0)) == TILDE))
2072 && validate_factor(CHILD(tree, 1)))
2073 || ((nch == 1)
2074 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002075 return (res);
2076
2077} /* validate_factor() */
2078
2079
Guido van Rossum3d602e31996-07-21 02:33:56 +00002080/* power:
2081 *
2082 * power: atom trailer* ('**' factor)*
2083 */
Guido van Rossum47478871996-08-21 14:32:37 +00002084static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002085validate_power(tree)
2086 node *tree;
2087{
2088 int pos = 1;
2089 int nch = NCH(tree);
2090 int res = (validate_ntype(tree, power) && (nch >= 1)
2091 && validate_atom(CHILD(tree, 0)));
2092
2093 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2094 res = validate_trailer(CHILD(tree, pos++));
2095 if (res && (pos < nch)) {
2096 if (!is_even(nch - pos)) {
2097 err_string("Illegal number of nodes for 'power'.");
2098 return (0);
2099 }
2100 for ( ; res && (pos < (nch - 1)); pos += 2)
2101 res = (validate_doublestar(CHILD(tree, pos))
2102 && validate_factor(CHILD(tree, pos + 1)));
2103 }
2104 return (res);
2105
2106} /* validate_power() */
2107
2108
Guido van Rossum47478871996-08-21 14:32:37 +00002109static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002110validate_atom(tree)
2111 node *tree;
2112{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002113 int pos;
2114 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002115 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002116
2117 if (res) {
2118 switch (TYPE(CHILD(tree, 0))) {
2119 case LPAR:
2120 res = ((nch <= 3)
2121 && (validate_rparen(CHILD(tree, nch - 1))));
2122
Guido van Rossum3d602e31996-07-21 02:33:56 +00002123 if (res && (nch == 3))
2124 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002125 break;
2126 case LSQB:
2127 res = ((nch <= 3)
2128 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2129
Guido van Rossum3d602e31996-07-21 02:33:56 +00002130 if (res && (nch == 3))
2131 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002132 break;
2133 case LBRACE:
2134 res = ((nch <= 3)
2135 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2136
Guido van Rossum3d602e31996-07-21 02:33:56 +00002137 if (res && (nch == 3))
2138 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002139 break;
2140 case BACKQUOTE:
2141 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002142 && validate_testlist(CHILD(tree, 1))
2143 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2144 break;
2145 case NAME:
2146 case NUMBER:
2147 res = (nch == 1);
2148 break;
2149 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002150 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002151 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002152 break;
2153 default:
2154 res = 0;
2155 break;
2156 }
2157 }
2158 return (res);
2159
2160} /* validate_atom() */
2161
2162
Guido van Rossum3d602e31996-07-21 02:33:56 +00002163/* funcdef:
2164 * 'def' NAME parameters ':' suite
2165 *
2166 */
Guido van Rossum47478871996-08-21 14:32:37 +00002167static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002168validate_funcdef(tree)
2169 node *tree;
2170{
2171 return (validate_ntype(tree, funcdef)
2172 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002173 && validate_name(CHILD(tree, 0), "def")
2174 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002175 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002176 && validate_parameters(CHILD(tree, 2))
2177 && validate_suite(CHILD(tree, 4)));
2178
2179} /* validate_funcdef() */
2180
2181
Guido van Rossum47478871996-08-21 14:32:37 +00002182static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002183validate_lambdef(tree)
2184 node *tree;
2185{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002186 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002187 int res = (validate_ntype(tree, lambdef)
2188 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002189 && validate_name(CHILD(tree, 0), "lambda")
2190 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002191 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002192
Guido van Rossum3d602e31996-07-21 02:33:56 +00002193 if (res && (nch == 4))
2194 res = validate_varargslist(CHILD(tree, 1));
2195 else if (!res && !PyErr_Occurred())
2196 validate_numnodes(tree, 3, "lambdef");
2197
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002198 return (res);
2199
2200} /* validate_lambdef() */
2201
2202
Guido van Rossum3d602e31996-07-21 02:33:56 +00002203/* arglist:
2204 *
2205 * argument (',' argument)* [',']
2206 */
Guido van Rossum47478871996-08-21 14:32:37 +00002207static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002208validate_arglist(tree)
2209 node *tree;
2210{
Guido van Rossum47478871996-08-21 14:32:37 +00002211 return (validate_repeating_list(tree, arglist,
2212 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002213
2214} /* validate_arglist() */
2215
2216
2217
2218/* argument:
2219 *
2220 * [test '='] test
2221 */
Guido van Rossum47478871996-08-21 14:32:37 +00002222static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002223validate_argument(tree)
2224 node *tree;
2225{
2226 int nch = NCH(tree);
2227 int res = (validate_ntype(tree, argument)
2228 && ((nch == 1) || (nch == 3))
2229 && validate_test(CHILD(tree, 0)));
2230
2231 if (res && (nch == 3))
2232 res = (validate_equal(CHILD(tree, 1))
2233 && validate_test(CHILD(tree, 2)));
2234
2235 return (res);
2236
2237} /* validate_argument() */
2238
2239
2240
2241/* trailer:
2242 *
Guido van Rossum47478871996-08-21 14:32:37 +00002243 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002244 */
Guido van Rossum47478871996-08-21 14:32:37 +00002245static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002246validate_trailer(tree)
2247 node *tree;
2248{
2249 int nch = NCH(tree);
2250 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002251
2252 if (res) {
2253 switch (TYPE(CHILD(tree, 0))) {
2254 case LPAR:
2255 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002256 if (res && (nch == 3))
2257 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002258 break;
2259 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002260 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002261 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002262 && validate_ntype(CHILD(tree, 2), RSQB));
2263 break;
2264 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002265 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002266 && validate_ntype(CHILD(tree, 1), NAME));
2267 break;
2268 default:
2269 res = 0;
2270 break;
2271 }
2272 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002273 else
2274 validate_numnodes(tree, 2, "trailer");
2275
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002276 return (res);
2277
2278} /* validate_trailer() */
2279
2280
Guido van Rossum47478871996-08-21 14:32:37 +00002281/* subscriptlist:
2282 *
2283 * subscript (',' subscript)* [',']
2284 */
2285static int
2286validate_subscriptlist(tree)
2287 node *tree;
2288{
2289 return (validate_repeating_list(tree, subscriptlist,
2290 validate_subscript, "subscriptlist"));
2291
2292} /* validate_subscriptlist() */
2293
2294
Guido van Rossum3d602e31996-07-21 02:33:56 +00002295/* subscript:
2296 *
Guido van Rossum47478871996-08-21 14:32:37 +00002297 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002298 */
Guido van Rossum47478871996-08-21 14:32:37 +00002299static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002300validate_subscript(tree)
2301 node *tree;
2302{
Guido van Rossum47478871996-08-21 14:32:37 +00002303 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002304 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002305 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002306
Guido van Rossum47478871996-08-21 14:32:37 +00002307 if (!res) {
2308 if (!PyErr_Occurred())
2309 err_string("invalid number of arguments for subscript node");
2310 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002311 }
Guido van Rossum47478871996-08-21 14:32:37 +00002312 if (TYPE(CHILD(tree, 0)) == DOT)
2313 /* take care of ('.' '.' '.') possibility */
2314 return (validate_numnodes(tree, 3, "subscript")
2315 && validate_dot(CHILD(tree, 0))
2316 && validate_dot(CHILD(tree, 1))
2317 && validate_dot(CHILD(tree, 2)));
2318 if (nch == 1) {
2319 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002320 res = validate_test(CHILD(tree, 0));
2321 else
Guido van Rossum47478871996-08-21 14:32:37 +00002322 res = validate_colon(CHILD(tree, 0));
2323 return (res);
2324 }
2325 /* Must be [test] ':' [test] [sliceop],
2326 * but at least one of the optional components will
2327 * be present, but we don't know which yet.
2328 */
2329 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2330 res = validate_test(CHILD(tree, 0));
2331 offset = 1;
2332 }
2333 if (res)
2334 res = validate_colon(CHILD(tree, offset));
2335 if (res) {
2336 int rem = nch - ++offset;
2337 if (rem) {
2338 if (TYPE(CHILD(tree, offset)) == test) {
2339 res = validate_test(CHILD(tree, offset));
2340 ++offset;
2341 --rem;
2342 }
2343 if (res && rem)
2344 res = validate_sliceop(CHILD(tree, offset));
2345 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002346 }
2347 return (res);
2348
2349} /* validate_subscript() */
2350
2351
Guido van Rossum47478871996-08-21 14:32:37 +00002352static int
2353validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002354 node *tree;
2355{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002356 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002357 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2358 && validate_ntype(tree, sliceop);
2359 if (!res && !PyErr_Occurred()) {
2360 validate_numnodes(tree, 1, "sliceop");
2361 res = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002362 }
Guido van Rossum47478871996-08-21 14:32:37 +00002363 if (res)
2364 res = validate_colon(CHILD(tree, 0));
2365 if (res && (nch == 2))
2366 res = validate_test(CHILD(tree, 1));
2367
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002368 return (res);
2369
Guido van Rossum47478871996-08-21 14:32:37 +00002370} /* validate_sliceop() */
2371
2372
2373static int
2374validate_exprlist(tree)
2375 node *tree;
2376{
2377 return (validate_repeating_list(tree, exprlist,
2378 validate_expr, "exprlist"));
2379
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002380} /* validate_exprlist() */
2381
2382
Guido van Rossum47478871996-08-21 14:32:37 +00002383static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002384validate_dictmaker(tree)
2385 node *tree;
2386{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002387 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002388 int res = (validate_ntype(tree, dictmaker)
2389 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002390 && validate_test(CHILD(tree, 0))
2391 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002392 && validate_test(CHILD(tree, 2)));
2393
Guido van Rossum3d602e31996-07-21 02:33:56 +00002394 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002395 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002396 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002397 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002398
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002399 if (res && (nch > 3)) {
2400 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002401 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002402 while (res && (pos < nch)) {
2403 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002404 && validate_test(CHILD(tree, pos + 1))
2405 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002406 && validate_test(CHILD(tree, pos + 3)));
2407 pos += 4;
2408 }
2409 }
2410 return (res);
2411
2412} /* validate_dictmaker() */
2413
2414
Guido van Rossum47478871996-08-21 14:32:37 +00002415static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002416validate_eval_input(tree)
2417 node *tree;
2418{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002419 int pos;
2420 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002421 int res = (validate_ntype(tree, eval_input)
2422 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002423 && validate_testlist(CHILD(tree, 0))
2424 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2425
Guido van Rossum3d602e31996-07-21 02:33:56 +00002426 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002427 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002428
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002429 return (res);
2430
2431} /* validate_eval_input() */
2432
2433
Guido van Rossum47478871996-08-21 14:32:37 +00002434static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002435validate_node(tree)
2436 node *tree;
2437{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002438 int nch = 0; /* num. children on current node */
2439 int res = 1; /* result value */
2440 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002441
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002442 while (res & (tree != 0)) {
2443 nch = NCH(tree);
2444 next = 0;
2445 switch (TYPE(tree)) {
2446 /*
2447 * Definition nodes.
2448 */
2449 case funcdef:
2450 res = validate_funcdef(tree);
2451 break;
2452 case classdef:
2453 res = validate_class(tree);
2454 break;
2455 /*
2456 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002457 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002458 */
2459 case stmt:
2460 res = validate_stmt(tree);
2461 break;
2462 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002463 /*
2464 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum925e5471997-04-02 05:32:13 +00002465 * | import_stmt | global_stmt | exec_stmt | assert_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002466 */
2467 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002468 break;
2469 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002470 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002471 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2472 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2473 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002474 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2475 if (res)
2476 next = CHILD(tree, 0);
2477 else if (nch == 1)
2478 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002479 break;
2480 /*
2481 * Compound statements.
2482 */
2483 case simple_stmt:
2484 res = validate_simple_stmt(tree);
2485 break;
2486 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002487 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002488 break;
2489 /*
2490 * Fundemental statements.
2491 */
2492 case expr_stmt:
2493 res = validate_expr_stmt(tree);
2494 break;
2495 case print_stmt:
2496 res = validate_print_stmt(tree);
2497 break;
2498 case del_stmt:
2499 res = validate_del_stmt(tree);
2500 break;
2501 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002502 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002503 && validate_name(CHILD(tree, 0), "pass"));
2504 break;
2505 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002506 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002507 && validate_name(CHILD(tree, 0), "break"));
2508 break;
2509 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002510 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002511 && validate_name(CHILD(tree, 0), "continue"));
2512 break;
2513 case return_stmt:
2514 res = validate_return_stmt(tree);
2515 break;
2516 case raise_stmt:
2517 res = validate_raise_stmt(tree);
2518 break;
2519 case import_stmt:
2520 res = validate_import_stmt(tree);
2521 break;
2522 case global_stmt:
2523 res = validate_global_stmt(tree);
2524 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002525 case exec_stmt:
2526 res = validate_exec_stmt(tree);
2527 break;
Guido van Rossum925e5471997-04-02 05:32:13 +00002528 case assert_stmt:
2529 res = validate_assert_stmt(tree);
2530 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002531 case if_stmt:
2532 res = validate_if(tree);
2533 break;
2534 case while_stmt:
2535 res = validate_while(tree);
2536 break;
2537 case for_stmt:
2538 res = validate_for(tree);
2539 break;
2540 case try_stmt:
2541 res = validate_try(tree);
2542 break;
2543 case suite:
2544 res = validate_suite(tree);
2545 break;
2546 /*
2547 * Expression nodes.
2548 */
2549 case testlist:
2550 res = validate_testlist(tree);
2551 break;
2552 case test:
2553 res = validate_test(tree);
2554 break;
2555 case and_test:
2556 res = validate_and_test(tree);
2557 break;
2558 case not_test:
2559 res = validate_not_test(tree);
2560 break;
2561 case comparison:
2562 res = validate_comparison(tree);
2563 break;
2564 case exprlist:
2565 res = validate_exprlist(tree);
2566 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002567 case comp_op:
2568 res = validate_comp_op(tree);
2569 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002570 case expr:
2571 res = validate_expr(tree);
2572 break;
2573 case xor_expr:
2574 res = validate_xor_expr(tree);
2575 break;
2576 case and_expr:
2577 res = validate_and_expr(tree);
2578 break;
2579 case shift_expr:
2580 res = validate_shift_expr(tree);
2581 break;
2582 case arith_expr:
2583 res = validate_arith_expr(tree);
2584 break;
2585 case term:
2586 res = validate_term(tree);
2587 break;
2588 case factor:
2589 res = validate_factor(tree);
2590 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002591 case power:
2592 res = validate_power(tree);
2593 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002594 case atom:
2595 res = validate_atom(tree);
2596 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002597
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002598 default:
2599 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002600 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002601 res = 0;
2602 break;
2603 }
2604 tree = next;
2605 }
2606 return (res);
2607
2608} /* validate_node() */
2609
2610
Guido van Rossum47478871996-08-21 14:32:37 +00002611static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002612validate_expr_tree(tree)
2613 node *tree;
2614{
2615 int res = validate_eval_input(tree);
2616
2617 if (!res && !PyErr_Occurred())
2618 err_string("Could not validate expression tuple.");
2619
2620 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002621
2622} /* validate_expr_tree() */
2623
2624
Guido van Rossum3d602e31996-07-21 02:33:56 +00002625/* file_input:
2626 * (NEWLINE | stmt)* ENDMARKER
2627 */
Guido van Rossum47478871996-08-21 14:32:37 +00002628static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002629validate_file_input(tree)
2630 node *tree;
2631{
2632 int j = 0;
2633 int nch = NCH(tree) - 1;
2634 int res = ((nch >= 0)
2635 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002636
Guido van Rossum3d602e31996-07-21 02:33:56 +00002637 for ( ; res && (j < nch); ++j) {
2638 if (TYPE(CHILD(tree, j)) == stmt)
2639 res = validate_stmt(CHILD(tree, j));
2640 else
2641 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002642 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002643 /* This stays in to prevent any internal failues from getting to the
2644 * user. Hopefully, this won't be needed. If a user reports getting
2645 * this, we have some debugging to do.
2646 */
2647 if (!res && !PyErr_Occurred())
2648 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2649
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002650 return (res);
2651
Guido van Rossum2a288461996-08-21 21:55:43 +00002652} /* validate_file_input() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002653
2654
Fred Drake43f8f9b1998-04-13 16:25:46 +00002655static PyObject*
2656pickle_constructor = NULL;
2657
2658
2659static PyObject*
2660parser__pickler(self, args)
2661 PyObject *self;
2662 PyObject *args;
2663{
2664 PyObject *result = NULL;
2665 PyObject *ast = NULL;
2666
2667 if (PyArg_ParseTuple(args, "O!:_pickler", &PyAST_Type, &ast)) {
2668 PyObject *newargs;
2669 PyObject *tuple;
2670
2671 if ((newargs = Py_BuildValue("Oi", ast, 1)) == NULL)
2672 goto finally;
2673 tuple = parser_ast2tuple(NULL, newargs);
2674 if (tuple != NULL) {
2675 result = Py_BuildValue("O(O)", pickle_constructor, tuple);
2676 Py_DECREF(tuple);
2677 }
2678 Py_XDECREF(newargs);
2679 }
2680 finally:
2681 return (result);
2682
2683} /* parser__pickler() */
2684
2685
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002686/* Functions exported by this module. Most of this should probably
2687 * be converted into an AST object with methods, but that is better
2688 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002689 * We'd really have to write a wrapper around it all anyway to allow
2690 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002691 */
2692static PyMethodDef parser_functions[] = {
Fred Drake301b5be1998-04-21 22:31:45 +00002693 {"ast2tuple", (PyCFunction)parser_ast2tuple, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002694 "Creates a tuple-tree representation of an AST."},
Fred Drake301b5be1998-04-21 22:31:45 +00002695 {"ast2list", (PyCFunction)parser_ast2list, METH_VARARGS,
Guido van Rossum47478871996-08-21 14:32:37 +00002696 "Creates a list-tree representation of an AST."},
Fred Drake301b5be1998-04-21 22:31:45 +00002697 {"compileast", (PyCFunction)parser_compileast, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002698 "Compiles an AST object into a code object."},
Fred Drake301b5be1998-04-21 22:31:45 +00002699 {"expr", (PyCFunction)parser_expr, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002700 "Creates an AST object from an expression."},
Fred Drake301b5be1998-04-21 22:31:45 +00002701 {"isexpr", (PyCFunction)parser_isexpr, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002702 "Determines if an AST object was created from an expression."},
Fred Drake301b5be1998-04-21 22:31:45 +00002703 {"issuite", (PyCFunction)parser_issuite, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002704 "Determines if an AST object was created from a suite."},
Fred Drake301b5be1998-04-21 22:31:45 +00002705 {"suite", (PyCFunction)parser_suite, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002706 "Creates an AST object from a suite."},
Fred Drake301b5be1998-04-21 22:31:45 +00002707 {"sequence2ast", (PyCFunction)parser_tuple2ast, METH_VARARGS,
Guido van Rossum47478871996-08-21 14:32:37 +00002708 "Creates an AST object from a tree representation."},
Fred Drake301b5be1998-04-21 22:31:45 +00002709 {"tuple2ast", (PyCFunction)parser_tuple2ast, METH_VARARGS,
Guido van Rossum47478871996-08-21 14:32:37 +00002710 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002711
Fred Drake43f8f9b1998-04-13 16:25:46 +00002712 /* private stuff: support pickle module */
Fred Drake301b5be1998-04-21 22:31:45 +00002713 {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS,
Fred Drake43f8f9b1998-04-13 16:25:46 +00002714 "Returns the pickle magic to allow ast objects to be pickled."},
2715
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002716 {0, 0, 0}
2717 };
2718
2719
Guido van Rossum52f2c051993-11-10 12:53:24 +00002720void
Guido van Rossum3d602e31996-07-21 02:33:56 +00002721initparser()
2722 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002723 PyObject* module;
2724 PyObject* dict;
2725
2726 PyAST_Type.ob_type = &PyType_Type;
2727 module = Py_InitModule("parser", parser_functions);
2728 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002729
Fred Drake0225a381997-10-07 19:32:00 +00002730 parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002731
2732 if ((parser_error == 0)
2733 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2734 /*
2735 * This is serious.
2736 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002737 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002738 }
2739 /*
2740 * Nice to have, but don't cry if we fail.
2741 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002742 Py_INCREF(&PyAST_Type);
2743 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2744
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002745 PyDict_SetItemString(dict, "__copyright__",
2746 PyString_FromString(parser_copyright_string));
2747 PyDict_SetItemString(dict, "__doc__",
2748 PyString_FromString(parser_doc_string));
2749 PyDict_SetItemString(dict, "__version__",
2750 PyString_FromString(parser_version_string));
2751
Fred Drake503d8d61998-04-13 18:45:18 +00002752 parser_method_list = PyList_New(0);
2753 if (parser_method_list != NULL) {
2754 PyMethodDef *mdef = parser_methods;
2755
2756 while (mdef->ml_name != NULL) {
2757 PyObject *temp = PyString_FromString(mdef->ml_name);
2758 if (temp != NULL) {
2759 PyList_Append(parser_method_list, temp);
2760 Py_DECREF(temp);
2761 }
2762 ++mdef;
2763 }
2764 }
2765
Fred Drake43f8f9b1998-04-13 16:25:46 +00002766 /* register to support pickling */
2767 module = PyImport_ImportModule("copy_reg");
2768 if (module != NULL) {
Fred Drake301b5be1998-04-21 22:31:45 +00002769 PyObject *func, *pickler;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002770
2771 func = PyObject_GetAttrString(module, "pickle");
2772 pickle_constructor = PyDict_GetItemString(dict, "sequence2ast");
2773 pickler = PyDict_GetItemString(dict, "_pickler");
2774 Py_XINCREF(pickle_constructor);
2775 if ((func != NULL) && (pickle_constructor != NULL)
2776 && (pickler != NULL)) {
2777 PyObject *res;
2778
2779 res = PyObject_CallFunction(
2780 func, "OOO", &PyAST_Type, pickler, pickle_constructor);
2781 Py_XDECREF(res);
2782 }
2783 Py_XDECREF(func);
2784 Py_DECREF(module);
2785 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002786} /* initparser() */