blob: d1f11548dc9a98b9a8d274c9ffd924b7218f6b6c [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
186
187/* static */
188PyTypeObject PyAST_Type = {
189
Guido van Rossumf2b2dac1997-01-23 23:29:44 +0000190 PyObject_HEAD_INIT(NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000191 0,
192 "ast", /* tp_name */
193 sizeof(PyAST_Object), /* tp_basicsize */
194 0, /* tp_itemsize */
195 (destructor)parser_free, /* tp_dealloc */
196 0, /* tp_print */
197 0, /* tp_getattr */
198 0, /* tp_setattr */
199 (cmpfunc)parser_compare, /* tp_compare */
200 0, /* tp_repr */
201 0, /* tp_as_number */
202 0, /* tp_as_sequence */
203 0, /* tp_as_mapping */
204 0, /* tp_hash */
205 0, /* tp_call */
Fred Drake69b9ae41997-05-23 04:04:17 +0000206 0, /* tp_str */
207 0, /* tp_getattro */
208 0, /* tp_setattro */
209
210 /* Functions to access object as input/output buffer */
211 0, /* tp_as_buffer */
212
213 /* Space for future expansion */
214 0, /* tp_xxx4 */
215
216 /* __doc__ */
217 "Intermediate representation of a Python parse tree."
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000218
219}; /* PyAST_Type */
220
221
222static int
223parser_compare_nodes(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000224 node *left;
225 node *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000226{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000227 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000228
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000229 if (TYPE(left) < TYPE(right))
230 return (-1);
231
232 if (TYPE(right) < TYPE(left))
233 return (1);
234
235 if (ISTERMINAL(TYPE(left)))
236 return (strcmp(STR(left), STR(right)));
237
238 if (NCH(left) < NCH(right))
239 return (-1);
240
241 if (NCH(right) < NCH(left))
242 return (1);
243
244 for (j = 0; j < NCH(left); ++j) {
245 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
246
247 if (v)
248 return (v);
249 }
250 return (0);
251
252} /* parser_compare_nodes() */
253
254
255/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
256 *
257 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
258 * This really just wraps a call to parser_compare_nodes() with some easy
259 * checks and protection code.
260 *
261 */
262static int
263parser_compare(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000264 PyAST_Object *left;
265 PyAST_Object *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000266{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000267 if (left == right)
268 return (0);
269
270 if ((left == 0) || (right == 0))
271 return (-1);
272
273 return (parser_compare_nodes(left->ast_node, right->ast_node));
274
275} /* parser_compare() */
276
277
278/* parser_newastobject(node* ast)
279 *
280 * Allocates a new Python object representing an AST. This is simply the
281 * 'wrapper' object that holds a node* and allows it to be passed around in
282 * Python code.
283 *
284 */
285static PyObject*
286parser_newastobject(ast, type)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000287 node *ast;
288 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000289{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000290 PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
291
292 if (o != 0) {
293 o->ast_node = ast;
294 o->ast_type = type;
295 }
296 return ((PyObject*)o);
297
298} /* parser_newastobject() */
299
300
301/* void parser_free(PyAST_Object* ast)
302 *
303 * This is called by a del statement that reduces the reference count to 0.
304 *
305 */
306static void
307parser_free(ast)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000308 PyAST_Object *ast;
Guido van Rossum47478871996-08-21 14:32:37 +0000309{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000310 PyNode_Free(ast->ast_node);
311 PyMem_DEL(ast);
312
313} /* parser_free() */
314
315
316/* parser_ast2tuple(PyObject* self, PyObject* args)
317 *
318 * This provides conversion from a node* to a tuple object that can be
319 * returned to the Python-level caller. The AST object is not modified.
320 *
321 */
322static PyObject*
323parser_ast2tuple(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000324 PyObject *self;
325 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000326{
327 PyObject *ast;
328 PyObject *line_option = 0;
329 PyObject *res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000330
Guido van Rossum47478871996-08-21 14:32:37 +0000331 if (PyArg_ParseTuple(args, "O!|O:ast2tuple", &PyAST_Type, &ast,
332 &line_option)) {
333 int lineno = 0;
334 if (line_option != 0) {
335 lineno = PyObject_IsTrue(line_option);
336 lineno = lineno ? 1 : 0;
337 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000338 /*
339 * Convert AST into a tuple representation. Use Guido's function,
340 * since it's known to work already.
341 */
Guido van Rossum47478871996-08-21 14:32:37 +0000342 res = node2tuple(((PyAST_Object*)ast)->ast_node,
343 PyTuple_New, PyTuple_SetItem, lineno);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000344 }
345 return (res);
346
347} /* parser_ast2tuple() */
348
349
Guido van Rossum47478871996-08-21 14:32:37 +0000350/* parser_ast2tuple(PyObject* self, PyObject* args)
351 *
352 * This provides conversion from a node* to a tuple object that can be
353 * returned to the Python-level caller. The AST object is not modified.
354 *
355 */
356static PyObject*
357parser_ast2list(self, args)
358 PyObject *self;
359 PyObject *args;
360{
361 PyObject *ast;
362 PyObject *line_option = 0;
363 PyObject *res = 0;
364
365 if (PyArg_ParseTuple(args, "O!|O:ast2list", &PyAST_Type, &ast,
366 &line_option)) {
367 int lineno = 0;
368 if (line_option != 0) {
369 lineno = PyObject_IsTrue(line_option);
370 lineno = lineno ? 1 : 0;
371 }
372 /*
373 * Convert AST into a tuple representation. Use Guido's function,
374 * since it's known to work already.
375 */
376 res = node2tuple(((PyAST_Object*)ast)->ast_node,
377 PyList_New, PyList_SetItem, lineno);
378 }
379 return (res);
380
381} /* parser_ast2list() */
382
383
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000384/* parser_compileast(PyObject* self, PyObject* args)
385 *
386 * This function creates code objects from the parse tree represented by
387 * the passed-in data object. An optional file name is passed in as well.
388 *
389 */
390static PyObject*
391parser_compileast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000392 PyObject *self;
393 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000394{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000395 PyAST_Object* ast;
396 PyObject* res = 0;
397 char* str = "<ast>";
398
399 if (PyArg_ParseTuple(args, "O!|s", &PyAST_Type, &ast, &str))
Guido van Rossum3d602e31996-07-21 02:33:56 +0000400 res = (PyObject*) PyNode_Compile(ast->ast_node, str);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000401
402 return (res);
403
404} /* parser_compileast() */
405
406
407/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
408 * PyObject* parser_issuite(PyObject* self, PyObject* args)
409 *
410 * Checks the passed-in AST object to determine if it is an expression or
411 * a statement suite, respectively. The return is a Python truth value.
412 *
413 */
414static PyObject*
415parser_isexpr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000416 PyObject *self;
417 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000418{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000419 PyAST_Object* ast;
420 PyObject* res = 0;
421
422 if (PyArg_ParseTuple(args, "O!:isexpr", &PyAST_Type, &ast)) {
423 /*
424 * Check to see if the AST represents an expression or not.
425 */
426 res = (ast->ast_type == PyAST_EXPR) ? Py_True : Py_False;
427 Py_INCREF(res);
428 }
429 return (res);
430
431} /* parser_isexpr() */
432
433
434static PyObject*
435parser_issuite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000436 PyObject *self;
437 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000438{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000439 PyAST_Object* ast;
440 PyObject* res = 0;
441
Guido van Rossum3d602e31996-07-21 02:33:56 +0000442 if (PyArg_ParseTuple(args, "O!:issuite", &PyAST_Type, &ast)) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000443 /*
444 * Check to see if the AST represents an expression or not.
445 */
446 res = (ast->ast_type == PyAST_EXPR) ? Py_False : Py_True;
447 Py_INCREF(res);
448 }
449 return (res);
450
451} /* parser_issuite() */
452
453
Guido van Rossum3d602e31996-07-21 02:33:56 +0000454/* err_string(char* message)
455 *
456 * Sets the error string for an exception of type ParserError.
457 *
458 */
459static void
460err_string(message)
461 char *message;
Guido van Rossum47478871996-08-21 14:32:37 +0000462{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000463 PyErr_SetString(parser_error, message);
464
465} /* err_string() */
466
467
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000468/* PyObject* parser_do_parse(PyObject* args, int type)
469 *
470 * Internal function to actually execute the parse and return the result if
471 * successful, or set an exception if not.
472 *
473 */
474static PyObject*
475parser_do_parse(args, type)
476 PyObject *args;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000477 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000478{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000479 char* string = 0;
480 PyObject* res = 0;
481
482 if (PyArg_ParseTuple(args, "s", &string)) {
483 node* n = PyParser_SimpleParseString(string,
484 (type == PyAST_EXPR)
485 ? eval_input : file_input);
486
487 if (n != 0)
488 res = parser_newastobject(n, type);
489 else
Guido van Rossum3d602e31996-07-21 02:33:56 +0000490 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000491 }
492 return (res);
493
494} /* parser_do_parse() */
495
496
497/* PyObject* parser_expr(PyObject* self, PyObject* args)
498 * PyObject* parser_suite(PyObject* self, PyObject* args)
499 *
500 * External interfaces to the parser itself. Which is called determines if
501 * the parser attempts to recognize an expression ('eval' form) or statement
502 * suite ('exec' form). The real work is done by parser_do_parse() above.
503 *
504 */
505static PyObject*
506parser_expr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000507 PyObject *self;
508 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000509{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000510 return (parser_do_parse(args, PyAST_EXPR));
511
512} /* parser_expr() */
513
514
515static PyObject*
516parser_suite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000517 PyObject *self;
518 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000519{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000520 return (parser_do_parse(args, PyAST_SUITE));
521
522} /* parser_suite() */
523
524
525
526/* This is the messy part of the code. Conversion from a tuple to an AST
527 * object requires that the input tuple be valid without having to rely on
528 * catching an exception from the compiler. This is done to allow the
529 * compiler itself to remain fast, since most of its input will come from
530 * the parser directly, and therefore be known to be syntactically correct.
531 * This validation is done to ensure that we don't core dump the compile
532 * phase, returning an exception instead.
533 *
534 * Two aspects can be broken out in this code: creating a node tree from
535 * the tuple passed in, and verifying that it is indeed valid. It may be
536 * advantageous to expand the number of AST types to include funcdefs and
537 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
538 * here. They are not necessary, and not quite as useful in a raw form.
539 * For now, let's get expressions and suites working reliably.
540 */
541
542
Guido van Rossum2a288461996-08-21 21:55:43 +0000543staticforward node* build_node_tree Py_PROTO((PyObject *tuple));
544staticforward int validate_expr_tree Py_PROTO((node *tree));
545staticforward int validate_file_input Py_PROTO((node *tree));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000546
547
548/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
549 *
550 * This is the public function, called from the Python code. It receives a
551 * single tuple object from the caller, and creates an AST object if the
552 * tuple can be validated. It does this by checking the first code of the
553 * tuple, and, if acceptable, builds the internal representation. If this
554 * step succeeds, the internal representation is validated as fully as
555 * possible with the various validate_*() routines defined below.
556 *
557 * This function must be changed if support is to be added for PyAST_FRAGMENT
558 * AST objects.
559 *
560 */
561static PyObject*
562parser_tuple2ast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000563 PyObject *self;
564 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000565{
566 PyObject *ast = 0;
567 PyObject *tuple = 0;
568 PyObject *temp = 0;
569 int ok;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000570 int start_sym = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000571
Guido van Rossum47478871996-08-21 14:32:37 +0000572 if (!PyArg_ParseTuple(args, "O:tuple2ast", &tuple))
573 return (0);
574 if (!PySequence_Check(tuple)) {
575 PyErr_SetString(PyExc_ValueError,
576 "tuple2ast() requires a single sequence argument");
577 return (0);
578 }
579 /*
580 * This mess of tests is written this way so we can use the abstract
581 * object interface (AOI). Unfortunately, the AOI increments reference
582 * counts, which requires that we store a pointer to retrieved object
583 * so we can DECREF it after the check. But we really should accept
584 * lists as well as tuples at the very least.
585 */
586 ok = PyObject_Length(tuple) >= 2;
587 if (ok) {
588 temp = PySequence_GetItem(tuple, 0);
589 ok = (temp != NULL) && PyInt_Check(temp);
590 if (ok)
591 /* this is used after the initial checks: */
592 start_sym = PyInt_AsLong(temp);
593 Py_XDECREF(temp);
594 }
595 if (ok) {
596 temp = PySequence_GetItem(tuple, 1);
597 ok = (temp != NULL) && PySequence_Check(temp);
598 Py_XDECREF(temp);
599 }
600 if (ok) {
601 temp = PySequence_GetItem(tuple, 1);
602 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
603 if (ok) {
604 PyObject *temp2 = PySequence_GetItem(temp, 0);
605 if (temp2 != NULL) {
606 ok = PyInt_Check(temp2);
607 Py_DECREF(temp2);
608 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000609 }
Guido van Rossum47478871996-08-21 14:32:37 +0000610 Py_XDECREF(temp);
611 }
612 /* If we've failed at some point, get out of here. */
613 if (!ok) {
614 err_string("malformed sequence for tuple2ast()");
615 return (0);
616 }
617 /*
618 * This might be a valid parse tree, but let's do a quick check
619 * before we jump the gun.
620 */
621 if (start_sym == eval_input) {
622 /* Might be an eval form. */
623 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000624
Guido van Rossum47478871996-08-21 14:32:37 +0000625 if ((expression != 0) && validate_expr_tree(expression))
626 ast = parser_newastobject(expression, PyAST_EXPR);
627 }
628 else if (start_sym == file_input) {
629 /* This looks like an exec form so far. */
630 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000631
Guido van Rossum47478871996-08-21 14:32:37 +0000632 if ((suite_tree != 0) && validate_file_input(suite_tree))
633 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000634 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000635 else
Guido van Rossum47478871996-08-21 14:32:37 +0000636 /* This is a fragment, and is not yet supported. Maybe they
637 * will be if I find a use for them.
638 */
639 err_string("Fragmentary parse trees not supported.");
640
641 /* Make sure we throw an exception on all errors. We should never
642 * get this, but we'd do well to be sure something is done.
643 */
644 if ((ast == 0) && !PyErr_Occurred())
645 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000646
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000647 return (ast);
648
649} /* parser_tuple2ast() */
650
651
652/* int check_terminal_tuple()
653 *
Guido van Rossum47478871996-08-21 14:32:37 +0000654 * Check a tuple to determine that it is indeed a valid terminal
655 * node. The node is known to be required as a terminal, so we throw
656 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000657 *
Guido van Rossum47478871996-08-21 14:32:37 +0000658 * The format of an acceptable terminal tuple is "(is[i])": the fact
659 * that elem is a tuple and the integer is a valid terminal symbol
660 * has been established before this function is called. We must
661 * check the length of the tuple and the type of the second element
662 * and optional third element. We do *NOT* check the actual text of
663 * the string element, which we could do in many cases. This is done
664 * by the validate_*() functions which operate on the internal
665 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000666 */
667static int
Guido van Rossum47478871996-08-21 14:32:37 +0000668check_terminal_tuple(elem)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000669 PyObject *elem;
Guido van Rossum47478871996-08-21 14:32:37 +0000670{
671 int len = PyObject_Length(elem);
672 int res = 1;
673 char* str = "Illegal terminal symbol; bad node length.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000674
Guido van Rossum47478871996-08-21 14:32:37 +0000675 if ((len == 2) || (len == 3)) {
676 PyObject *temp = PySequence_GetItem(elem, 1);
677 res = PyString_Check(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000678 str = "Illegal terminal symbol; expected a string.";
Guido van Rossum47478871996-08-21 14:32:37 +0000679 if (res && (len == 3)) {
680 PyObject* third = PySequence_GetItem(elem, 2);
681 res = PyInt_Check(third);
682 str = "Invalid third element of terminal node.";
683 Py_XDECREF(third);
684 }
685 Py_XDECREF(temp);
686 }
687 else {
688 res = 0;
689 }
690 if (!res) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000691 elem = Py_BuildValue("(os)", elem, str);
692 PyErr_SetObject(parser_error, elem);
693 }
694 return (res);
695
696} /* check_terminal_tuple() */
697
698
699/* node* build_node_children()
700 *
701 * Iterate across the children of the current non-terminal node and build
702 * their structures. If successful, return the root of this portion of
703 * the tree, otherwise, 0. Any required exception will be specified already,
704 * and no memory will have been deallocated.
705 *
706 */
707static node*
708build_node_children(tuple, root, line_num)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000709 PyObject *tuple;
710 node *root;
711 int *line_num;
Guido van Rossum47478871996-08-21 14:32:37 +0000712{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000713 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000714 int i;
715
716 for (i = 1; i < len; ++i) {
717 /* elem must always be a tuple, however simple */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000718 PyObject* elem = PySequence_GetItem(tuple, i);
Guido van Rossum47478871996-08-21 14:32:37 +0000719 int ok = elem != NULL;
720 long type = 0;
721 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000722
Guido van Rossum47478871996-08-21 14:32:37 +0000723 if (ok)
724 ok = PySequence_Check(elem);
725 if (ok) {
726 PyObject *temp = PySequence_GetItem(elem, 0);
727 if (temp == NULL)
728 ok = 0;
729 else {
730 ok = PyInt_Check(temp);
731 if (ok)
732 type = PyInt_AsLong(temp);
733 Py_DECREF(temp);
734 }
735 }
736 if (!ok) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000737 PyErr_SetObject(parser_error,
738 Py_BuildValue("(os)", elem,
739 "Illegal node construct."));
Guido van Rossum47478871996-08-21 14:32:37 +0000740 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000741 return (0);
742 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000743 if (ISTERMINAL(type)) {
Guido van Rossum47478871996-08-21 14:32:37 +0000744 if (check_terminal_tuple(elem)) {
745 PyObject *temp = PySequence_GetItem(elem, 1);
746
747 strn = strdup(PyString_AsString(temp));
748 Py_XDECREF(temp);
749
750 if (PyObject_Length(elem) == 3) {
751 PyObject* temp = PySequence_GetItem(elem, 2);
752 *line_num = PyInt_AsLong(temp);
753 Py_DECREF(temp);
754 }
755 }
756 else {
757 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000758 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000759 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000760 }
761 else if (!ISNONTERMINAL(type)) {
762 /*
763 * It has to be one or the other; this is an error.
764 * Throw an exception.
765 */
766 PyErr_SetObject(parser_error,
767 Py_BuildValue("(os)", elem,
768 "Unknown node type."));
Guido van Rossum47478871996-08-21 14:32:37 +0000769 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000770 return (0);
771 }
772 PyNode_AddChild(root, type, strn, *line_num);
773
774 if (ISNONTERMINAL(type)) {
775 node* new_child = CHILD(root, i - 1);
776
Guido van Rossum47478871996-08-21 14:32:37 +0000777 if (new_child != build_node_children(elem, new_child, line_num)) {
778 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000779 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000780 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000781 }
Guido van Rossum47478871996-08-21 14:32:37 +0000782 else if (type == NEWLINE) { /* It's true: we increment the */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000783 ++(*line_num); /* line number *after* the newline! */
Guido van Rossum47478871996-08-21 14:32:37 +0000784 }
785 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000786 }
787 return (root);
788
789} /* build_node_children() */
790
791
792static node*
793build_node_tree(tuple)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000794 PyObject *tuple;
Guido van Rossum47478871996-08-21 14:32:37 +0000795{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000796 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000797 PyObject *temp = PySequence_GetItem(tuple, 0);
798 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000799
Guido van Rossum47478871996-08-21 14:32:37 +0000800 if (temp != NULL)
801 num = PyInt_AsLong(temp);
802 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000803 if (ISTERMINAL(num)) {
804 /*
805 * The tuple is simple, but it doesn't start with a start symbol.
806 * Throw an exception now and be done with it.
807 */
808 tuple = Py_BuildValue("(os)", tuple,
Guido van Rossum3d602e31996-07-21 02:33:56 +0000809 "Illegal ast tuple; cannot start with terminal symbol.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000810 PyErr_SetObject(parser_error, tuple);
811 }
812 else if (ISNONTERMINAL(num)) {
813 /*
814 * Not efficient, but that can be handled later.
815 */
816 int line_num = 0;
817
818 res = PyNode_New(num);
819 if (res != build_node_children(tuple, res, &line_num)) {
820 PyNode_Free(res);
821 res = 0;
822 }
823 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000824 else
825 /* The tuple is illegal -- if the number is neither TERMINAL nor
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000826 * NONTERMINAL, we can't use it.
827 */
828 PyErr_SetObject(parser_error,
829 Py_BuildValue("(os)", tuple,
830 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000831
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000832 return (res);
833
834} /* build_node_tree() */
835
836
Guido van Rossum360a9341996-08-21 19:04:10 +0000837#ifdef HAVE_OLD_CPP
Guido van Rossum2a288461996-08-21 21:55:43 +0000838#define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000839#else
Guido van Rossum2a288461996-08-21 21:55:43 +0000840#define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000841#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000842
843
844/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000845 * Validation routines used within the validation section:
846 */
Guido van Rossum2a288461996-08-21 21:55:43 +0000847staticforward int validate_terminal Py_PROTO((node *terminal,
848 int type, char *string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000849
850#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
851#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
852#define validate_colon(ch) validate_terminal(ch, COLON, ":")
853#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
854#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
855#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000856#define validate_indent(ch) validate_terminal(ch, INDENT, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000857#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000858#define validate_newline(ch) validate_terminal(ch, NEWLINE, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000859#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
860#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
861#define validate_star(ch) validate_terminal(ch, STAR, "*")
862#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000863#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
Guido van Rossum47478871996-08-21 14:32:37 +0000864#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000865#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000866
Guido van Rossum3d602e31996-07-21 02:33:56 +0000867VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000868VALIDATER(class); VALIDATER(node);
869VALIDATER(parameters); VALIDATER(suite);
870VALIDATER(testlist); VALIDATER(varargslist);
871VALIDATER(fpdef); VALIDATER(fplist);
872VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000873VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000874VALIDATER(print_stmt); VALIDATER(del_stmt);
875VALIDATER(return_stmt);
876VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000877VALIDATER(global_stmt);
Guido van Rossum925e5471997-04-02 05:32:13 +0000878VALIDATER(assert_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000879VALIDATER(exec_stmt); VALIDATER(compound_stmt);
880VALIDATER(while); VALIDATER(for);
881VALIDATER(try); VALIDATER(except_clause);
882VALIDATER(test); VALIDATER(and_test);
883VALIDATER(not_test); VALIDATER(comparison);
884VALIDATER(comp_op); VALIDATER(expr);
885VALIDATER(xor_expr); VALIDATER(and_expr);
886VALIDATER(shift_expr); VALIDATER(arith_expr);
887VALIDATER(term); VALIDATER(factor);
888VALIDATER(atom); VALIDATER(lambdef);
889VALIDATER(trailer); VALIDATER(subscript);
Guido van Rossum47478871996-08-21 14:32:37 +0000890VALIDATER(subscriptlist); VALIDATER(sliceop);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000891VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000892VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000893
894
895#define is_even(n) (((n) & 1) == 0)
896#define is_odd(n) (((n) & 1) == 1)
897
898
899static int
900validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000901 node *n;
902 int t;
Guido van Rossum47478871996-08-21 14:32:37 +0000903{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000904 int res = (TYPE(n) == t);
905
906 if (!res) {
907 char buffer[128];
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000908 sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000909 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000910 }
911 return (res);
912
913} /* validate_ntype() */
914
915
916static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000917validate_numnodes(n, num, name)
918 node *n;
919 int num;
920 const char *const name;
Guido van Rossum47478871996-08-21 14:32:37 +0000921{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000922 if (NCH(n) != num) {
923 char buff[60];
924 sprintf(buff, "Illegal number of children for %s node.", name);
925 err_string(buff);
926 }
927 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000928
Guido van Rossum3d602e31996-07-21 02:33:56 +0000929} /* validate_numnodes() */
930
931
932static int
933validate_terminal(terminal, type, string)
934 node *terminal;
935 int type;
936 char *string;
Guido van Rossum47478871996-08-21 14:32:37 +0000937{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000938 int res = (validate_ntype(terminal, type)
939 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
940
941 if (!res && !PyErr_Occurred()) {
942 char buffer[60];
943 sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
944 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000945 }
946 return (res);
947
948} /* validate_terminal() */
949
950
Guido van Rossum47478871996-08-21 14:32:37 +0000951/* X (',' X) [',']
952 */
953static int
954validate_repeating_list(tree, ntype, vfunc, name)
955 node *tree;
956 int ntype;
957 int (*vfunc)();
958 const char *const name;
959{
960 int nch = NCH(tree);
961 int res = (nch && validate_ntype(tree, ntype)
962 && vfunc(CHILD(tree, 0)));
963
964 if (!res && !PyErr_Occurred())
965 validate_numnodes(tree, 1, name);
966 else {
967 if (is_even(nch))
968 res = validate_comma(CHILD(tree, --nch));
969 if (res && nch > 1) {
970 int pos = 1;
971 for ( ; res && pos < nch; pos += 2)
972 res = (validate_comma(CHILD(tree, pos))
973 && vfunc(CHILD(tree, pos + 1)));
974 }
975 }
976 return (res);
977
978} /* validate_repeating_list() */
979
980
Guido van Rossum3d602e31996-07-21 02:33:56 +0000981/* VALIDATE(class)
982 *
983 * classdef:
984 * 'class' NAME ['(' testlist ')'] ':' suite
985 */
Guido van Rossum47478871996-08-21 14:32:37 +0000986static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000987validate_class(tree)
988 node *tree;
989{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000990 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000991 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000992
Guido van Rossum3d602e31996-07-21 02:33:56 +0000993 if (res) {
994 res = (validate_name(CHILD(tree, 0), "class")
995 && validate_ntype(CHILD(tree, 1), NAME)
996 && validate_colon(CHILD(tree, nch - 2))
997 && validate_suite(CHILD(tree, nch - 1)));
998 }
999 else
1000 validate_numnodes(tree, 4, "class");
1001 if (res && (nch == 7)) {
1002 res = (validate_lparen(CHILD(tree, 2))
1003 && validate_testlist(CHILD(tree, 3))
1004 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001005 }
1006 return (res);
1007
1008} /* validate_class() */
1009
1010
Guido van Rossum3d602e31996-07-21 02:33:56 +00001011/* if_stmt:
1012 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1013 */
Guido van Rossum47478871996-08-21 14:32:37 +00001014static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001015validate_if(tree)
1016 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001017{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001018 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001019 int res = (validate_ntype(tree, if_stmt)
1020 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001021 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +00001022 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001023 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001024 && validate_suite(CHILD(tree, 3)));
1025
1026 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001027 /* ... 'else' ':' suite */
1028 res = (validate_name(CHILD(tree, nch - 3), "else")
1029 && validate_colon(CHILD(tree, nch - 2))
1030 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001031 nch -= 3;
1032 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001033 else if (!res && !PyErr_Occurred())
1034 validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001035 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001036 /* Will catch the case for nch < 4 */
1037 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001038 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001039 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001040 int j = 4;
1041 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001042 res = (validate_name(CHILD(tree, j), "elif")
1043 && validate_colon(CHILD(tree, j + 2))
1044 && validate_test(CHILD(tree, j + 1))
1045 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001046 j += 4;
1047 }
1048 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001049 return (res);
1050
1051} /* validate_if() */
1052
1053
Guido van Rossum3d602e31996-07-21 02:33:56 +00001054/* parameters:
1055 * '(' [varargslist] ')'
1056 *
1057 */
Guido van Rossum47478871996-08-21 14:32:37 +00001058static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001059validate_parameters(tree)
1060 node *tree;
1061{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001062 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001063 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001064
Guido van Rossum3d602e31996-07-21 02:33:56 +00001065 if (res) {
1066 res = (validate_lparen(CHILD(tree, 0))
1067 && validate_rparen(CHILD(tree, nch - 1)));
1068 if (res && (nch == 3))
1069 res = validate_varargslist(CHILD(tree, 1));
1070 }
1071 else
1072 validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001073
1074 return (res);
1075
1076} /* validate_parameters() */
1077
1078
Guido van Rossum3d602e31996-07-21 02:33:56 +00001079/* VALIDATE(suite)
1080 *
1081 * suite:
1082 * simple_stmt
1083 * | NEWLINE INDENT stmt+ DEDENT
1084 */
Guido van Rossum47478871996-08-21 14:32:37 +00001085static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001086validate_suite(tree)
1087 node *tree;
1088{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001089 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001090 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001091
Guido van Rossum3d602e31996-07-21 02:33:56 +00001092 if (res && (nch == 1))
1093 res = validate_simple_stmt(CHILD(tree, 0));
1094 else if (res) {
1095 /* NEWLINE INDENT stmt+ DEDENT */
1096 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001097 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001098 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001099 && validate_dedent(CHILD(tree, nch - 1)));
1100
Guido van Rossum3d602e31996-07-21 02:33:56 +00001101 if (res && (nch > 4)) {
1102 int i = 3;
1103 --nch; /* forget the DEDENT */
1104 for ( ; res && (i < nch); ++i)
1105 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001106 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001107 else if (nch < 4)
1108 validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001109 }
1110 return (res);
1111
1112} /* validate_suite() */
1113
1114
Guido van Rossum47478871996-08-21 14:32:37 +00001115static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001116validate_testlist(tree)
1117 node *tree;
1118{
Guido van Rossum47478871996-08-21 14:32:37 +00001119 return (validate_repeating_list(tree, testlist,
1120 validate_test, "testlist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001121
1122} /* validate_testlist() */
1123
1124
Guido van Rossum3d602e31996-07-21 02:33:56 +00001125/* VALIDATE(varargslist)
1126 *
1127 * varargslist:
1128 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1129 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1130 *
1131 * (fpdef ['=' test] ',')*
1132 * ('*' NAME [',' ('**'|'*' '*') NAME]
1133 * | ('**'|'*' '*') NAME)
1134 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1135 *
1136 */
Guido van Rossum47478871996-08-21 14:32:37 +00001137static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001138validate_varargslist(tree)
1139 node *tree;
1140{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001141 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001142 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001143
Guido van Rossum3d602e31996-07-21 02:33:56 +00001144 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1145 /* (fpdef ['=' test] ',')*
1146 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1147 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001148 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001149 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001150
Guido van Rossum3d602e31996-07-21 02:33:56 +00001151 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1152 res = validate_fpdef(CHILD(tree, pos));
1153 if (res) {
1154 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1155 res = validate_test(CHILD(tree, pos + 2));
1156 pos += 2;
1157 }
1158 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001159 pos += 2;
1160 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001161 }
1162 if (res) {
1163 remaining = nch - pos;
1164 res = ((remaining == 2) || (remaining == 3)
1165 || (remaining == 5) || (remaining == 6));
1166 if (!res)
1167 validate_numnodes(tree, 2, "varargslist");
1168 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1169 return ((remaining == 2)
1170 && validate_ntype(CHILD(tree, pos+1), NAME));
1171 else {
1172 res = validate_star(CHILD(tree, pos++));
1173 --remaining;
1174 }
1175 }
1176 if (res) {
1177 if (remaining == 2) {
1178 res = (validate_star(CHILD(tree, pos))
1179 && validate_ntype(CHILD(tree, pos + 1), NAME));
1180 }
1181 else {
1182 res = validate_ntype(CHILD(tree, pos++), NAME);
1183 if (res && (remaining >= 4)) {
1184 res = validate_comma(CHILD(tree, pos));
1185 if (--remaining == 3)
Fred Drakee1607a81996-09-11 21:58:26 +00001186 res = (validate_star(CHILD(tree, pos + 1))
1187 && validate_star(CHILD(tree, pos + 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001188 else
1189 validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1190 }
1191 }
1192 }
1193 if (!res && !PyErr_Occurred())
1194 err_string("Incorrect validation of variable arguments list.");
1195 }
1196 else if (res) {
1197 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1198 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1199 --nch;
1200
1201 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1202 res = (is_odd(nch)
1203 && validate_fpdef(CHILD(tree, 0)));
1204
1205 if (res && (nch > 1)) {
1206 int pos = 1;
1207 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1208 res = validate_test(CHILD(tree, 2));
1209 pos += 2;
1210 }
1211 /* ... (',' fpdef ['=' test])* */
1212 for ( ; res && (pos < nch); pos += 2) {
1213 /* ',' fpdef */
1214 res = (validate_comma(CHILD(tree, pos))
1215 && validate_fpdef(CHILD(tree, pos + 1)));
1216 if (res
1217 && ((nch - pos) > 2)
1218 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1219 /* ['=' test] */
1220 res = validate_test(CHILD(tree, pos + 3));
1221 pos += 2;
1222 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001223 }
1224 }
1225 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001226 else
1227 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001228
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001229 return (res);
1230
1231} /* validate_varargslist() */
1232
1233
Guido van Rossum3d602e31996-07-21 02:33:56 +00001234/* VALIDATE(fpdef)
1235 *
1236 * fpdef:
1237 * NAME
1238 * | '(' fplist ')'
1239 */
Guido van Rossum47478871996-08-21 14:32:37 +00001240static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001241validate_fpdef(tree)
1242 node *tree;
1243{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001244 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001245 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001246
Guido van Rossum3d602e31996-07-21 02:33:56 +00001247 if (res) {
1248 if (nch == 1)
1249 res = validate_ntype(CHILD(tree, 0), NAME);
1250 else if (nch == 3)
1251 res = (validate_lparen(CHILD(tree, 0))
1252 && validate_fplist(CHILD(tree, 1))
1253 && validate_rparen(CHILD(tree, 2)));
1254 else
1255 validate_numnodes(tree, 1, "fpdef");
1256 }
1257 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001258
1259} /* validate_fpdef() */
1260
1261
Guido van Rossum47478871996-08-21 14:32:37 +00001262static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001263validate_fplist(tree)
1264 node *tree;
1265{
Guido van Rossum47478871996-08-21 14:32:37 +00001266 return (validate_repeating_list(tree, fplist,
1267 validate_fpdef, "fplist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001268
1269} /* validate_fplist() */
1270
1271
Guido van Rossum3d602e31996-07-21 02:33:56 +00001272/* simple_stmt | compound_stmt
1273 *
1274 */
Guido van Rossum47478871996-08-21 14:32:37 +00001275static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001276validate_stmt(tree)
1277 node *tree;
1278{
1279 int res = (validate_ntype(tree, stmt)
1280 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001281
Guido van Rossum3d602e31996-07-21 02:33:56 +00001282 if (res) {
1283 tree = CHILD(tree, 0);
1284
1285 if (TYPE(tree) == simple_stmt)
1286 res = validate_simple_stmt(tree);
1287 else
1288 res = validate_compound_stmt(tree);
1289 }
1290 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001291
1292} /* validate_stmt() */
1293
1294
Guido van Rossum3d602e31996-07-21 02:33:56 +00001295/* small_stmt (';' small_stmt)* [';'] NEWLINE
1296 *
1297 */
Guido van Rossum47478871996-08-21 14:32:37 +00001298static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001299validate_simple_stmt(tree)
1300 node *tree;
1301{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001302 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001303 int res = (validate_ntype(tree, simple_stmt)
1304 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001305 && validate_small_stmt(CHILD(tree, 0))
1306 && validate_newline(CHILD(tree, nch - 1)));
1307
Guido van Rossum3d602e31996-07-21 02:33:56 +00001308 if (nch < 2)
1309 res = validate_numnodes(tree, 2, "simple_stmt");
1310 --nch; /* forget the NEWLINE */
1311 if (res && is_even(nch))
1312 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001313 if (res && (nch > 2)) {
1314 int i;
1315
Guido van Rossum3d602e31996-07-21 02:33:56 +00001316 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001317 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001318 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001319 }
1320 return (res);
1321
1322} /* validate_simple_stmt() */
1323
1324
Guido van Rossum47478871996-08-21 14:32:37 +00001325static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001326validate_small_stmt(tree)
1327 node *tree;
1328{
1329 int nch = NCH(tree);
1330 int res = (validate_numnodes(tree, 1, "small_stmt")
1331 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1332 || (TYPE(CHILD(tree, 0)) == print_stmt)
1333 || (TYPE(CHILD(tree, 0)) == del_stmt)
1334 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1335 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1336 || (TYPE(CHILD(tree, 0)) == import_stmt)
1337 || (TYPE(CHILD(tree, 0)) == global_stmt)
Guido van Rossum925e5471997-04-02 05:32:13 +00001338 || (TYPE(CHILD(tree, 0)) == assert_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001339 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1340
1341 if (res)
1342 res = validate_node(CHILD(tree, 0));
1343 else if (nch == 1) {
1344 char buffer[60];
1345 sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1346 TYPE(CHILD(tree, 0)));
1347 err_string(buffer);
1348 }
1349 return (res);
1350
1351} /* validate_small_stmt */
1352
1353
1354/* compound_stmt:
1355 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1356 */
Guido van Rossum47478871996-08-21 14:32:37 +00001357static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001358validate_compound_stmt(tree)
1359 node *tree;
1360{
1361 int res = (validate_ntype(tree, compound_stmt)
1362 && validate_numnodes(tree, 1, "compound_stmt"));
1363
1364 if (!res)
1365 return (0);
1366
1367 tree = CHILD(tree, 0);
1368 res = ((TYPE(tree) == if_stmt)
1369 || (TYPE(tree) == while_stmt)
1370 || (TYPE(tree) == for_stmt)
1371 || (TYPE(tree) == try_stmt)
1372 || (TYPE(tree) == funcdef)
1373 || (TYPE(tree) == classdef));
1374 if (res)
1375 res = validate_node(tree);
1376 else {
1377 char buffer[60];
1378 sprintf(buffer, "Illegal compound statement type: %d.", TYPE(tree));
1379 err_string(buffer);
1380 }
1381 return (res);
1382
1383} /* validate_compound_stmt() */
1384
1385
Guido van Rossum47478871996-08-21 14:32:37 +00001386static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001387validate_expr_stmt(tree)
1388 node *tree;
1389{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001390 int j;
1391 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001392 int res = (validate_ntype(tree, expr_stmt)
1393 && is_odd(nch)
1394 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001395
Guido van Rossum3d602e31996-07-21 02:33:56 +00001396 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001397 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001398 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001399
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001400 return (res);
1401
1402} /* validate_expr_stmt() */
1403
1404
Guido van Rossum3d602e31996-07-21 02:33:56 +00001405/* print_stmt:
1406 *
1407 * 'print' (test ',')* [test]
1408 *
1409 */
Guido van Rossum47478871996-08-21 14:32:37 +00001410static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001411validate_print_stmt(tree)
1412 node *tree;
1413{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001414 int j;
1415 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001416 int res = (validate_ntype(tree, print_stmt)
1417 && (nch != 0)
1418 && validate_name(CHILD(tree, 0), "print"));
1419
1420 if (res && is_even(nch)) {
1421 res = validate_test(CHILD(tree, nch - 1));
1422 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001423 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001424 else if (!res && !PyErr_Occurred())
1425 validate_numnodes(tree, 1, "print_stmt");
1426 for (j = 1; res && (j < nch); j += 2)
1427 res = (validate_test(CHILD(tree, j))
1428 && validate_ntype(CHILD(tree, j + 1), COMMA));
1429
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001430 return (res);
1431
1432} /* validate_print_stmt() */
1433
1434
Guido van Rossum47478871996-08-21 14:32:37 +00001435static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001436validate_del_stmt(tree)
1437 node *tree;
1438{
1439 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001440 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001441 && validate_exprlist(CHILD(tree, 1)));
1442
1443} /* validate_del_stmt() */
1444
1445
Guido van Rossum47478871996-08-21 14:32:37 +00001446static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001447validate_return_stmt(tree)
1448 node *tree;
1449{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001450 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001451 int res = (validate_ntype(tree, return_stmt)
1452 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001453 && validate_name(CHILD(tree, 0), "return"));
1454
Guido van Rossum3d602e31996-07-21 02:33:56 +00001455 if (res && (nch == 2))
1456 res = validate_testlist(CHILD(tree, 1));
1457
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001458 return (res);
1459
1460} /* validate_return_stmt() */
1461
1462
Guido van Rossum47478871996-08-21 14:32:37 +00001463static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001464validate_raise_stmt(tree)
1465 node *tree;
1466{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001467 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001468 int res = (validate_ntype(tree, raise_stmt)
1469 && ((nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001470
Guido van Rossum3d602e31996-07-21 02:33:56 +00001471 if (res) {
1472 res = (validate_name(CHILD(tree, 0), "raise")
1473 && validate_test(CHILD(tree, 1)));
1474 if (res && nch > 2) {
1475 res = (validate_comma(CHILD(tree, 2))
1476 && validate_test(CHILD(tree, 3)));
1477 if (res && (nch > 4))
1478 res = (validate_comma(CHILD(tree, 4))
1479 && validate_test(CHILD(tree, 5)));
1480 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001481 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001482 else
1483 validate_numnodes(tree, 2, "raise");
1484 if (res && (nch == 4))
1485 res = (validate_comma(CHILD(tree, 2))
1486 && validate_test(CHILD(tree, 3)));
1487
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001488 return (res);
1489
1490} /* validate_raise_stmt() */
1491
1492
Guido van Rossum3d602e31996-07-21 02:33:56 +00001493/* import_stmt:
1494 *
1495 * 'import' dotted_name (',' dotted_name)*
1496 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1497 */
Guido van Rossum47478871996-08-21 14:32:37 +00001498static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001499validate_import_stmt(tree)
1500 node *tree;
1501{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001502 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001503 int res = (validate_ntype(tree, import_stmt)
1504 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001505 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001506 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001507
1508 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001509 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001510
Guido van Rossum3d602e31996-07-21 02:33:56 +00001511 for (j = 2; res && (j < nch); j += 2)
1512 res = (validate_comma(CHILD(tree, j))
1513 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001514 }
1515 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001516 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001517 && validate_name(CHILD(tree, 2), "import"));
1518 if (nch == 4) {
1519 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001520 || (TYPE(CHILD(tree, 3)) == STAR));
1521 if (!res)
1522 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001523 }
1524 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001525 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001526 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001527 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001528 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001529 res = (validate_comma(CHILD(tree, j))
1530 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001531 }
1532 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001533 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001534 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001535
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001536 return (res);
1537
1538} /* validate_import_stmt() */
1539
1540
Guido van Rossum47478871996-08-21 14:32:37 +00001541static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001542validate_global_stmt(tree)
1543 node *tree;
1544{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001545 int j;
1546 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001547 int res = (validate_ntype(tree, global_stmt)
1548 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001549
Guido van Rossum3d602e31996-07-21 02:33:56 +00001550 if (res)
1551 res = (validate_name(CHILD(tree, 0), "global")
1552 && validate_ntype(CHILD(tree, 1), NAME));
1553 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001554 res = (validate_comma(CHILD(tree, j))
1555 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001556
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001557 return (res);
1558
1559} /* validate_global_stmt() */
1560
1561
Guido van Rossum3d602e31996-07-21 02:33:56 +00001562/* exec_stmt:
1563 *
1564 * 'exec' expr ['in' test [',' test]]
1565 */
Guido van Rossum47478871996-08-21 14:32:37 +00001566static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001567validate_exec_stmt(tree)
1568 node *tree;
1569{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001570 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001571 int res = (validate_ntype(tree, exec_stmt)
1572 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001573 && validate_name(CHILD(tree, 0), "exec")
1574 && validate_expr(CHILD(tree, 1)));
1575
Guido van Rossum3d602e31996-07-21 02:33:56 +00001576 if (!res && !PyErr_Occurred())
1577 err_string("Illegal exec statement.");
1578 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001579 res = (validate_name(CHILD(tree, 2), "in")
1580 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001581 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001582 res = (validate_comma(CHILD(tree, 4))
1583 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001584
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001585 return (res);
1586
1587} /* validate_exec_stmt() */
1588
1589
Guido van Rossum925e5471997-04-02 05:32:13 +00001590/* assert_stmt:
1591 *
1592 * 'assert' test [',' test]
1593 */
1594static int
1595validate_assert_stmt(tree)
1596 node *tree;
1597{
1598 int nch = NCH(tree);
1599 int res = (validate_ntype(tree, assert_stmt)
1600 && ((nch == 2) || (nch == 4))
1601 && (validate_name(CHILD(tree, 0), "__assert__") ||
1602 validate_name(CHILD(tree, 0), "assert"))
1603 && validate_test(CHILD(tree, 1)));
1604
1605 if (!res && !PyErr_Occurred())
1606 err_string("Illegal assert statement.");
1607 if (res && (nch > 2))
1608 res = (validate_comma(CHILD(tree, 2))
1609 && validate_test(CHILD(tree, 3)));
1610
1611 return (res);
1612
1613} /* validate_assert_stmt() */
1614
1615
Guido van Rossum47478871996-08-21 14:32:37 +00001616static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001617validate_while(tree)
1618 node *tree;
1619{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001620 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001621 int res = (validate_ntype(tree, while_stmt)
1622 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001623 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001624 && validate_test(CHILD(tree, 1))
1625 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001626 && validate_suite(CHILD(tree, 3)));
1627
Guido van Rossum3d602e31996-07-21 02:33:56 +00001628 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001629 res = (validate_name(CHILD(tree, 4), "else")
1630 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001631 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001632
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001633 return (res);
1634
1635} /* validate_while() */
1636
1637
Guido van Rossum47478871996-08-21 14:32:37 +00001638static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001639validate_for(tree)
1640 node *tree;
1641{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001642 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001643 int res = (validate_ntype(tree, for_stmt)
1644 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001645 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001646 && validate_exprlist(CHILD(tree, 1))
1647 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001648 && validate_testlist(CHILD(tree, 3))
1649 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001650 && validate_suite(CHILD(tree, 5)));
1651
Guido van Rossum3d602e31996-07-21 02:33:56 +00001652 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001653 res = (validate_name(CHILD(tree, 6), "else")
1654 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001655 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001656
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001657 return (res);
1658
1659} /* validate_for() */
1660
1661
Guido van Rossum3d602e31996-07-21 02:33:56 +00001662/* try_stmt:
1663 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1664 * | 'try' ':' suite 'finally' ':' suite
1665 *
1666 */
Guido van Rossum47478871996-08-21 14:32:37 +00001667static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001668validate_try(tree)
1669 node *tree;
1670{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001671 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001672 int pos = 3;
1673 int res = (validate_ntype(tree, try_stmt)
1674 && (nch >= 6) && ((nch % 3) == 0));
1675
1676 if (res)
1677 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001678 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001679 && validate_suite(CHILD(tree, 2))
1680 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001681 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001682 else {
1683 const char* name = "execpt";
1684 char buffer[60];
1685 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1686 name = STR(CHILD(tree, nch - 3));
1687 sprintf(buffer, "Illegal number of children for try/%s node.", name);
1688 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001689 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001690 /* Skip past except_clause sections: */
1691 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1692 res = (validate_except_clause(CHILD(tree, pos))
1693 && validate_colon(CHILD(tree, pos + 1))
1694 && validate_suite(CHILD(tree, pos + 2)));
1695 pos += 3;
1696 }
1697 if (res && (pos < nch)) {
1698 res = validate_ntype(CHILD(tree, pos), NAME);
1699 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1700 res = (validate_numnodes(tree, 6, "try/finally")
1701 && validate_colon(CHILD(tree, 4))
1702 && validate_suite(CHILD(tree, 5)));
1703 else if (res)
1704 if (nch == (pos + 3)) {
1705 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1706 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1707 if (!res)
1708 err_string("Illegal trailing triple in try statement.");
1709 }
1710 else if (nch == (pos + 6))
1711 res = (validate_name(CHILD(tree, pos), "except")
1712 && validate_colon(CHILD(tree, pos + 1))
1713 && validate_suite(CHILD(tree, pos + 2))
1714 && validate_name(CHILD(tree, pos + 3), "else"));
1715 else
1716 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001717 }
1718 return (res);
1719
1720} /* validate_try() */
1721
1722
Guido van Rossum47478871996-08-21 14:32:37 +00001723static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001724validate_except_clause(tree)
1725 node *tree;
1726{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001727 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001728 int res = (validate_ntype(tree, except_clause)
1729 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001730 && validate_name(CHILD(tree, 0), "except"));
1731
Guido van Rossum3d602e31996-07-21 02:33:56 +00001732 if (res && (nch > 1))
1733 res = validate_test(CHILD(tree, 1));
1734 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001735 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001736 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001737
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001738 return (res);
1739
1740} /* validate_except_clause() */
1741
1742
Guido van Rossum47478871996-08-21 14:32:37 +00001743static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001744validate_test(tree)
1745 node *tree;
1746{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001747 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001748 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001749
Guido van Rossum3d602e31996-07-21 02:33:56 +00001750 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001751 res = ((nch == 1)
1752 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001753 else if (res) {
1754 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001755 res = validate_and_test(CHILD(tree, 0));
1756 for (pos = 1; res && (pos < nch); pos += 2)
1757 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001758 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001759 }
1760 return (res);
1761
1762} /* validate_test() */
1763
1764
Guido van Rossum47478871996-08-21 14:32:37 +00001765static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001766validate_and_test(tree)
1767 node *tree;
1768{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001769 int pos;
1770 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001771 int res = (validate_ntype(tree, and_test)
1772 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001773 && validate_not_test(CHILD(tree, 0)));
1774
Guido van Rossum3d602e31996-07-21 02:33:56 +00001775 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001776 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001777 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001778
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001779 return (res);
1780
1781} /* validate_and_test() */
1782
1783
Guido van Rossum47478871996-08-21 14:32:37 +00001784static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001785validate_not_test(tree)
1786 node *tree;
1787{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001788 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001789 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001790
Guido van Rossum3d602e31996-07-21 02:33:56 +00001791 if (res) {
1792 if (nch == 2)
1793 res = (validate_name(CHILD(tree, 0), "not")
1794 && validate_not_test(CHILD(tree, 1)));
1795 else if (nch == 1)
1796 res = validate_comparison(CHILD(tree, 0));
1797 }
1798 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001799
1800} /* validate_not_test() */
1801
1802
Guido van Rossum47478871996-08-21 14:32:37 +00001803static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001804validate_comparison(tree)
1805 node *tree;
1806{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001807 int pos;
1808 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001809 int res = (validate_ntype(tree, comparison)
1810 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001811 && validate_expr(CHILD(tree, 0)));
1812
Guido van Rossum3d602e31996-07-21 02:33:56 +00001813 for (pos = 1; res && (pos < nch); pos += 2)
1814 res = (validate_comp_op(CHILD(tree, pos))
1815 && validate_expr(CHILD(tree, pos + 1)));
1816
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001817 return (res);
1818
1819} /* validate_comparison() */
1820
1821
Guido van Rossum47478871996-08-21 14:32:37 +00001822static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001823validate_comp_op(tree)
1824 node *tree;
1825{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001826 int res = 0;
1827 int nch = NCH(tree);
1828
Guido van Rossum3d602e31996-07-21 02:33:56 +00001829 if (!validate_ntype(tree, comp_op))
1830 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001831 if (nch == 1) {
1832 /*
1833 * Only child will be a terminal with a well-defined symbolic name
1834 * or a NAME with a string of either 'is' or 'in'
1835 */
1836 tree = CHILD(tree, 0);
1837 switch (TYPE(tree)) {
1838 case LESS:
1839 case GREATER:
1840 case EQEQUAL:
1841 case EQUAL:
1842 case LESSEQUAL:
1843 case GREATEREQUAL:
1844 case NOTEQUAL:
1845 res = 1;
1846 break;
1847 case NAME:
1848 res = ((strcmp(STR(tree), "in") == 0)
1849 || (strcmp(STR(tree), "is") == 0));
1850 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001851 char buff[128];
1852 sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1853 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001854 }
1855 break;
1856 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001857 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001858 break;
1859 }
1860 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001861 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001862 res = (validate_ntype(CHILD(tree, 0), NAME)
1863 && validate_ntype(CHILD(tree, 1), NAME)
1864 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1865 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1866 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1867 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001868 if (!res && !PyErr_Occurred())
1869 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001870 }
1871 return (res);
1872
1873} /* validate_comp_op() */
1874
1875
Guido van Rossum47478871996-08-21 14:32:37 +00001876static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001877validate_expr(tree)
1878 node *tree;
1879{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001880 int j;
1881 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001882 int res = (validate_ntype(tree, expr)
1883 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001884 && validate_xor_expr(CHILD(tree, 0)));
1885
Guido van Rossum3d602e31996-07-21 02:33:56 +00001886 for (j = 2; res && (j < nch); j += 2)
1887 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001888 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001889
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001890 return (res);
1891
1892} /* validate_expr() */
1893
1894
Guido van Rossum47478871996-08-21 14:32:37 +00001895static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001896validate_xor_expr(tree)
1897 node *tree;
1898{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001899 int j;
1900 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001901 int res = (validate_ntype(tree, xor_expr)
1902 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001903 && validate_and_expr(CHILD(tree, 0)));
1904
Guido van Rossum3d602e31996-07-21 02:33:56 +00001905 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001906 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001907 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001908
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001909 return (res);
1910
1911} /* validate_xor_expr() */
1912
1913
Guido van Rossum47478871996-08-21 14:32:37 +00001914static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001915validate_and_expr(tree)
1916 node *tree;
1917{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001918 int pos;
1919 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001920 int res = (validate_ntype(tree, and_expr)
1921 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001922 && validate_shift_expr(CHILD(tree, 0)));
1923
Guido van Rossum3d602e31996-07-21 02:33:56 +00001924 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001925 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001926 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001927
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001928 return (res);
1929
1930} /* validate_and_expr() */
1931
1932
1933static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001934validate_chain_two_ops(tree, termvalid, op1, op2)
1935 node *tree;
1936 int (*termvalid)();
1937 int op1;
1938 int op2;
1939 {
1940 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001941 int nch = NCH(tree);
1942 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001943 && (*termvalid)(CHILD(tree, 0)));
1944
Guido van Rossum3d602e31996-07-21 02:33:56 +00001945 for ( ; res && (pos < nch); pos += 2) {
1946 if (TYPE(CHILD(tree, pos)) != op1)
1947 res = validate_ntype(CHILD(tree, pos), op2);
1948 if (res)
1949 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001950 }
1951 return (res);
1952
1953} /* validate_chain_two_ops() */
1954
1955
Guido van Rossum47478871996-08-21 14:32:37 +00001956static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001957validate_shift_expr(tree)
1958 node *tree;
1959{
1960 return (validate_ntype(tree, shift_expr)
1961 && validate_chain_two_ops(tree, validate_arith_expr,
1962 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001963
1964} /* validate_shift_expr() */
1965
1966
Guido van Rossum47478871996-08-21 14:32:37 +00001967static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001968validate_arith_expr(tree)
1969 node *tree;
1970{
1971 return (validate_ntype(tree, arith_expr)
1972 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001973
1974} /* validate_arith_expr() */
1975
1976
Guido van Rossum47478871996-08-21 14:32:37 +00001977static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001978validate_term(tree)
1979 node *tree;
1980{
1981 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001982 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001983 int res = (validate_ntype(tree, term)
1984 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001985 && validate_factor(CHILD(tree, 0)));
1986
Guido van Rossum3d602e31996-07-21 02:33:56 +00001987 for ( ; res && (pos < nch); pos += 2)
1988 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001989 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001990 || (TYPE(CHILD(tree, pos)) == PERCENT))
1991 && validate_factor(CHILD(tree, pos + 1)));
1992
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001993 return (res);
1994
1995} /* validate_term() */
1996
1997
Guido van Rossum3d602e31996-07-21 02:33:56 +00001998/* factor:
1999 *
2000 * factor: ('+'|'-'|'~') factor | power
2001 */
Guido van Rossum47478871996-08-21 14:32:37 +00002002static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002003validate_factor(tree)
2004 node *tree;
2005{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002006 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002007 int res = (validate_ntype(tree, factor)
2008 && (((nch == 2)
2009 && ((TYPE(CHILD(tree, 0)) == PLUS)
2010 || (TYPE(CHILD(tree, 0)) == MINUS)
2011 || (TYPE(CHILD(tree, 0)) == TILDE))
2012 && validate_factor(CHILD(tree, 1)))
2013 || ((nch == 1)
2014 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002015 return (res);
2016
2017} /* validate_factor() */
2018
2019
Guido van Rossum3d602e31996-07-21 02:33:56 +00002020/* power:
2021 *
2022 * power: atom trailer* ('**' factor)*
2023 */
Guido van Rossum47478871996-08-21 14:32:37 +00002024static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002025validate_power(tree)
2026 node *tree;
2027{
2028 int pos = 1;
2029 int nch = NCH(tree);
2030 int res = (validate_ntype(tree, power) && (nch >= 1)
2031 && validate_atom(CHILD(tree, 0)));
2032
2033 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2034 res = validate_trailer(CHILD(tree, pos++));
2035 if (res && (pos < nch)) {
2036 if (!is_even(nch - pos)) {
2037 err_string("Illegal number of nodes for 'power'.");
2038 return (0);
2039 }
2040 for ( ; res && (pos < (nch - 1)); pos += 2)
2041 res = (validate_doublestar(CHILD(tree, pos))
2042 && validate_factor(CHILD(tree, pos + 1)));
2043 }
2044 return (res);
2045
2046} /* validate_power() */
2047
2048
Guido van Rossum47478871996-08-21 14:32:37 +00002049static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002050validate_atom(tree)
2051 node *tree;
2052{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002053 int pos;
2054 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002055 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002056
2057 if (res) {
2058 switch (TYPE(CHILD(tree, 0))) {
2059 case LPAR:
2060 res = ((nch <= 3)
2061 && (validate_rparen(CHILD(tree, nch - 1))));
2062
Guido van Rossum3d602e31996-07-21 02:33:56 +00002063 if (res && (nch == 3))
2064 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002065 break;
2066 case LSQB:
2067 res = ((nch <= 3)
2068 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2069
Guido van Rossum3d602e31996-07-21 02:33:56 +00002070 if (res && (nch == 3))
2071 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002072 break;
2073 case LBRACE:
2074 res = ((nch <= 3)
2075 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2076
Guido van Rossum3d602e31996-07-21 02:33:56 +00002077 if (res && (nch == 3))
2078 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002079 break;
2080 case BACKQUOTE:
2081 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002082 && validate_testlist(CHILD(tree, 1))
2083 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2084 break;
2085 case NAME:
2086 case NUMBER:
2087 res = (nch == 1);
2088 break;
2089 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002090 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002091 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002092 break;
2093 default:
2094 res = 0;
2095 break;
2096 }
2097 }
2098 return (res);
2099
2100} /* validate_atom() */
2101
2102
Guido van Rossum3d602e31996-07-21 02:33:56 +00002103/* funcdef:
2104 * 'def' NAME parameters ':' suite
2105 *
2106 */
Guido van Rossum47478871996-08-21 14:32:37 +00002107static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002108validate_funcdef(tree)
2109 node *tree;
2110{
2111 return (validate_ntype(tree, funcdef)
2112 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002113 && validate_name(CHILD(tree, 0), "def")
2114 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002115 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002116 && validate_parameters(CHILD(tree, 2))
2117 && validate_suite(CHILD(tree, 4)));
2118
2119} /* validate_funcdef() */
2120
2121
Guido van Rossum47478871996-08-21 14:32:37 +00002122static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002123validate_lambdef(tree)
2124 node *tree;
2125{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002126 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002127 int res = (validate_ntype(tree, lambdef)
2128 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002129 && validate_name(CHILD(tree, 0), "lambda")
2130 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002131 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002132
Guido van Rossum3d602e31996-07-21 02:33:56 +00002133 if (res && (nch == 4))
2134 res = validate_varargslist(CHILD(tree, 1));
2135 else if (!res && !PyErr_Occurred())
2136 validate_numnodes(tree, 3, "lambdef");
2137
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002138 return (res);
2139
2140} /* validate_lambdef() */
2141
2142
Guido van Rossum3d602e31996-07-21 02:33:56 +00002143/* arglist:
2144 *
2145 * argument (',' argument)* [',']
2146 */
Guido van Rossum47478871996-08-21 14:32:37 +00002147static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002148validate_arglist(tree)
2149 node *tree;
2150{
Guido van Rossum47478871996-08-21 14:32:37 +00002151 return (validate_repeating_list(tree, arglist,
2152 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002153
2154} /* validate_arglist() */
2155
2156
2157
2158/* argument:
2159 *
2160 * [test '='] test
2161 */
Guido van Rossum47478871996-08-21 14:32:37 +00002162static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002163validate_argument(tree)
2164 node *tree;
2165{
2166 int nch = NCH(tree);
2167 int res = (validate_ntype(tree, argument)
2168 && ((nch == 1) || (nch == 3))
2169 && validate_test(CHILD(tree, 0)));
2170
2171 if (res && (nch == 3))
2172 res = (validate_equal(CHILD(tree, 1))
2173 && validate_test(CHILD(tree, 2)));
2174
2175 return (res);
2176
2177} /* validate_argument() */
2178
2179
2180
2181/* trailer:
2182 *
Guido van Rossum47478871996-08-21 14:32:37 +00002183 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002184 */
Guido van Rossum47478871996-08-21 14:32:37 +00002185static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002186validate_trailer(tree)
2187 node *tree;
2188{
2189 int nch = NCH(tree);
2190 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002191
2192 if (res) {
2193 switch (TYPE(CHILD(tree, 0))) {
2194 case LPAR:
2195 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002196 if (res && (nch == 3))
2197 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002198 break;
2199 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002200 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002201 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002202 && validate_ntype(CHILD(tree, 2), RSQB));
2203 break;
2204 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002205 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002206 && validate_ntype(CHILD(tree, 1), NAME));
2207 break;
2208 default:
2209 res = 0;
2210 break;
2211 }
2212 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002213 else
2214 validate_numnodes(tree, 2, "trailer");
2215
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002216 return (res);
2217
2218} /* validate_trailer() */
2219
2220
Guido van Rossum47478871996-08-21 14:32:37 +00002221/* subscriptlist:
2222 *
2223 * subscript (',' subscript)* [',']
2224 */
2225static int
2226validate_subscriptlist(tree)
2227 node *tree;
2228{
2229 return (validate_repeating_list(tree, subscriptlist,
2230 validate_subscript, "subscriptlist"));
2231
2232} /* validate_subscriptlist() */
2233
2234
Guido van Rossum3d602e31996-07-21 02:33:56 +00002235/* subscript:
2236 *
Guido van Rossum47478871996-08-21 14:32:37 +00002237 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002238 */
Guido van Rossum47478871996-08-21 14:32:37 +00002239static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002240validate_subscript(tree)
2241 node *tree;
2242{
Guido van Rossum47478871996-08-21 14:32:37 +00002243 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002244 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002245 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002246
Guido van Rossum47478871996-08-21 14:32:37 +00002247 if (!res) {
2248 if (!PyErr_Occurred())
2249 err_string("invalid number of arguments for subscript node");
2250 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002251 }
Guido van Rossum47478871996-08-21 14:32:37 +00002252 if (TYPE(CHILD(tree, 0)) == DOT)
2253 /* take care of ('.' '.' '.') possibility */
2254 return (validate_numnodes(tree, 3, "subscript")
2255 && validate_dot(CHILD(tree, 0))
2256 && validate_dot(CHILD(tree, 1))
2257 && validate_dot(CHILD(tree, 2)));
2258 if (nch == 1) {
2259 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002260 res = validate_test(CHILD(tree, 0));
2261 else
Guido van Rossum47478871996-08-21 14:32:37 +00002262 res = validate_colon(CHILD(tree, 0));
2263 return (res);
2264 }
2265 /* Must be [test] ':' [test] [sliceop],
2266 * but at least one of the optional components will
2267 * be present, but we don't know which yet.
2268 */
2269 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2270 res = validate_test(CHILD(tree, 0));
2271 offset = 1;
2272 }
2273 if (res)
2274 res = validate_colon(CHILD(tree, offset));
2275 if (res) {
2276 int rem = nch - ++offset;
2277 if (rem) {
2278 if (TYPE(CHILD(tree, offset)) == test) {
2279 res = validate_test(CHILD(tree, offset));
2280 ++offset;
2281 --rem;
2282 }
2283 if (res && rem)
2284 res = validate_sliceop(CHILD(tree, offset));
2285 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002286 }
2287 return (res);
2288
2289} /* validate_subscript() */
2290
2291
Guido van Rossum47478871996-08-21 14:32:37 +00002292static int
2293validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002294 node *tree;
2295{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002296 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002297 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2298 && validate_ntype(tree, sliceop);
2299 if (!res && !PyErr_Occurred()) {
2300 validate_numnodes(tree, 1, "sliceop");
2301 res = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002302 }
Guido van Rossum47478871996-08-21 14:32:37 +00002303 if (res)
2304 res = validate_colon(CHILD(tree, 0));
2305 if (res && (nch == 2))
2306 res = validate_test(CHILD(tree, 1));
2307
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002308 return (res);
2309
Guido van Rossum47478871996-08-21 14:32:37 +00002310} /* validate_sliceop() */
2311
2312
2313static int
2314validate_exprlist(tree)
2315 node *tree;
2316{
2317 return (validate_repeating_list(tree, exprlist,
2318 validate_expr, "exprlist"));
2319
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002320} /* validate_exprlist() */
2321
2322
Guido van Rossum47478871996-08-21 14:32:37 +00002323static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002324validate_dictmaker(tree)
2325 node *tree;
2326{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002327 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002328 int res = (validate_ntype(tree, dictmaker)
2329 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002330 && validate_test(CHILD(tree, 0))
2331 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002332 && validate_test(CHILD(tree, 2)));
2333
Guido van Rossum3d602e31996-07-21 02:33:56 +00002334 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002335 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002336 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002337 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002338
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002339 if (res && (nch > 3)) {
2340 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002341 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002342 while (res && (pos < nch)) {
2343 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002344 && validate_test(CHILD(tree, pos + 1))
2345 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002346 && validate_test(CHILD(tree, pos + 3)));
2347 pos += 4;
2348 }
2349 }
2350 return (res);
2351
2352} /* validate_dictmaker() */
2353
2354
Guido van Rossum47478871996-08-21 14:32:37 +00002355static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002356validate_eval_input(tree)
2357 node *tree;
2358{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002359 int pos;
2360 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002361 int res = (validate_ntype(tree, eval_input)
2362 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002363 && validate_testlist(CHILD(tree, 0))
2364 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2365
Guido van Rossum3d602e31996-07-21 02:33:56 +00002366 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002367 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002368
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002369 return (res);
2370
2371} /* validate_eval_input() */
2372
2373
Guido van Rossum47478871996-08-21 14:32:37 +00002374static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002375validate_node(tree)
2376 node *tree;
2377{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002378 int nch = 0; /* num. children on current node */
2379 int res = 1; /* result value */
2380 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002381
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002382 while (res & (tree != 0)) {
2383 nch = NCH(tree);
2384 next = 0;
2385 switch (TYPE(tree)) {
2386 /*
2387 * Definition nodes.
2388 */
2389 case funcdef:
2390 res = validate_funcdef(tree);
2391 break;
2392 case classdef:
2393 res = validate_class(tree);
2394 break;
2395 /*
2396 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002397 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002398 */
2399 case stmt:
2400 res = validate_stmt(tree);
2401 break;
2402 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002403 /*
2404 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum925e5471997-04-02 05:32:13 +00002405 * | import_stmt | global_stmt | exec_stmt | assert_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002406 */
2407 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002408 break;
2409 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002410 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002411 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2412 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2413 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002414 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2415 if (res)
2416 next = CHILD(tree, 0);
2417 else if (nch == 1)
2418 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002419 break;
2420 /*
2421 * Compound statements.
2422 */
2423 case simple_stmt:
2424 res = validate_simple_stmt(tree);
2425 break;
2426 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002427 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002428 break;
2429 /*
2430 * Fundemental statements.
2431 */
2432 case expr_stmt:
2433 res = validate_expr_stmt(tree);
2434 break;
2435 case print_stmt:
2436 res = validate_print_stmt(tree);
2437 break;
2438 case del_stmt:
2439 res = validate_del_stmt(tree);
2440 break;
2441 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002442 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002443 && validate_name(CHILD(tree, 0), "pass"));
2444 break;
2445 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002446 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002447 && validate_name(CHILD(tree, 0), "break"));
2448 break;
2449 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002450 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002451 && validate_name(CHILD(tree, 0), "continue"));
2452 break;
2453 case return_stmt:
2454 res = validate_return_stmt(tree);
2455 break;
2456 case raise_stmt:
2457 res = validate_raise_stmt(tree);
2458 break;
2459 case import_stmt:
2460 res = validate_import_stmt(tree);
2461 break;
2462 case global_stmt:
2463 res = validate_global_stmt(tree);
2464 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002465 case exec_stmt:
2466 res = validate_exec_stmt(tree);
2467 break;
Guido van Rossum925e5471997-04-02 05:32:13 +00002468 case assert_stmt:
2469 res = validate_assert_stmt(tree);
2470 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002471 case if_stmt:
2472 res = validate_if(tree);
2473 break;
2474 case while_stmt:
2475 res = validate_while(tree);
2476 break;
2477 case for_stmt:
2478 res = validate_for(tree);
2479 break;
2480 case try_stmt:
2481 res = validate_try(tree);
2482 break;
2483 case suite:
2484 res = validate_suite(tree);
2485 break;
2486 /*
2487 * Expression nodes.
2488 */
2489 case testlist:
2490 res = validate_testlist(tree);
2491 break;
2492 case test:
2493 res = validate_test(tree);
2494 break;
2495 case and_test:
2496 res = validate_and_test(tree);
2497 break;
2498 case not_test:
2499 res = validate_not_test(tree);
2500 break;
2501 case comparison:
2502 res = validate_comparison(tree);
2503 break;
2504 case exprlist:
2505 res = validate_exprlist(tree);
2506 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002507 case comp_op:
2508 res = validate_comp_op(tree);
2509 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002510 case expr:
2511 res = validate_expr(tree);
2512 break;
2513 case xor_expr:
2514 res = validate_xor_expr(tree);
2515 break;
2516 case and_expr:
2517 res = validate_and_expr(tree);
2518 break;
2519 case shift_expr:
2520 res = validate_shift_expr(tree);
2521 break;
2522 case arith_expr:
2523 res = validate_arith_expr(tree);
2524 break;
2525 case term:
2526 res = validate_term(tree);
2527 break;
2528 case factor:
2529 res = validate_factor(tree);
2530 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002531 case power:
2532 res = validate_power(tree);
2533 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002534 case atom:
2535 res = validate_atom(tree);
2536 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002537
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002538 default:
2539 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002540 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002541 res = 0;
2542 break;
2543 }
2544 tree = next;
2545 }
2546 return (res);
2547
2548} /* validate_node() */
2549
2550
Guido van Rossum47478871996-08-21 14:32:37 +00002551static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002552validate_expr_tree(tree)
2553 node *tree;
2554{
2555 int res = validate_eval_input(tree);
2556
2557 if (!res && !PyErr_Occurred())
2558 err_string("Could not validate expression tuple.");
2559
2560 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002561
2562} /* validate_expr_tree() */
2563
2564
Guido van Rossum3d602e31996-07-21 02:33:56 +00002565/* file_input:
2566 * (NEWLINE | stmt)* ENDMARKER
2567 */
Guido van Rossum47478871996-08-21 14:32:37 +00002568static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002569validate_file_input(tree)
2570 node *tree;
2571{
2572 int j = 0;
2573 int nch = NCH(tree) - 1;
2574 int res = ((nch >= 0)
2575 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002576
Guido van Rossum3d602e31996-07-21 02:33:56 +00002577 for ( ; res && (j < nch); ++j) {
2578 if (TYPE(CHILD(tree, j)) == stmt)
2579 res = validate_stmt(CHILD(tree, j));
2580 else
2581 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002582 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002583 /* This stays in to prevent any internal failues from getting to the
2584 * user. Hopefully, this won't be needed. If a user reports getting
2585 * this, we have some debugging to do.
2586 */
2587 if (!res && !PyErr_Occurred())
2588 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2589
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002590 return (res);
2591
Guido van Rossum2a288461996-08-21 21:55:43 +00002592} /* validate_file_input() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002593
2594
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002595/* Functions exported by this module. Most of this should probably
2596 * be converted into an AST object with methods, but that is better
2597 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002598 * We'd really have to write a wrapper around it all anyway to allow
2599 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002600 */
2601static PyMethodDef parser_functions[] = {
Guido van Rossum3d602e31996-07-21 02:33:56 +00002602 {"ast2tuple", parser_ast2tuple, 1,
2603 "Creates a tuple-tree representation of an AST."},
Guido van Rossum47478871996-08-21 14:32:37 +00002604 {"ast2list", parser_ast2list, 1,
2605 "Creates a list-tree representation of an AST."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002606 {"compileast", parser_compileast, 1,
2607 "Compiles an AST object into a code object."},
2608 {"expr", parser_expr, 1,
2609 "Creates an AST object from an expression."},
2610 {"isexpr", parser_isexpr, 1,
2611 "Determines if an AST object was created from an expression."},
2612 {"issuite", parser_issuite, 1,
2613 "Determines if an AST object was created from a suite."},
2614 {"suite", parser_suite, 1,
2615 "Creates an AST object from a suite."},
Guido van Rossum47478871996-08-21 14:32:37 +00002616 {"sequence2ast", parser_tuple2ast, 1,
2617 "Creates an AST object from a tree representation."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002618 {"tuple2ast", parser_tuple2ast, 1,
Guido van Rossum47478871996-08-21 14:32:37 +00002619 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002620
2621 {0, 0, 0}
2622 };
2623
2624
Guido van Rossum52f2c051993-11-10 12:53:24 +00002625void
Guido van Rossum3d602e31996-07-21 02:33:56 +00002626initparser()
2627 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002628 PyObject* module;
2629 PyObject* dict;
2630
2631 PyAST_Type.ob_type = &PyType_Type;
2632 module = Py_InitModule("parser", parser_functions);
2633 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002634
2635 parser_error = PyString_FromString("parser.ParserError");
2636
2637 if ((parser_error == 0)
2638 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2639 /*
2640 * This is serious.
2641 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002642 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002643 }
2644 /*
2645 * Nice to have, but don't cry if we fail.
2646 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002647 Py_INCREF(&PyAST_Type);
2648 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2649
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002650 PyDict_SetItemString(dict, "__copyright__",
2651 PyString_FromString(parser_copyright_string));
2652 PyDict_SetItemString(dict, "__doc__",
2653 PyString_FromString(parser_doc_string));
2654 PyDict_SetItemString(dict, "__version__",
2655 PyString_FromString(parser_version_string));
2656
2657} /* initparser() */
2658
2659
2660/*
Guido van Rossum3d602e31996-07-21 02:33:56 +00002661 * end of parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002662 */