blob: 57fbf48018d56a866f0f8eebb27b0676e3d4e200 [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
Fred Draked49266e1997-10-09 16:29:31 +0000747 /* check_terminal_tuple() already verified it's a string */
748 strn = (char *)malloc(PyString_GET_SIZE(temp) + 1);
749 if (strn != NULL)
750 strcpy(strn, PyString_AS_STRING(temp));
Guido van Rossum47478871996-08-21 14:32:37 +0000751 Py_XDECREF(temp);
752
753 if (PyObject_Length(elem) == 3) {
754 PyObject* temp = PySequence_GetItem(elem, 2);
755 *line_num = PyInt_AsLong(temp);
756 Py_DECREF(temp);
757 }
758 }
759 else {
760 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000761 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000762 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000763 }
764 else if (!ISNONTERMINAL(type)) {
765 /*
766 * It has to be one or the other; this is an error.
767 * Throw an exception.
768 */
769 PyErr_SetObject(parser_error,
770 Py_BuildValue("(os)", elem,
771 "Unknown node type."));
Guido van Rossum47478871996-08-21 14:32:37 +0000772 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000773 return (0);
774 }
775 PyNode_AddChild(root, type, strn, *line_num);
776
777 if (ISNONTERMINAL(type)) {
778 node* new_child = CHILD(root, i - 1);
779
Guido van Rossum47478871996-08-21 14:32:37 +0000780 if (new_child != build_node_children(elem, new_child, line_num)) {
781 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000782 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000783 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000784 }
Guido van Rossum47478871996-08-21 14:32:37 +0000785 else if (type == NEWLINE) { /* It's true: we increment the */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000786 ++(*line_num); /* line number *after* the newline! */
Guido van Rossum47478871996-08-21 14:32:37 +0000787 }
788 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000789 }
790 return (root);
791
792} /* build_node_children() */
793
794
795static node*
796build_node_tree(tuple)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000797 PyObject *tuple;
Guido van Rossum47478871996-08-21 14:32:37 +0000798{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000799 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000800 PyObject *temp = PySequence_GetItem(tuple, 0);
801 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000802
Guido van Rossum47478871996-08-21 14:32:37 +0000803 if (temp != NULL)
804 num = PyInt_AsLong(temp);
805 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000806 if (ISTERMINAL(num)) {
807 /*
808 * The tuple is simple, but it doesn't start with a start symbol.
809 * Throw an exception now and be done with it.
810 */
811 tuple = Py_BuildValue("(os)", tuple,
Guido van Rossum3d602e31996-07-21 02:33:56 +0000812 "Illegal ast tuple; cannot start with terminal symbol.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000813 PyErr_SetObject(parser_error, tuple);
814 }
815 else if (ISNONTERMINAL(num)) {
816 /*
817 * Not efficient, but that can be handled later.
818 */
819 int line_num = 0;
820
821 res = PyNode_New(num);
822 if (res != build_node_children(tuple, res, &line_num)) {
823 PyNode_Free(res);
824 res = 0;
825 }
826 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000827 else
828 /* The tuple is illegal -- if the number is neither TERMINAL nor
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000829 * NONTERMINAL, we can't use it.
830 */
831 PyErr_SetObject(parser_error,
832 Py_BuildValue("(os)", tuple,
833 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000834
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000835 return (res);
836
837} /* build_node_tree() */
838
839
Guido van Rossum360a9341996-08-21 19:04:10 +0000840#ifdef HAVE_OLD_CPP
Guido van Rossum2a288461996-08-21 21:55:43 +0000841#define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000842#else
Guido van Rossum2a288461996-08-21 21:55:43 +0000843#define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000844#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000845
846
847/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000848 * Validation routines used within the validation section:
849 */
Guido van Rossum2a288461996-08-21 21:55:43 +0000850staticforward int validate_terminal Py_PROTO((node *terminal,
851 int type, char *string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000852
853#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
854#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
855#define validate_colon(ch) validate_terminal(ch, COLON, ":")
856#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
857#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
858#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000859#define validate_indent(ch) validate_terminal(ch, INDENT, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000860#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000861#define validate_newline(ch) validate_terminal(ch, NEWLINE, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000862#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
863#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
864#define validate_star(ch) validate_terminal(ch, STAR, "*")
865#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000866#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
Guido van Rossum47478871996-08-21 14:32:37 +0000867#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000868#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000869
Guido van Rossum3d602e31996-07-21 02:33:56 +0000870VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000871VALIDATER(class); VALIDATER(node);
872VALIDATER(parameters); VALIDATER(suite);
873VALIDATER(testlist); VALIDATER(varargslist);
874VALIDATER(fpdef); VALIDATER(fplist);
875VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000876VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000877VALIDATER(print_stmt); VALIDATER(del_stmt);
878VALIDATER(return_stmt);
879VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000880VALIDATER(global_stmt);
Guido van Rossum925e5471997-04-02 05:32:13 +0000881VALIDATER(assert_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000882VALIDATER(exec_stmt); VALIDATER(compound_stmt);
883VALIDATER(while); VALIDATER(for);
884VALIDATER(try); VALIDATER(except_clause);
885VALIDATER(test); VALIDATER(and_test);
886VALIDATER(not_test); VALIDATER(comparison);
887VALIDATER(comp_op); VALIDATER(expr);
888VALIDATER(xor_expr); VALIDATER(and_expr);
889VALIDATER(shift_expr); VALIDATER(arith_expr);
890VALIDATER(term); VALIDATER(factor);
891VALIDATER(atom); VALIDATER(lambdef);
892VALIDATER(trailer); VALIDATER(subscript);
Guido van Rossum47478871996-08-21 14:32:37 +0000893VALIDATER(subscriptlist); VALIDATER(sliceop);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000894VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000895VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000896
897
898#define is_even(n) (((n) & 1) == 0)
899#define is_odd(n) (((n) & 1) == 1)
900
901
902static int
903validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000904 node *n;
905 int t;
Guido van Rossum47478871996-08-21 14:32:37 +0000906{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000907 int res = (TYPE(n) == t);
908
909 if (!res) {
910 char buffer[128];
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000911 sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000912 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000913 }
914 return (res);
915
916} /* validate_ntype() */
917
918
919static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000920validate_numnodes(n, num, name)
921 node *n;
922 int num;
923 const char *const name;
Guido van Rossum47478871996-08-21 14:32:37 +0000924{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000925 if (NCH(n) != num) {
926 char buff[60];
927 sprintf(buff, "Illegal number of children for %s node.", name);
928 err_string(buff);
929 }
930 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000931
Guido van Rossum3d602e31996-07-21 02:33:56 +0000932} /* validate_numnodes() */
933
934
935static int
936validate_terminal(terminal, type, string)
937 node *terminal;
938 int type;
939 char *string;
Guido van Rossum47478871996-08-21 14:32:37 +0000940{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000941 int res = (validate_ntype(terminal, type)
942 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
943
944 if (!res && !PyErr_Occurred()) {
945 char buffer[60];
946 sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
947 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000948 }
949 return (res);
950
951} /* validate_terminal() */
952
953
Guido van Rossum47478871996-08-21 14:32:37 +0000954/* X (',' X) [',']
955 */
956static int
957validate_repeating_list(tree, ntype, vfunc, name)
958 node *tree;
959 int ntype;
960 int (*vfunc)();
961 const char *const name;
962{
963 int nch = NCH(tree);
964 int res = (nch && validate_ntype(tree, ntype)
965 && vfunc(CHILD(tree, 0)));
966
967 if (!res && !PyErr_Occurred())
968 validate_numnodes(tree, 1, name);
969 else {
970 if (is_even(nch))
971 res = validate_comma(CHILD(tree, --nch));
972 if (res && nch > 1) {
973 int pos = 1;
974 for ( ; res && pos < nch; pos += 2)
975 res = (validate_comma(CHILD(tree, pos))
976 && vfunc(CHILD(tree, pos + 1)));
977 }
978 }
979 return (res);
980
981} /* validate_repeating_list() */
982
983
Guido van Rossum3d602e31996-07-21 02:33:56 +0000984/* VALIDATE(class)
985 *
986 * classdef:
987 * 'class' NAME ['(' testlist ')'] ':' suite
988 */
Guido van Rossum47478871996-08-21 14:32:37 +0000989static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000990validate_class(tree)
991 node *tree;
992{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000993 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000994 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000995
Guido van Rossum3d602e31996-07-21 02:33:56 +0000996 if (res) {
997 res = (validate_name(CHILD(tree, 0), "class")
998 && validate_ntype(CHILD(tree, 1), NAME)
999 && validate_colon(CHILD(tree, nch - 2))
1000 && validate_suite(CHILD(tree, nch - 1)));
1001 }
1002 else
1003 validate_numnodes(tree, 4, "class");
1004 if (res && (nch == 7)) {
1005 res = (validate_lparen(CHILD(tree, 2))
1006 && validate_testlist(CHILD(tree, 3))
1007 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001008 }
1009 return (res);
1010
1011} /* validate_class() */
1012
1013
Guido van Rossum3d602e31996-07-21 02:33:56 +00001014/* if_stmt:
1015 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1016 */
Guido van Rossum47478871996-08-21 14:32:37 +00001017static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001018validate_if(tree)
1019 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001020{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001021 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001022 int res = (validate_ntype(tree, if_stmt)
1023 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001024 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +00001025 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001026 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001027 && validate_suite(CHILD(tree, 3)));
1028
1029 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001030 /* ... 'else' ':' suite */
1031 res = (validate_name(CHILD(tree, nch - 3), "else")
1032 && validate_colon(CHILD(tree, nch - 2))
1033 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001034 nch -= 3;
1035 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001036 else if (!res && !PyErr_Occurred())
1037 validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001038 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001039 /* Will catch the case for nch < 4 */
1040 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001041 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001042 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001043 int j = 4;
1044 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001045 res = (validate_name(CHILD(tree, j), "elif")
1046 && validate_colon(CHILD(tree, j + 2))
1047 && validate_test(CHILD(tree, j + 1))
1048 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001049 j += 4;
1050 }
1051 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001052 return (res);
1053
1054} /* validate_if() */
1055
1056
Guido van Rossum3d602e31996-07-21 02:33:56 +00001057/* parameters:
1058 * '(' [varargslist] ')'
1059 *
1060 */
Guido van Rossum47478871996-08-21 14:32:37 +00001061static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001062validate_parameters(tree)
1063 node *tree;
1064{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001065 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001066 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001067
Guido van Rossum3d602e31996-07-21 02:33:56 +00001068 if (res) {
1069 res = (validate_lparen(CHILD(tree, 0))
1070 && validate_rparen(CHILD(tree, nch - 1)));
1071 if (res && (nch == 3))
1072 res = validate_varargslist(CHILD(tree, 1));
1073 }
1074 else
1075 validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001076
1077 return (res);
1078
1079} /* validate_parameters() */
1080
1081
Guido van Rossum3d602e31996-07-21 02:33:56 +00001082/* VALIDATE(suite)
1083 *
1084 * suite:
1085 * simple_stmt
1086 * | NEWLINE INDENT stmt+ DEDENT
1087 */
Guido van Rossum47478871996-08-21 14:32:37 +00001088static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001089validate_suite(tree)
1090 node *tree;
1091{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001092 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001093 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001094
Guido van Rossum3d602e31996-07-21 02:33:56 +00001095 if (res && (nch == 1))
1096 res = validate_simple_stmt(CHILD(tree, 0));
1097 else if (res) {
1098 /* NEWLINE INDENT stmt+ DEDENT */
1099 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001100 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001101 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001102 && validate_dedent(CHILD(tree, nch - 1)));
1103
Guido van Rossum3d602e31996-07-21 02:33:56 +00001104 if (res && (nch > 4)) {
1105 int i = 3;
1106 --nch; /* forget the DEDENT */
1107 for ( ; res && (i < nch); ++i)
1108 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001109 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001110 else if (nch < 4)
1111 validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001112 }
1113 return (res);
1114
1115} /* validate_suite() */
1116
1117
Guido van Rossum47478871996-08-21 14:32:37 +00001118static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001119validate_testlist(tree)
1120 node *tree;
1121{
Guido van Rossum47478871996-08-21 14:32:37 +00001122 return (validate_repeating_list(tree, testlist,
1123 validate_test, "testlist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001124
1125} /* validate_testlist() */
1126
1127
Guido van Rossum3d602e31996-07-21 02:33:56 +00001128/* VALIDATE(varargslist)
1129 *
1130 * varargslist:
1131 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1132 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1133 *
1134 * (fpdef ['=' test] ',')*
1135 * ('*' NAME [',' ('**'|'*' '*') NAME]
1136 * | ('**'|'*' '*') NAME)
1137 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1138 *
1139 */
Guido van Rossum47478871996-08-21 14:32:37 +00001140static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001141validate_varargslist(tree)
1142 node *tree;
1143{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001144 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001145 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001146
Guido van Rossum3d602e31996-07-21 02:33:56 +00001147 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1148 /* (fpdef ['=' test] ',')*
1149 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1150 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001151 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001152 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001153
Guido van Rossum3d602e31996-07-21 02:33:56 +00001154 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1155 res = validate_fpdef(CHILD(tree, pos));
1156 if (res) {
1157 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1158 res = validate_test(CHILD(tree, pos + 2));
1159 pos += 2;
1160 }
1161 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001162 pos += 2;
1163 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001164 }
1165 if (res) {
1166 remaining = nch - pos;
1167 res = ((remaining == 2) || (remaining == 3)
1168 || (remaining == 5) || (remaining == 6));
1169 if (!res)
1170 validate_numnodes(tree, 2, "varargslist");
1171 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1172 return ((remaining == 2)
1173 && validate_ntype(CHILD(tree, pos+1), NAME));
1174 else {
1175 res = validate_star(CHILD(tree, pos++));
1176 --remaining;
1177 }
1178 }
1179 if (res) {
1180 if (remaining == 2) {
1181 res = (validate_star(CHILD(tree, pos))
1182 && validate_ntype(CHILD(tree, pos + 1), NAME));
1183 }
1184 else {
1185 res = validate_ntype(CHILD(tree, pos++), NAME);
1186 if (res && (remaining >= 4)) {
1187 res = validate_comma(CHILD(tree, pos));
1188 if (--remaining == 3)
Fred Drakee1607a81996-09-11 21:58:26 +00001189 res = (validate_star(CHILD(tree, pos + 1))
1190 && validate_star(CHILD(tree, pos + 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001191 else
1192 validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1193 }
1194 }
1195 }
1196 if (!res && !PyErr_Occurred())
1197 err_string("Incorrect validation of variable arguments list.");
1198 }
1199 else if (res) {
1200 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1201 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1202 --nch;
1203
1204 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1205 res = (is_odd(nch)
1206 && validate_fpdef(CHILD(tree, 0)));
1207
1208 if (res && (nch > 1)) {
1209 int pos = 1;
1210 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1211 res = validate_test(CHILD(tree, 2));
1212 pos += 2;
1213 }
1214 /* ... (',' fpdef ['=' test])* */
1215 for ( ; res && (pos < nch); pos += 2) {
1216 /* ',' fpdef */
1217 res = (validate_comma(CHILD(tree, pos))
1218 && validate_fpdef(CHILD(tree, pos + 1)));
1219 if (res
1220 && ((nch - pos) > 2)
1221 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1222 /* ['=' test] */
1223 res = validate_test(CHILD(tree, pos + 3));
1224 pos += 2;
1225 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001226 }
1227 }
1228 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001229 else
1230 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001231
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001232 return (res);
1233
1234} /* validate_varargslist() */
1235
1236
Guido van Rossum3d602e31996-07-21 02:33:56 +00001237/* VALIDATE(fpdef)
1238 *
1239 * fpdef:
1240 * NAME
1241 * | '(' fplist ')'
1242 */
Guido van Rossum47478871996-08-21 14:32:37 +00001243static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001244validate_fpdef(tree)
1245 node *tree;
1246{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001247 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001248 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001249
Guido van Rossum3d602e31996-07-21 02:33:56 +00001250 if (res) {
1251 if (nch == 1)
1252 res = validate_ntype(CHILD(tree, 0), NAME);
1253 else if (nch == 3)
1254 res = (validate_lparen(CHILD(tree, 0))
1255 && validate_fplist(CHILD(tree, 1))
1256 && validate_rparen(CHILD(tree, 2)));
1257 else
1258 validate_numnodes(tree, 1, "fpdef");
1259 }
1260 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001261
1262} /* validate_fpdef() */
1263
1264
Guido van Rossum47478871996-08-21 14:32:37 +00001265static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001266validate_fplist(tree)
1267 node *tree;
1268{
Guido van Rossum47478871996-08-21 14:32:37 +00001269 return (validate_repeating_list(tree, fplist,
1270 validate_fpdef, "fplist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001271
1272} /* validate_fplist() */
1273
1274
Guido van Rossum3d602e31996-07-21 02:33:56 +00001275/* simple_stmt | compound_stmt
1276 *
1277 */
Guido van Rossum47478871996-08-21 14:32:37 +00001278static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001279validate_stmt(tree)
1280 node *tree;
1281{
1282 int res = (validate_ntype(tree, stmt)
1283 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001284
Guido van Rossum3d602e31996-07-21 02:33:56 +00001285 if (res) {
1286 tree = CHILD(tree, 0);
1287
1288 if (TYPE(tree) == simple_stmt)
1289 res = validate_simple_stmt(tree);
1290 else
1291 res = validate_compound_stmt(tree);
1292 }
1293 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001294
1295} /* validate_stmt() */
1296
1297
Guido van Rossum3d602e31996-07-21 02:33:56 +00001298/* small_stmt (';' small_stmt)* [';'] NEWLINE
1299 *
1300 */
Guido van Rossum47478871996-08-21 14:32:37 +00001301static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001302validate_simple_stmt(tree)
1303 node *tree;
1304{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001305 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001306 int res = (validate_ntype(tree, simple_stmt)
1307 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001308 && validate_small_stmt(CHILD(tree, 0))
1309 && validate_newline(CHILD(tree, nch - 1)));
1310
Guido van Rossum3d602e31996-07-21 02:33:56 +00001311 if (nch < 2)
1312 res = validate_numnodes(tree, 2, "simple_stmt");
1313 --nch; /* forget the NEWLINE */
1314 if (res && is_even(nch))
1315 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001316 if (res && (nch > 2)) {
1317 int i;
1318
Guido van Rossum3d602e31996-07-21 02:33:56 +00001319 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001320 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001321 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001322 }
1323 return (res);
1324
1325} /* validate_simple_stmt() */
1326
1327
Guido van Rossum47478871996-08-21 14:32:37 +00001328static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001329validate_small_stmt(tree)
1330 node *tree;
1331{
1332 int nch = NCH(tree);
1333 int res = (validate_numnodes(tree, 1, "small_stmt")
1334 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1335 || (TYPE(CHILD(tree, 0)) == print_stmt)
1336 || (TYPE(CHILD(tree, 0)) == del_stmt)
1337 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1338 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1339 || (TYPE(CHILD(tree, 0)) == import_stmt)
1340 || (TYPE(CHILD(tree, 0)) == global_stmt)
Guido van Rossum925e5471997-04-02 05:32:13 +00001341 || (TYPE(CHILD(tree, 0)) == assert_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001342 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1343
1344 if (res)
1345 res = validate_node(CHILD(tree, 0));
1346 else if (nch == 1) {
1347 char buffer[60];
1348 sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1349 TYPE(CHILD(tree, 0)));
1350 err_string(buffer);
1351 }
1352 return (res);
1353
1354} /* validate_small_stmt */
1355
1356
1357/* compound_stmt:
1358 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1359 */
Guido van Rossum47478871996-08-21 14:32:37 +00001360static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001361validate_compound_stmt(tree)
1362 node *tree;
1363{
1364 int res = (validate_ntype(tree, compound_stmt)
1365 && validate_numnodes(tree, 1, "compound_stmt"));
1366
1367 if (!res)
1368 return (0);
1369
1370 tree = CHILD(tree, 0);
1371 res = ((TYPE(tree) == if_stmt)
1372 || (TYPE(tree) == while_stmt)
1373 || (TYPE(tree) == for_stmt)
1374 || (TYPE(tree) == try_stmt)
1375 || (TYPE(tree) == funcdef)
1376 || (TYPE(tree) == classdef));
1377 if (res)
1378 res = validate_node(tree);
1379 else {
1380 char buffer[60];
1381 sprintf(buffer, "Illegal compound statement type: %d.", TYPE(tree));
1382 err_string(buffer);
1383 }
1384 return (res);
1385
1386} /* validate_compound_stmt() */
1387
1388
Guido van Rossum47478871996-08-21 14:32:37 +00001389static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001390validate_expr_stmt(tree)
1391 node *tree;
1392{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001393 int j;
1394 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001395 int res = (validate_ntype(tree, expr_stmt)
1396 && is_odd(nch)
1397 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001398
Guido van Rossum3d602e31996-07-21 02:33:56 +00001399 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001400 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001401 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001402
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001403 return (res);
1404
1405} /* validate_expr_stmt() */
1406
1407
Guido van Rossum3d602e31996-07-21 02:33:56 +00001408/* print_stmt:
1409 *
1410 * 'print' (test ',')* [test]
1411 *
1412 */
Guido van Rossum47478871996-08-21 14:32:37 +00001413static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001414validate_print_stmt(tree)
1415 node *tree;
1416{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001417 int j;
1418 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001419 int res = (validate_ntype(tree, print_stmt)
1420 && (nch != 0)
1421 && validate_name(CHILD(tree, 0), "print"));
1422
1423 if (res && is_even(nch)) {
1424 res = validate_test(CHILD(tree, nch - 1));
1425 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001426 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001427 else if (!res && !PyErr_Occurred())
1428 validate_numnodes(tree, 1, "print_stmt");
1429 for (j = 1; res && (j < nch); j += 2)
1430 res = (validate_test(CHILD(tree, j))
1431 && validate_ntype(CHILD(tree, j + 1), COMMA));
1432
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001433 return (res);
1434
1435} /* validate_print_stmt() */
1436
1437
Guido van Rossum47478871996-08-21 14:32:37 +00001438static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001439validate_del_stmt(tree)
1440 node *tree;
1441{
1442 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001443 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001444 && validate_exprlist(CHILD(tree, 1)));
1445
1446} /* validate_del_stmt() */
1447
1448
Guido van Rossum47478871996-08-21 14:32:37 +00001449static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001450validate_return_stmt(tree)
1451 node *tree;
1452{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001453 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001454 int res = (validate_ntype(tree, return_stmt)
1455 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001456 && validate_name(CHILD(tree, 0), "return"));
1457
Guido van Rossum3d602e31996-07-21 02:33:56 +00001458 if (res && (nch == 2))
1459 res = validate_testlist(CHILD(tree, 1));
1460
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001461 return (res);
1462
1463} /* validate_return_stmt() */
1464
1465
Guido van Rossum47478871996-08-21 14:32:37 +00001466static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001467validate_raise_stmt(tree)
1468 node *tree;
1469{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001470 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001471 int res = (validate_ntype(tree, raise_stmt)
Fred Drakec542bc71998-04-10 04:43:28 +00001472 && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001473
Guido van Rossum3d602e31996-07-21 02:33:56 +00001474 if (res) {
Fred Drakec542bc71998-04-10 04:43:28 +00001475 res = validate_name(CHILD(tree, 0), "raise");
1476 if (res && (nch >= 2))
1477 res = validate_test(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001478 if (res && nch > 2) {
1479 res = (validate_comma(CHILD(tree, 2))
1480 && validate_test(CHILD(tree, 3)));
1481 if (res && (nch > 4))
1482 res = (validate_comma(CHILD(tree, 4))
1483 && validate_test(CHILD(tree, 5)));
1484 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001485 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001486 else
1487 validate_numnodes(tree, 2, "raise");
1488 if (res && (nch == 4))
1489 res = (validate_comma(CHILD(tree, 2))
1490 && validate_test(CHILD(tree, 3)));
1491
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001492 return (res);
1493
1494} /* validate_raise_stmt() */
1495
1496
Guido van Rossum3d602e31996-07-21 02:33:56 +00001497/* import_stmt:
1498 *
1499 * 'import' dotted_name (',' dotted_name)*
1500 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1501 */
Guido van Rossum47478871996-08-21 14:32:37 +00001502static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001503validate_import_stmt(tree)
1504 node *tree;
1505{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001506 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001507 int res = (validate_ntype(tree, import_stmt)
1508 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001509 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001510 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001511
1512 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001513 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001514
Guido van Rossum3d602e31996-07-21 02:33:56 +00001515 for (j = 2; res && (j < nch); j += 2)
1516 res = (validate_comma(CHILD(tree, j))
1517 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001518 }
1519 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001520 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001521 && validate_name(CHILD(tree, 2), "import"));
1522 if (nch == 4) {
1523 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001524 || (TYPE(CHILD(tree, 3)) == STAR));
1525 if (!res)
1526 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001527 }
1528 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001529 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001530 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001531 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001532 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001533 res = (validate_comma(CHILD(tree, j))
1534 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001535 }
1536 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001537 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001538 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001539
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001540 return (res);
1541
1542} /* validate_import_stmt() */
1543
1544
Guido van Rossum47478871996-08-21 14:32:37 +00001545static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001546validate_global_stmt(tree)
1547 node *tree;
1548{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001549 int j;
1550 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001551 int res = (validate_ntype(tree, global_stmt)
1552 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001553
Guido van Rossum3d602e31996-07-21 02:33:56 +00001554 if (res)
1555 res = (validate_name(CHILD(tree, 0), "global")
1556 && validate_ntype(CHILD(tree, 1), NAME));
1557 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001558 res = (validate_comma(CHILD(tree, j))
1559 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001560
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001561 return (res);
1562
1563} /* validate_global_stmt() */
1564
1565
Guido van Rossum3d602e31996-07-21 02:33:56 +00001566/* exec_stmt:
1567 *
1568 * 'exec' expr ['in' test [',' test]]
1569 */
Guido van Rossum47478871996-08-21 14:32:37 +00001570static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001571validate_exec_stmt(tree)
1572 node *tree;
1573{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001574 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001575 int res = (validate_ntype(tree, exec_stmt)
1576 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001577 && validate_name(CHILD(tree, 0), "exec")
1578 && validate_expr(CHILD(tree, 1)));
1579
Guido van Rossum3d602e31996-07-21 02:33:56 +00001580 if (!res && !PyErr_Occurred())
1581 err_string("Illegal exec statement.");
1582 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001583 res = (validate_name(CHILD(tree, 2), "in")
1584 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001585 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001586 res = (validate_comma(CHILD(tree, 4))
1587 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001588
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001589 return (res);
1590
1591} /* validate_exec_stmt() */
1592
1593
Guido van Rossum925e5471997-04-02 05:32:13 +00001594/* assert_stmt:
1595 *
1596 * 'assert' test [',' test]
1597 */
1598static int
1599validate_assert_stmt(tree)
1600 node *tree;
1601{
1602 int nch = NCH(tree);
1603 int res = (validate_ntype(tree, assert_stmt)
1604 && ((nch == 2) || (nch == 4))
1605 && (validate_name(CHILD(tree, 0), "__assert__") ||
1606 validate_name(CHILD(tree, 0), "assert"))
1607 && validate_test(CHILD(tree, 1)));
1608
1609 if (!res && !PyErr_Occurred())
1610 err_string("Illegal assert statement.");
1611 if (res && (nch > 2))
1612 res = (validate_comma(CHILD(tree, 2))
1613 && validate_test(CHILD(tree, 3)));
1614
1615 return (res);
1616
1617} /* validate_assert_stmt() */
1618
1619
Guido van Rossum47478871996-08-21 14:32:37 +00001620static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001621validate_while(tree)
1622 node *tree;
1623{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001624 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001625 int res = (validate_ntype(tree, while_stmt)
1626 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001627 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001628 && validate_test(CHILD(tree, 1))
1629 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001630 && validate_suite(CHILD(tree, 3)));
1631
Guido van Rossum3d602e31996-07-21 02:33:56 +00001632 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001633 res = (validate_name(CHILD(tree, 4), "else")
1634 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001635 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001636
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001637 return (res);
1638
1639} /* validate_while() */
1640
1641
Guido van Rossum47478871996-08-21 14:32:37 +00001642static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001643validate_for(tree)
1644 node *tree;
1645{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001646 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001647 int res = (validate_ntype(tree, for_stmt)
1648 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001649 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001650 && validate_exprlist(CHILD(tree, 1))
1651 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001652 && validate_testlist(CHILD(tree, 3))
1653 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001654 && validate_suite(CHILD(tree, 5)));
1655
Guido van Rossum3d602e31996-07-21 02:33:56 +00001656 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001657 res = (validate_name(CHILD(tree, 6), "else")
1658 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001659 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001660
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001661 return (res);
1662
1663} /* validate_for() */
1664
1665
Guido van Rossum3d602e31996-07-21 02:33:56 +00001666/* try_stmt:
1667 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1668 * | 'try' ':' suite 'finally' ':' suite
1669 *
1670 */
Guido van Rossum47478871996-08-21 14:32:37 +00001671static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001672validate_try(tree)
1673 node *tree;
1674{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001675 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001676 int pos = 3;
1677 int res = (validate_ntype(tree, try_stmt)
1678 && (nch >= 6) && ((nch % 3) == 0));
1679
1680 if (res)
1681 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001682 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001683 && validate_suite(CHILD(tree, 2))
1684 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001685 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001686 else {
1687 const char* name = "execpt";
1688 char buffer[60];
1689 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1690 name = STR(CHILD(tree, nch - 3));
1691 sprintf(buffer, "Illegal number of children for try/%s node.", name);
1692 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001693 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001694 /* Skip past except_clause sections: */
1695 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1696 res = (validate_except_clause(CHILD(tree, pos))
1697 && validate_colon(CHILD(tree, pos + 1))
1698 && validate_suite(CHILD(tree, pos + 2)));
1699 pos += 3;
1700 }
1701 if (res && (pos < nch)) {
1702 res = validate_ntype(CHILD(tree, pos), NAME);
1703 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1704 res = (validate_numnodes(tree, 6, "try/finally")
1705 && validate_colon(CHILD(tree, 4))
1706 && validate_suite(CHILD(tree, 5)));
Guido van Rossum730806d1998-04-10 22:27:42 +00001707 else if (res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001708 if (nch == (pos + 3)) {
1709 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1710 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1711 if (!res)
1712 err_string("Illegal trailing triple in try statement.");
1713 }
Guido van Rossum730806d1998-04-10 22:27:42 +00001714 else if (nch == (pos + 6)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001715 res = (validate_name(CHILD(tree, pos), "except")
1716 && validate_colon(CHILD(tree, pos + 1))
1717 && validate_suite(CHILD(tree, pos + 2))
1718 && validate_name(CHILD(tree, pos + 3), "else"));
Guido van Rossum730806d1998-04-10 22:27:42 +00001719 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001720 else
1721 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossum730806d1998-04-10 22:27:42 +00001722 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001723 }
1724 return (res);
1725
1726} /* validate_try() */
1727
1728
Guido van Rossum47478871996-08-21 14:32:37 +00001729static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001730validate_except_clause(tree)
1731 node *tree;
1732{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001733 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001734 int res = (validate_ntype(tree, except_clause)
1735 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001736 && validate_name(CHILD(tree, 0), "except"));
1737
Guido van Rossum3d602e31996-07-21 02:33:56 +00001738 if (res && (nch > 1))
1739 res = validate_test(CHILD(tree, 1));
1740 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001741 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001742 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001743
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001744 return (res);
1745
1746} /* validate_except_clause() */
1747
1748
Guido van Rossum47478871996-08-21 14:32:37 +00001749static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001750validate_test(tree)
1751 node *tree;
1752{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001753 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001754 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001755
Guido van Rossum3d602e31996-07-21 02:33:56 +00001756 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001757 res = ((nch == 1)
1758 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001759 else if (res) {
1760 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001761 res = validate_and_test(CHILD(tree, 0));
1762 for (pos = 1; res && (pos < nch); pos += 2)
1763 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001764 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001765 }
1766 return (res);
1767
1768} /* validate_test() */
1769
1770
Guido van Rossum47478871996-08-21 14:32:37 +00001771static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001772validate_and_test(tree)
1773 node *tree;
1774{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001775 int pos;
1776 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001777 int res = (validate_ntype(tree, and_test)
1778 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001779 && validate_not_test(CHILD(tree, 0)));
1780
Guido van Rossum3d602e31996-07-21 02:33:56 +00001781 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001782 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001783 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001784
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001785 return (res);
1786
1787} /* validate_and_test() */
1788
1789
Guido van Rossum47478871996-08-21 14:32:37 +00001790static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001791validate_not_test(tree)
1792 node *tree;
1793{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001794 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001795 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001796
Guido van Rossum3d602e31996-07-21 02:33:56 +00001797 if (res) {
1798 if (nch == 2)
1799 res = (validate_name(CHILD(tree, 0), "not")
1800 && validate_not_test(CHILD(tree, 1)));
1801 else if (nch == 1)
1802 res = validate_comparison(CHILD(tree, 0));
1803 }
1804 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001805
1806} /* validate_not_test() */
1807
1808
Guido van Rossum47478871996-08-21 14:32:37 +00001809static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001810validate_comparison(tree)
1811 node *tree;
1812{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001813 int pos;
1814 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001815 int res = (validate_ntype(tree, comparison)
1816 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001817 && validate_expr(CHILD(tree, 0)));
1818
Guido van Rossum3d602e31996-07-21 02:33:56 +00001819 for (pos = 1; res && (pos < nch); pos += 2)
1820 res = (validate_comp_op(CHILD(tree, pos))
1821 && validate_expr(CHILD(tree, pos + 1)));
1822
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001823 return (res);
1824
1825} /* validate_comparison() */
1826
1827
Guido van Rossum47478871996-08-21 14:32:37 +00001828static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001829validate_comp_op(tree)
1830 node *tree;
1831{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001832 int res = 0;
1833 int nch = NCH(tree);
1834
Guido van Rossum3d602e31996-07-21 02:33:56 +00001835 if (!validate_ntype(tree, comp_op))
1836 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001837 if (nch == 1) {
1838 /*
1839 * Only child will be a terminal with a well-defined symbolic name
1840 * or a NAME with a string of either 'is' or 'in'
1841 */
1842 tree = CHILD(tree, 0);
1843 switch (TYPE(tree)) {
1844 case LESS:
1845 case GREATER:
1846 case EQEQUAL:
1847 case EQUAL:
1848 case LESSEQUAL:
1849 case GREATEREQUAL:
1850 case NOTEQUAL:
1851 res = 1;
1852 break;
1853 case NAME:
1854 res = ((strcmp(STR(tree), "in") == 0)
1855 || (strcmp(STR(tree), "is") == 0));
1856 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001857 char buff[128];
1858 sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1859 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001860 }
1861 break;
1862 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001863 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001864 break;
1865 }
1866 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001867 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001868 res = (validate_ntype(CHILD(tree, 0), NAME)
1869 && validate_ntype(CHILD(tree, 1), NAME)
1870 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1871 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1872 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1873 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001874 if (!res && !PyErr_Occurred())
1875 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001876 }
1877 return (res);
1878
1879} /* validate_comp_op() */
1880
1881
Guido van Rossum47478871996-08-21 14:32:37 +00001882static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001883validate_expr(tree)
1884 node *tree;
1885{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001886 int j;
1887 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001888 int res = (validate_ntype(tree, expr)
1889 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001890 && validate_xor_expr(CHILD(tree, 0)));
1891
Guido van Rossum3d602e31996-07-21 02:33:56 +00001892 for (j = 2; res && (j < nch); j += 2)
1893 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001894 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001895
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001896 return (res);
1897
1898} /* validate_expr() */
1899
1900
Guido van Rossum47478871996-08-21 14:32:37 +00001901static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001902validate_xor_expr(tree)
1903 node *tree;
1904{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001905 int j;
1906 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001907 int res = (validate_ntype(tree, xor_expr)
1908 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001909 && validate_and_expr(CHILD(tree, 0)));
1910
Guido van Rossum3d602e31996-07-21 02:33:56 +00001911 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001912 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001913 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001914
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001915 return (res);
1916
1917} /* validate_xor_expr() */
1918
1919
Guido van Rossum47478871996-08-21 14:32:37 +00001920static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001921validate_and_expr(tree)
1922 node *tree;
1923{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001924 int pos;
1925 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001926 int res = (validate_ntype(tree, and_expr)
1927 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001928 && validate_shift_expr(CHILD(tree, 0)));
1929
Guido van Rossum3d602e31996-07-21 02:33:56 +00001930 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001931 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001932 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001933
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001934 return (res);
1935
1936} /* validate_and_expr() */
1937
1938
1939static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001940validate_chain_two_ops(tree, termvalid, op1, op2)
1941 node *tree;
1942 int (*termvalid)();
1943 int op1;
1944 int op2;
1945 {
1946 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001947 int nch = NCH(tree);
1948 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001949 && (*termvalid)(CHILD(tree, 0)));
1950
Guido van Rossum3d602e31996-07-21 02:33:56 +00001951 for ( ; res && (pos < nch); pos += 2) {
1952 if (TYPE(CHILD(tree, pos)) != op1)
1953 res = validate_ntype(CHILD(tree, pos), op2);
1954 if (res)
1955 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001956 }
1957 return (res);
1958
1959} /* validate_chain_two_ops() */
1960
1961
Guido van Rossum47478871996-08-21 14:32:37 +00001962static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001963validate_shift_expr(tree)
1964 node *tree;
1965{
1966 return (validate_ntype(tree, shift_expr)
1967 && validate_chain_two_ops(tree, validate_arith_expr,
1968 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001969
1970} /* validate_shift_expr() */
1971
1972
Guido van Rossum47478871996-08-21 14:32:37 +00001973static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001974validate_arith_expr(tree)
1975 node *tree;
1976{
1977 return (validate_ntype(tree, arith_expr)
1978 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001979
1980} /* validate_arith_expr() */
1981
1982
Guido van Rossum47478871996-08-21 14:32:37 +00001983static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001984validate_term(tree)
1985 node *tree;
1986{
1987 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001988 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001989 int res = (validate_ntype(tree, term)
1990 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001991 && validate_factor(CHILD(tree, 0)));
1992
Guido van Rossum3d602e31996-07-21 02:33:56 +00001993 for ( ; res && (pos < nch); pos += 2)
1994 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001995 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001996 || (TYPE(CHILD(tree, pos)) == PERCENT))
1997 && validate_factor(CHILD(tree, pos + 1)));
1998
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001999 return (res);
2000
2001} /* validate_term() */
2002
2003
Guido van Rossum3d602e31996-07-21 02:33:56 +00002004/* factor:
2005 *
2006 * factor: ('+'|'-'|'~') factor | power
2007 */
Guido van Rossum47478871996-08-21 14:32:37 +00002008static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002009validate_factor(tree)
2010 node *tree;
2011{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002012 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002013 int res = (validate_ntype(tree, factor)
2014 && (((nch == 2)
2015 && ((TYPE(CHILD(tree, 0)) == PLUS)
2016 || (TYPE(CHILD(tree, 0)) == MINUS)
2017 || (TYPE(CHILD(tree, 0)) == TILDE))
2018 && validate_factor(CHILD(tree, 1)))
2019 || ((nch == 1)
2020 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002021 return (res);
2022
2023} /* validate_factor() */
2024
2025
Guido van Rossum3d602e31996-07-21 02:33:56 +00002026/* power:
2027 *
2028 * power: atom trailer* ('**' factor)*
2029 */
Guido van Rossum47478871996-08-21 14:32:37 +00002030static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002031validate_power(tree)
2032 node *tree;
2033{
2034 int pos = 1;
2035 int nch = NCH(tree);
2036 int res = (validate_ntype(tree, power) && (nch >= 1)
2037 && validate_atom(CHILD(tree, 0)));
2038
2039 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2040 res = validate_trailer(CHILD(tree, pos++));
2041 if (res && (pos < nch)) {
2042 if (!is_even(nch - pos)) {
2043 err_string("Illegal number of nodes for 'power'.");
2044 return (0);
2045 }
2046 for ( ; res && (pos < (nch - 1)); pos += 2)
2047 res = (validate_doublestar(CHILD(tree, pos))
2048 && validate_factor(CHILD(tree, pos + 1)));
2049 }
2050 return (res);
2051
2052} /* validate_power() */
2053
2054
Guido van Rossum47478871996-08-21 14:32:37 +00002055static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002056validate_atom(tree)
2057 node *tree;
2058{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002059 int pos;
2060 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002061 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002062
2063 if (res) {
2064 switch (TYPE(CHILD(tree, 0))) {
2065 case LPAR:
2066 res = ((nch <= 3)
2067 && (validate_rparen(CHILD(tree, nch - 1))));
2068
Guido van Rossum3d602e31996-07-21 02:33:56 +00002069 if (res && (nch == 3))
2070 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002071 break;
2072 case LSQB:
2073 res = ((nch <= 3)
2074 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2075
Guido van Rossum3d602e31996-07-21 02:33:56 +00002076 if (res && (nch == 3))
2077 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002078 break;
2079 case LBRACE:
2080 res = ((nch <= 3)
2081 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2082
Guido van Rossum3d602e31996-07-21 02:33:56 +00002083 if (res && (nch == 3))
2084 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002085 break;
2086 case BACKQUOTE:
2087 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002088 && validate_testlist(CHILD(tree, 1))
2089 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2090 break;
2091 case NAME:
2092 case NUMBER:
2093 res = (nch == 1);
2094 break;
2095 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002096 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002097 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002098 break;
2099 default:
2100 res = 0;
2101 break;
2102 }
2103 }
2104 return (res);
2105
2106} /* validate_atom() */
2107
2108
Guido van Rossum3d602e31996-07-21 02:33:56 +00002109/* funcdef:
2110 * 'def' NAME parameters ':' suite
2111 *
2112 */
Guido van Rossum47478871996-08-21 14:32:37 +00002113static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002114validate_funcdef(tree)
2115 node *tree;
2116{
2117 return (validate_ntype(tree, funcdef)
2118 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002119 && validate_name(CHILD(tree, 0), "def")
2120 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002121 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002122 && validate_parameters(CHILD(tree, 2))
2123 && validate_suite(CHILD(tree, 4)));
2124
2125} /* validate_funcdef() */
2126
2127
Guido van Rossum47478871996-08-21 14:32:37 +00002128static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002129validate_lambdef(tree)
2130 node *tree;
2131{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002132 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002133 int res = (validate_ntype(tree, lambdef)
2134 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002135 && validate_name(CHILD(tree, 0), "lambda")
2136 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002137 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002138
Guido van Rossum3d602e31996-07-21 02:33:56 +00002139 if (res && (nch == 4))
2140 res = validate_varargslist(CHILD(tree, 1));
2141 else if (!res && !PyErr_Occurred())
2142 validate_numnodes(tree, 3, "lambdef");
2143
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002144 return (res);
2145
2146} /* validate_lambdef() */
2147
2148
Guido van Rossum3d602e31996-07-21 02:33:56 +00002149/* arglist:
2150 *
2151 * argument (',' argument)* [',']
2152 */
Guido van Rossum47478871996-08-21 14:32:37 +00002153static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002154validate_arglist(tree)
2155 node *tree;
2156{
Guido van Rossum47478871996-08-21 14:32:37 +00002157 return (validate_repeating_list(tree, arglist,
2158 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002159
2160} /* validate_arglist() */
2161
2162
2163
2164/* argument:
2165 *
2166 * [test '='] test
2167 */
Guido van Rossum47478871996-08-21 14:32:37 +00002168static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002169validate_argument(tree)
2170 node *tree;
2171{
2172 int nch = NCH(tree);
2173 int res = (validate_ntype(tree, argument)
2174 && ((nch == 1) || (nch == 3))
2175 && validate_test(CHILD(tree, 0)));
2176
2177 if (res && (nch == 3))
2178 res = (validate_equal(CHILD(tree, 1))
2179 && validate_test(CHILD(tree, 2)));
2180
2181 return (res);
2182
2183} /* validate_argument() */
2184
2185
2186
2187/* trailer:
2188 *
Guido van Rossum47478871996-08-21 14:32:37 +00002189 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002190 */
Guido van Rossum47478871996-08-21 14:32:37 +00002191static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002192validate_trailer(tree)
2193 node *tree;
2194{
2195 int nch = NCH(tree);
2196 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002197
2198 if (res) {
2199 switch (TYPE(CHILD(tree, 0))) {
2200 case LPAR:
2201 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002202 if (res && (nch == 3))
2203 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002204 break;
2205 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002206 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002207 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002208 && validate_ntype(CHILD(tree, 2), RSQB));
2209 break;
2210 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002211 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002212 && validate_ntype(CHILD(tree, 1), NAME));
2213 break;
2214 default:
2215 res = 0;
2216 break;
2217 }
2218 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002219 else
2220 validate_numnodes(tree, 2, "trailer");
2221
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002222 return (res);
2223
2224} /* validate_trailer() */
2225
2226
Guido van Rossum47478871996-08-21 14:32:37 +00002227/* subscriptlist:
2228 *
2229 * subscript (',' subscript)* [',']
2230 */
2231static int
2232validate_subscriptlist(tree)
2233 node *tree;
2234{
2235 return (validate_repeating_list(tree, subscriptlist,
2236 validate_subscript, "subscriptlist"));
2237
2238} /* validate_subscriptlist() */
2239
2240
Guido van Rossum3d602e31996-07-21 02:33:56 +00002241/* subscript:
2242 *
Guido van Rossum47478871996-08-21 14:32:37 +00002243 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002244 */
Guido van Rossum47478871996-08-21 14:32:37 +00002245static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002246validate_subscript(tree)
2247 node *tree;
2248{
Guido van Rossum47478871996-08-21 14:32:37 +00002249 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002250 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002251 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002252
Guido van Rossum47478871996-08-21 14:32:37 +00002253 if (!res) {
2254 if (!PyErr_Occurred())
2255 err_string("invalid number of arguments for subscript node");
2256 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002257 }
Guido van Rossum47478871996-08-21 14:32:37 +00002258 if (TYPE(CHILD(tree, 0)) == DOT)
2259 /* take care of ('.' '.' '.') possibility */
2260 return (validate_numnodes(tree, 3, "subscript")
2261 && validate_dot(CHILD(tree, 0))
2262 && validate_dot(CHILD(tree, 1))
2263 && validate_dot(CHILD(tree, 2)));
2264 if (nch == 1) {
2265 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002266 res = validate_test(CHILD(tree, 0));
2267 else
Guido van Rossum47478871996-08-21 14:32:37 +00002268 res = validate_colon(CHILD(tree, 0));
2269 return (res);
2270 }
2271 /* Must be [test] ':' [test] [sliceop],
2272 * but at least one of the optional components will
2273 * be present, but we don't know which yet.
2274 */
2275 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2276 res = validate_test(CHILD(tree, 0));
2277 offset = 1;
2278 }
2279 if (res)
2280 res = validate_colon(CHILD(tree, offset));
2281 if (res) {
2282 int rem = nch - ++offset;
2283 if (rem) {
2284 if (TYPE(CHILD(tree, offset)) == test) {
2285 res = validate_test(CHILD(tree, offset));
2286 ++offset;
2287 --rem;
2288 }
2289 if (res && rem)
2290 res = validate_sliceop(CHILD(tree, offset));
2291 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002292 }
2293 return (res);
2294
2295} /* validate_subscript() */
2296
2297
Guido van Rossum47478871996-08-21 14:32:37 +00002298static int
2299validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002300 node *tree;
2301{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002302 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002303 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2304 && validate_ntype(tree, sliceop);
2305 if (!res && !PyErr_Occurred()) {
2306 validate_numnodes(tree, 1, "sliceop");
2307 res = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002308 }
Guido van Rossum47478871996-08-21 14:32:37 +00002309 if (res)
2310 res = validate_colon(CHILD(tree, 0));
2311 if (res && (nch == 2))
2312 res = validate_test(CHILD(tree, 1));
2313
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002314 return (res);
2315
Guido van Rossum47478871996-08-21 14:32:37 +00002316} /* validate_sliceop() */
2317
2318
2319static int
2320validate_exprlist(tree)
2321 node *tree;
2322{
2323 return (validate_repeating_list(tree, exprlist,
2324 validate_expr, "exprlist"));
2325
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002326} /* validate_exprlist() */
2327
2328
Guido van Rossum47478871996-08-21 14:32:37 +00002329static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002330validate_dictmaker(tree)
2331 node *tree;
2332{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002333 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002334 int res = (validate_ntype(tree, dictmaker)
2335 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002336 && validate_test(CHILD(tree, 0))
2337 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002338 && validate_test(CHILD(tree, 2)));
2339
Guido van Rossum3d602e31996-07-21 02:33:56 +00002340 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002341 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002342 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002343 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002344
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002345 if (res && (nch > 3)) {
2346 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002347 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002348 while (res && (pos < nch)) {
2349 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002350 && validate_test(CHILD(tree, pos + 1))
2351 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002352 && validate_test(CHILD(tree, pos + 3)));
2353 pos += 4;
2354 }
2355 }
2356 return (res);
2357
2358} /* validate_dictmaker() */
2359
2360
Guido van Rossum47478871996-08-21 14:32:37 +00002361static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002362validate_eval_input(tree)
2363 node *tree;
2364{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002365 int pos;
2366 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002367 int res = (validate_ntype(tree, eval_input)
2368 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002369 && validate_testlist(CHILD(tree, 0))
2370 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2371
Guido van Rossum3d602e31996-07-21 02:33:56 +00002372 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002373 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002374
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002375 return (res);
2376
2377} /* validate_eval_input() */
2378
2379
Guido van Rossum47478871996-08-21 14:32:37 +00002380static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002381validate_node(tree)
2382 node *tree;
2383{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002384 int nch = 0; /* num. children on current node */
2385 int res = 1; /* result value */
2386 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002387
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002388 while (res & (tree != 0)) {
2389 nch = NCH(tree);
2390 next = 0;
2391 switch (TYPE(tree)) {
2392 /*
2393 * Definition nodes.
2394 */
2395 case funcdef:
2396 res = validate_funcdef(tree);
2397 break;
2398 case classdef:
2399 res = validate_class(tree);
2400 break;
2401 /*
2402 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002403 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002404 */
2405 case stmt:
2406 res = validate_stmt(tree);
2407 break;
2408 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002409 /*
2410 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum925e5471997-04-02 05:32:13 +00002411 * | import_stmt | global_stmt | exec_stmt | assert_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002412 */
2413 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002414 break;
2415 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002416 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002417 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2418 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2419 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002420 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2421 if (res)
2422 next = CHILD(tree, 0);
2423 else if (nch == 1)
2424 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002425 break;
2426 /*
2427 * Compound statements.
2428 */
2429 case simple_stmt:
2430 res = validate_simple_stmt(tree);
2431 break;
2432 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002433 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002434 break;
2435 /*
2436 * Fundemental statements.
2437 */
2438 case expr_stmt:
2439 res = validate_expr_stmt(tree);
2440 break;
2441 case print_stmt:
2442 res = validate_print_stmt(tree);
2443 break;
2444 case del_stmt:
2445 res = validate_del_stmt(tree);
2446 break;
2447 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002448 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002449 && validate_name(CHILD(tree, 0), "pass"));
2450 break;
2451 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002452 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002453 && validate_name(CHILD(tree, 0), "break"));
2454 break;
2455 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002456 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002457 && validate_name(CHILD(tree, 0), "continue"));
2458 break;
2459 case return_stmt:
2460 res = validate_return_stmt(tree);
2461 break;
2462 case raise_stmt:
2463 res = validate_raise_stmt(tree);
2464 break;
2465 case import_stmt:
2466 res = validate_import_stmt(tree);
2467 break;
2468 case global_stmt:
2469 res = validate_global_stmt(tree);
2470 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002471 case exec_stmt:
2472 res = validate_exec_stmt(tree);
2473 break;
Guido van Rossum925e5471997-04-02 05:32:13 +00002474 case assert_stmt:
2475 res = validate_assert_stmt(tree);
2476 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002477 case if_stmt:
2478 res = validate_if(tree);
2479 break;
2480 case while_stmt:
2481 res = validate_while(tree);
2482 break;
2483 case for_stmt:
2484 res = validate_for(tree);
2485 break;
2486 case try_stmt:
2487 res = validate_try(tree);
2488 break;
2489 case suite:
2490 res = validate_suite(tree);
2491 break;
2492 /*
2493 * Expression nodes.
2494 */
2495 case testlist:
2496 res = validate_testlist(tree);
2497 break;
2498 case test:
2499 res = validate_test(tree);
2500 break;
2501 case and_test:
2502 res = validate_and_test(tree);
2503 break;
2504 case not_test:
2505 res = validate_not_test(tree);
2506 break;
2507 case comparison:
2508 res = validate_comparison(tree);
2509 break;
2510 case exprlist:
2511 res = validate_exprlist(tree);
2512 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002513 case comp_op:
2514 res = validate_comp_op(tree);
2515 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002516 case expr:
2517 res = validate_expr(tree);
2518 break;
2519 case xor_expr:
2520 res = validate_xor_expr(tree);
2521 break;
2522 case and_expr:
2523 res = validate_and_expr(tree);
2524 break;
2525 case shift_expr:
2526 res = validate_shift_expr(tree);
2527 break;
2528 case arith_expr:
2529 res = validate_arith_expr(tree);
2530 break;
2531 case term:
2532 res = validate_term(tree);
2533 break;
2534 case factor:
2535 res = validate_factor(tree);
2536 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002537 case power:
2538 res = validate_power(tree);
2539 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002540 case atom:
2541 res = validate_atom(tree);
2542 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002543
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002544 default:
2545 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002546 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002547 res = 0;
2548 break;
2549 }
2550 tree = next;
2551 }
2552 return (res);
2553
2554} /* validate_node() */
2555
2556
Guido van Rossum47478871996-08-21 14:32:37 +00002557static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002558validate_expr_tree(tree)
2559 node *tree;
2560{
2561 int res = validate_eval_input(tree);
2562
2563 if (!res && !PyErr_Occurred())
2564 err_string("Could not validate expression tuple.");
2565
2566 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002567
2568} /* validate_expr_tree() */
2569
2570
Guido van Rossum3d602e31996-07-21 02:33:56 +00002571/* file_input:
2572 * (NEWLINE | stmt)* ENDMARKER
2573 */
Guido van Rossum47478871996-08-21 14:32:37 +00002574static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002575validate_file_input(tree)
2576 node *tree;
2577{
2578 int j = 0;
2579 int nch = NCH(tree) - 1;
2580 int res = ((nch >= 0)
2581 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002582
Guido van Rossum3d602e31996-07-21 02:33:56 +00002583 for ( ; res && (j < nch); ++j) {
2584 if (TYPE(CHILD(tree, j)) == stmt)
2585 res = validate_stmt(CHILD(tree, j));
2586 else
2587 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002588 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002589 /* This stays in to prevent any internal failues from getting to the
2590 * user. Hopefully, this won't be needed. If a user reports getting
2591 * this, we have some debugging to do.
2592 */
2593 if (!res && !PyErr_Occurred())
2594 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2595
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002596 return (res);
2597
Guido van Rossum2a288461996-08-21 21:55:43 +00002598} /* validate_file_input() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002599
2600
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002601/* Functions exported by this module. Most of this should probably
2602 * be converted into an AST object with methods, but that is better
2603 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002604 * We'd really have to write a wrapper around it all anyway to allow
2605 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002606 */
2607static PyMethodDef parser_functions[] = {
Guido van Rossum3d602e31996-07-21 02:33:56 +00002608 {"ast2tuple", parser_ast2tuple, 1,
2609 "Creates a tuple-tree representation of an AST."},
Guido van Rossum47478871996-08-21 14:32:37 +00002610 {"ast2list", parser_ast2list, 1,
2611 "Creates a list-tree representation of an AST."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002612 {"compileast", parser_compileast, 1,
2613 "Compiles an AST object into a code object."},
2614 {"expr", parser_expr, 1,
2615 "Creates an AST object from an expression."},
2616 {"isexpr", parser_isexpr, 1,
2617 "Determines if an AST object was created from an expression."},
2618 {"issuite", parser_issuite, 1,
2619 "Determines if an AST object was created from a suite."},
2620 {"suite", parser_suite, 1,
2621 "Creates an AST object from a suite."},
Guido van Rossum47478871996-08-21 14:32:37 +00002622 {"sequence2ast", parser_tuple2ast, 1,
2623 "Creates an AST object from a tree representation."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002624 {"tuple2ast", parser_tuple2ast, 1,
Guido van Rossum47478871996-08-21 14:32:37 +00002625 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002626
2627 {0, 0, 0}
2628 };
2629
2630
Guido van Rossum52f2c051993-11-10 12:53:24 +00002631void
Guido van Rossum3d602e31996-07-21 02:33:56 +00002632initparser()
2633 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002634 PyObject* module;
2635 PyObject* dict;
2636
2637 PyAST_Type.ob_type = &PyType_Type;
2638 module = Py_InitModule("parser", parser_functions);
2639 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002640
Fred Drake0225a381997-10-07 19:32:00 +00002641 parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002642
2643 if ((parser_error == 0)
2644 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2645 /*
2646 * This is serious.
2647 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002648 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002649 }
2650 /*
2651 * Nice to have, but don't cry if we fail.
2652 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002653 Py_INCREF(&PyAST_Type);
2654 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2655
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002656 PyDict_SetItemString(dict, "__copyright__",
2657 PyString_FromString(parser_copyright_string));
2658 PyDict_SetItemString(dict, "__doc__",
2659 PyString_FromString(parser_doc_string));
2660 PyDict_SetItemString(dict, "__version__",
2661 PyString_FromString(parser_version_string));
2662
2663} /* initparser() */
2664
2665
2666/*
Guido van Rossum3d602e31996-07-21 02:33:56 +00002667 * end of parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002668 */