blob: c09cccc739059b20e0cd218f91ecfd51300763bb [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)));
1707 else if (res)
1708 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 }
1714 else if (nch == (pos + 6))
1715 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"));
1719 else
1720 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001721 }
1722 return (res);
1723
1724} /* validate_try() */
1725
1726
Guido van Rossum47478871996-08-21 14:32:37 +00001727static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001728validate_except_clause(tree)
1729 node *tree;
1730{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001731 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001732 int res = (validate_ntype(tree, except_clause)
1733 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001734 && validate_name(CHILD(tree, 0), "except"));
1735
Guido van Rossum3d602e31996-07-21 02:33:56 +00001736 if (res && (nch > 1))
1737 res = validate_test(CHILD(tree, 1));
1738 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001739 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001740 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001741
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001742 return (res);
1743
1744} /* validate_except_clause() */
1745
1746
Guido van Rossum47478871996-08-21 14:32:37 +00001747static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001748validate_test(tree)
1749 node *tree;
1750{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001751 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001752 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001753
Guido van Rossum3d602e31996-07-21 02:33:56 +00001754 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001755 res = ((nch == 1)
1756 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001757 else if (res) {
1758 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001759 res = validate_and_test(CHILD(tree, 0));
1760 for (pos = 1; res && (pos < nch); pos += 2)
1761 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001762 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001763 }
1764 return (res);
1765
1766} /* validate_test() */
1767
1768
Guido van Rossum47478871996-08-21 14:32:37 +00001769static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001770validate_and_test(tree)
1771 node *tree;
1772{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001773 int pos;
1774 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001775 int res = (validate_ntype(tree, and_test)
1776 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001777 && validate_not_test(CHILD(tree, 0)));
1778
Guido van Rossum3d602e31996-07-21 02:33:56 +00001779 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001780 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001781 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001782
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001783 return (res);
1784
1785} /* validate_and_test() */
1786
1787
Guido van Rossum47478871996-08-21 14:32:37 +00001788static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001789validate_not_test(tree)
1790 node *tree;
1791{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001792 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001793 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001794
Guido van Rossum3d602e31996-07-21 02:33:56 +00001795 if (res) {
1796 if (nch == 2)
1797 res = (validate_name(CHILD(tree, 0), "not")
1798 && validate_not_test(CHILD(tree, 1)));
1799 else if (nch == 1)
1800 res = validate_comparison(CHILD(tree, 0));
1801 }
1802 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001803
1804} /* validate_not_test() */
1805
1806
Guido van Rossum47478871996-08-21 14:32:37 +00001807static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001808validate_comparison(tree)
1809 node *tree;
1810{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001811 int pos;
1812 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001813 int res = (validate_ntype(tree, comparison)
1814 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001815 && validate_expr(CHILD(tree, 0)));
1816
Guido van Rossum3d602e31996-07-21 02:33:56 +00001817 for (pos = 1; res && (pos < nch); pos += 2)
1818 res = (validate_comp_op(CHILD(tree, pos))
1819 && validate_expr(CHILD(tree, pos + 1)));
1820
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001821 return (res);
1822
1823} /* validate_comparison() */
1824
1825
Guido van Rossum47478871996-08-21 14:32:37 +00001826static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001827validate_comp_op(tree)
1828 node *tree;
1829{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001830 int res = 0;
1831 int nch = NCH(tree);
1832
Guido van Rossum3d602e31996-07-21 02:33:56 +00001833 if (!validate_ntype(tree, comp_op))
1834 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001835 if (nch == 1) {
1836 /*
1837 * Only child will be a terminal with a well-defined symbolic name
1838 * or a NAME with a string of either 'is' or 'in'
1839 */
1840 tree = CHILD(tree, 0);
1841 switch (TYPE(tree)) {
1842 case LESS:
1843 case GREATER:
1844 case EQEQUAL:
1845 case EQUAL:
1846 case LESSEQUAL:
1847 case GREATEREQUAL:
1848 case NOTEQUAL:
1849 res = 1;
1850 break;
1851 case NAME:
1852 res = ((strcmp(STR(tree), "in") == 0)
1853 || (strcmp(STR(tree), "is") == 0));
1854 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001855 char buff[128];
1856 sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1857 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001858 }
1859 break;
1860 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001861 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001862 break;
1863 }
1864 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001865 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001866 res = (validate_ntype(CHILD(tree, 0), NAME)
1867 && validate_ntype(CHILD(tree, 1), NAME)
1868 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1869 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1870 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1871 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001872 if (!res && !PyErr_Occurred())
1873 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001874 }
1875 return (res);
1876
1877} /* validate_comp_op() */
1878
1879
Guido van Rossum47478871996-08-21 14:32:37 +00001880static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001881validate_expr(tree)
1882 node *tree;
1883{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001884 int j;
1885 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001886 int res = (validate_ntype(tree, expr)
1887 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001888 && validate_xor_expr(CHILD(tree, 0)));
1889
Guido van Rossum3d602e31996-07-21 02:33:56 +00001890 for (j = 2; res && (j < nch); j += 2)
1891 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001892 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001893
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001894 return (res);
1895
1896} /* validate_expr() */
1897
1898
Guido van Rossum47478871996-08-21 14:32:37 +00001899static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001900validate_xor_expr(tree)
1901 node *tree;
1902{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001903 int j;
1904 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001905 int res = (validate_ntype(tree, xor_expr)
1906 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001907 && validate_and_expr(CHILD(tree, 0)));
1908
Guido van Rossum3d602e31996-07-21 02:33:56 +00001909 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001910 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001911 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001912
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001913 return (res);
1914
1915} /* validate_xor_expr() */
1916
1917
Guido van Rossum47478871996-08-21 14:32:37 +00001918static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001919validate_and_expr(tree)
1920 node *tree;
1921{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001922 int pos;
1923 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001924 int res = (validate_ntype(tree, and_expr)
1925 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001926 && validate_shift_expr(CHILD(tree, 0)));
1927
Guido van Rossum3d602e31996-07-21 02:33:56 +00001928 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001929 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001930 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001931
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001932 return (res);
1933
1934} /* validate_and_expr() */
1935
1936
1937static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001938validate_chain_two_ops(tree, termvalid, op1, op2)
1939 node *tree;
1940 int (*termvalid)();
1941 int op1;
1942 int op2;
1943 {
1944 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001945 int nch = NCH(tree);
1946 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001947 && (*termvalid)(CHILD(tree, 0)));
1948
Guido van Rossum3d602e31996-07-21 02:33:56 +00001949 for ( ; res && (pos < nch); pos += 2) {
1950 if (TYPE(CHILD(tree, pos)) != op1)
1951 res = validate_ntype(CHILD(tree, pos), op2);
1952 if (res)
1953 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001954 }
1955 return (res);
1956
1957} /* validate_chain_two_ops() */
1958
1959
Guido van Rossum47478871996-08-21 14:32:37 +00001960static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001961validate_shift_expr(tree)
1962 node *tree;
1963{
1964 return (validate_ntype(tree, shift_expr)
1965 && validate_chain_two_ops(tree, validate_arith_expr,
1966 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001967
1968} /* validate_shift_expr() */
1969
1970
Guido van Rossum47478871996-08-21 14:32:37 +00001971static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001972validate_arith_expr(tree)
1973 node *tree;
1974{
1975 return (validate_ntype(tree, arith_expr)
1976 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001977
1978} /* validate_arith_expr() */
1979
1980
Guido van Rossum47478871996-08-21 14:32:37 +00001981static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001982validate_term(tree)
1983 node *tree;
1984{
1985 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001986 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001987 int res = (validate_ntype(tree, term)
1988 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001989 && validate_factor(CHILD(tree, 0)));
1990
Guido van Rossum3d602e31996-07-21 02:33:56 +00001991 for ( ; res && (pos < nch); pos += 2)
1992 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001993 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001994 || (TYPE(CHILD(tree, pos)) == PERCENT))
1995 && validate_factor(CHILD(tree, pos + 1)));
1996
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001997 return (res);
1998
1999} /* validate_term() */
2000
2001
Guido van Rossum3d602e31996-07-21 02:33:56 +00002002/* factor:
2003 *
2004 * factor: ('+'|'-'|'~') factor | power
2005 */
Guido van Rossum47478871996-08-21 14:32:37 +00002006static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002007validate_factor(tree)
2008 node *tree;
2009{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002010 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002011 int res = (validate_ntype(tree, factor)
2012 && (((nch == 2)
2013 && ((TYPE(CHILD(tree, 0)) == PLUS)
2014 || (TYPE(CHILD(tree, 0)) == MINUS)
2015 || (TYPE(CHILD(tree, 0)) == TILDE))
2016 && validate_factor(CHILD(tree, 1)))
2017 || ((nch == 1)
2018 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002019 return (res);
2020
2021} /* validate_factor() */
2022
2023
Guido van Rossum3d602e31996-07-21 02:33:56 +00002024/* power:
2025 *
2026 * power: atom trailer* ('**' factor)*
2027 */
Guido van Rossum47478871996-08-21 14:32:37 +00002028static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002029validate_power(tree)
2030 node *tree;
2031{
2032 int pos = 1;
2033 int nch = NCH(tree);
2034 int res = (validate_ntype(tree, power) && (nch >= 1)
2035 && validate_atom(CHILD(tree, 0)));
2036
2037 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2038 res = validate_trailer(CHILD(tree, pos++));
2039 if (res && (pos < nch)) {
2040 if (!is_even(nch - pos)) {
2041 err_string("Illegal number of nodes for 'power'.");
2042 return (0);
2043 }
2044 for ( ; res && (pos < (nch - 1)); pos += 2)
2045 res = (validate_doublestar(CHILD(tree, pos))
2046 && validate_factor(CHILD(tree, pos + 1)));
2047 }
2048 return (res);
2049
2050} /* validate_power() */
2051
2052
Guido van Rossum47478871996-08-21 14:32:37 +00002053static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002054validate_atom(tree)
2055 node *tree;
2056{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002057 int pos;
2058 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002059 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002060
2061 if (res) {
2062 switch (TYPE(CHILD(tree, 0))) {
2063 case LPAR:
2064 res = ((nch <= 3)
2065 && (validate_rparen(CHILD(tree, nch - 1))));
2066
Guido van Rossum3d602e31996-07-21 02:33:56 +00002067 if (res && (nch == 3))
2068 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002069 break;
2070 case LSQB:
2071 res = ((nch <= 3)
2072 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2073
Guido van Rossum3d602e31996-07-21 02:33:56 +00002074 if (res && (nch == 3))
2075 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002076 break;
2077 case LBRACE:
2078 res = ((nch <= 3)
2079 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2080
Guido van Rossum3d602e31996-07-21 02:33:56 +00002081 if (res && (nch == 3))
2082 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002083 break;
2084 case BACKQUOTE:
2085 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002086 && validate_testlist(CHILD(tree, 1))
2087 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2088 break;
2089 case NAME:
2090 case NUMBER:
2091 res = (nch == 1);
2092 break;
2093 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002094 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002095 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002096 break;
2097 default:
2098 res = 0;
2099 break;
2100 }
2101 }
2102 return (res);
2103
2104} /* validate_atom() */
2105
2106
Guido van Rossum3d602e31996-07-21 02:33:56 +00002107/* funcdef:
2108 * 'def' NAME parameters ':' suite
2109 *
2110 */
Guido van Rossum47478871996-08-21 14:32:37 +00002111static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002112validate_funcdef(tree)
2113 node *tree;
2114{
2115 return (validate_ntype(tree, funcdef)
2116 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002117 && validate_name(CHILD(tree, 0), "def")
2118 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002119 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002120 && validate_parameters(CHILD(tree, 2))
2121 && validate_suite(CHILD(tree, 4)));
2122
2123} /* validate_funcdef() */
2124
2125
Guido van Rossum47478871996-08-21 14:32:37 +00002126static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002127validate_lambdef(tree)
2128 node *tree;
2129{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002130 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002131 int res = (validate_ntype(tree, lambdef)
2132 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002133 && validate_name(CHILD(tree, 0), "lambda")
2134 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002135 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002136
Guido van Rossum3d602e31996-07-21 02:33:56 +00002137 if (res && (nch == 4))
2138 res = validate_varargslist(CHILD(tree, 1));
2139 else if (!res && !PyErr_Occurred())
2140 validate_numnodes(tree, 3, "lambdef");
2141
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002142 return (res);
2143
2144} /* validate_lambdef() */
2145
2146
Guido van Rossum3d602e31996-07-21 02:33:56 +00002147/* arglist:
2148 *
2149 * argument (',' argument)* [',']
2150 */
Guido van Rossum47478871996-08-21 14:32:37 +00002151static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002152validate_arglist(tree)
2153 node *tree;
2154{
Guido van Rossum47478871996-08-21 14:32:37 +00002155 return (validate_repeating_list(tree, arglist,
2156 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002157
2158} /* validate_arglist() */
2159
2160
2161
2162/* argument:
2163 *
2164 * [test '='] test
2165 */
Guido van Rossum47478871996-08-21 14:32:37 +00002166static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002167validate_argument(tree)
2168 node *tree;
2169{
2170 int nch = NCH(tree);
2171 int res = (validate_ntype(tree, argument)
2172 && ((nch == 1) || (nch == 3))
2173 && validate_test(CHILD(tree, 0)));
2174
2175 if (res && (nch == 3))
2176 res = (validate_equal(CHILD(tree, 1))
2177 && validate_test(CHILD(tree, 2)));
2178
2179 return (res);
2180
2181} /* validate_argument() */
2182
2183
2184
2185/* trailer:
2186 *
Guido van Rossum47478871996-08-21 14:32:37 +00002187 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002188 */
Guido van Rossum47478871996-08-21 14:32:37 +00002189static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002190validate_trailer(tree)
2191 node *tree;
2192{
2193 int nch = NCH(tree);
2194 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002195
2196 if (res) {
2197 switch (TYPE(CHILD(tree, 0))) {
2198 case LPAR:
2199 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002200 if (res && (nch == 3))
2201 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002202 break;
2203 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002204 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002205 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002206 && validate_ntype(CHILD(tree, 2), RSQB));
2207 break;
2208 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002209 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002210 && validate_ntype(CHILD(tree, 1), NAME));
2211 break;
2212 default:
2213 res = 0;
2214 break;
2215 }
2216 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002217 else
2218 validate_numnodes(tree, 2, "trailer");
2219
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002220 return (res);
2221
2222} /* validate_trailer() */
2223
2224
Guido van Rossum47478871996-08-21 14:32:37 +00002225/* subscriptlist:
2226 *
2227 * subscript (',' subscript)* [',']
2228 */
2229static int
2230validate_subscriptlist(tree)
2231 node *tree;
2232{
2233 return (validate_repeating_list(tree, subscriptlist,
2234 validate_subscript, "subscriptlist"));
2235
2236} /* validate_subscriptlist() */
2237
2238
Guido van Rossum3d602e31996-07-21 02:33:56 +00002239/* subscript:
2240 *
Guido van Rossum47478871996-08-21 14:32:37 +00002241 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002242 */
Guido van Rossum47478871996-08-21 14:32:37 +00002243static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002244validate_subscript(tree)
2245 node *tree;
2246{
Guido van Rossum47478871996-08-21 14:32:37 +00002247 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002248 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002249 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002250
Guido van Rossum47478871996-08-21 14:32:37 +00002251 if (!res) {
2252 if (!PyErr_Occurred())
2253 err_string("invalid number of arguments for subscript node");
2254 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002255 }
Guido van Rossum47478871996-08-21 14:32:37 +00002256 if (TYPE(CHILD(tree, 0)) == DOT)
2257 /* take care of ('.' '.' '.') possibility */
2258 return (validate_numnodes(tree, 3, "subscript")
2259 && validate_dot(CHILD(tree, 0))
2260 && validate_dot(CHILD(tree, 1))
2261 && validate_dot(CHILD(tree, 2)));
2262 if (nch == 1) {
2263 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002264 res = validate_test(CHILD(tree, 0));
2265 else
Guido van Rossum47478871996-08-21 14:32:37 +00002266 res = validate_colon(CHILD(tree, 0));
2267 return (res);
2268 }
2269 /* Must be [test] ':' [test] [sliceop],
2270 * but at least one of the optional components will
2271 * be present, but we don't know which yet.
2272 */
2273 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2274 res = validate_test(CHILD(tree, 0));
2275 offset = 1;
2276 }
2277 if (res)
2278 res = validate_colon(CHILD(tree, offset));
2279 if (res) {
2280 int rem = nch - ++offset;
2281 if (rem) {
2282 if (TYPE(CHILD(tree, offset)) == test) {
2283 res = validate_test(CHILD(tree, offset));
2284 ++offset;
2285 --rem;
2286 }
2287 if (res && rem)
2288 res = validate_sliceop(CHILD(tree, offset));
2289 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002290 }
2291 return (res);
2292
2293} /* validate_subscript() */
2294
2295
Guido van Rossum47478871996-08-21 14:32:37 +00002296static int
2297validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002298 node *tree;
2299{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002300 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002301 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2302 && validate_ntype(tree, sliceop);
2303 if (!res && !PyErr_Occurred()) {
2304 validate_numnodes(tree, 1, "sliceop");
2305 res = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002306 }
Guido van Rossum47478871996-08-21 14:32:37 +00002307 if (res)
2308 res = validate_colon(CHILD(tree, 0));
2309 if (res && (nch == 2))
2310 res = validate_test(CHILD(tree, 1));
2311
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002312 return (res);
2313
Guido van Rossum47478871996-08-21 14:32:37 +00002314} /* validate_sliceop() */
2315
2316
2317static int
2318validate_exprlist(tree)
2319 node *tree;
2320{
2321 return (validate_repeating_list(tree, exprlist,
2322 validate_expr, "exprlist"));
2323
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002324} /* validate_exprlist() */
2325
2326
Guido van Rossum47478871996-08-21 14:32:37 +00002327static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002328validate_dictmaker(tree)
2329 node *tree;
2330{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002331 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002332 int res = (validate_ntype(tree, dictmaker)
2333 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002334 && validate_test(CHILD(tree, 0))
2335 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002336 && validate_test(CHILD(tree, 2)));
2337
Guido van Rossum3d602e31996-07-21 02:33:56 +00002338 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002339 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002340 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002341 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002342
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002343 if (res && (nch > 3)) {
2344 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002345 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002346 while (res && (pos < nch)) {
2347 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002348 && validate_test(CHILD(tree, pos + 1))
2349 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002350 && validate_test(CHILD(tree, pos + 3)));
2351 pos += 4;
2352 }
2353 }
2354 return (res);
2355
2356} /* validate_dictmaker() */
2357
2358
Guido van Rossum47478871996-08-21 14:32:37 +00002359static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002360validate_eval_input(tree)
2361 node *tree;
2362{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002363 int pos;
2364 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002365 int res = (validate_ntype(tree, eval_input)
2366 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002367 && validate_testlist(CHILD(tree, 0))
2368 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2369
Guido van Rossum3d602e31996-07-21 02:33:56 +00002370 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002371 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002372
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002373 return (res);
2374
2375} /* validate_eval_input() */
2376
2377
Guido van Rossum47478871996-08-21 14:32:37 +00002378static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002379validate_node(tree)
2380 node *tree;
2381{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002382 int nch = 0; /* num. children on current node */
2383 int res = 1; /* result value */
2384 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002385
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002386 while (res & (tree != 0)) {
2387 nch = NCH(tree);
2388 next = 0;
2389 switch (TYPE(tree)) {
2390 /*
2391 * Definition nodes.
2392 */
2393 case funcdef:
2394 res = validate_funcdef(tree);
2395 break;
2396 case classdef:
2397 res = validate_class(tree);
2398 break;
2399 /*
2400 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002401 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002402 */
2403 case stmt:
2404 res = validate_stmt(tree);
2405 break;
2406 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002407 /*
2408 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum925e5471997-04-02 05:32:13 +00002409 * | import_stmt | global_stmt | exec_stmt | assert_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002410 */
2411 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002412 break;
2413 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002414 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002415 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2416 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2417 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002418 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2419 if (res)
2420 next = CHILD(tree, 0);
2421 else if (nch == 1)
2422 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002423 break;
2424 /*
2425 * Compound statements.
2426 */
2427 case simple_stmt:
2428 res = validate_simple_stmt(tree);
2429 break;
2430 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002431 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002432 break;
2433 /*
2434 * Fundemental statements.
2435 */
2436 case expr_stmt:
2437 res = validate_expr_stmt(tree);
2438 break;
2439 case print_stmt:
2440 res = validate_print_stmt(tree);
2441 break;
2442 case del_stmt:
2443 res = validate_del_stmt(tree);
2444 break;
2445 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002446 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002447 && validate_name(CHILD(tree, 0), "pass"));
2448 break;
2449 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002450 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002451 && validate_name(CHILD(tree, 0), "break"));
2452 break;
2453 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002454 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002455 && validate_name(CHILD(tree, 0), "continue"));
2456 break;
2457 case return_stmt:
2458 res = validate_return_stmt(tree);
2459 break;
2460 case raise_stmt:
2461 res = validate_raise_stmt(tree);
2462 break;
2463 case import_stmt:
2464 res = validate_import_stmt(tree);
2465 break;
2466 case global_stmt:
2467 res = validate_global_stmt(tree);
2468 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002469 case exec_stmt:
2470 res = validate_exec_stmt(tree);
2471 break;
Guido van Rossum925e5471997-04-02 05:32:13 +00002472 case assert_stmt:
2473 res = validate_assert_stmt(tree);
2474 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002475 case if_stmt:
2476 res = validate_if(tree);
2477 break;
2478 case while_stmt:
2479 res = validate_while(tree);
2480 break;
2481 case for_stmt:
2482 res = validate_for(tree);
2483 break;
2484 case try_stmt:
2485 res = validate_try(tree);
2486 break;
2487 case suite:
2488 res = validate_suite(tree);
2489 break;
2490 /*
2491 * Expression nodes.
2492 */
2493 case testlist:
2494 res = validate_testlist(tree);
2495 break;
2496 case test:
2497 res = validate_test(tree);
2498 break;
2499 case and_test:
2500 res = validate_and_test(tree);
2501 break;
2502 case not_test:
2503 res = validate_not_test(tree);
2504 break;
2505 case comparison:
2506 res = validate_comparison(tree);
2507 break;
2508 case exprlist:
2509 res = validate_exprlist(tree);
2510 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002511 case comp_op:
2512 res = validate_comp_op(tree);
2513 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002514 case expr:
2515 res = validate_expr(tree);
2516 break;
2517 case xor_expr:
2518 res = validate_xor_expr(tree);
2519 break;
2520 case and_expr:
2521 res = validate_and_expr(tree);
2522 break;
2523 case shift_expr:
2524 res = validate_shift_expr(tree);
2525 break;
2526 case arith_expr:
2527 res = validate_arith_expr(tree);
2528 break;
2529 case term:
2530 res = validate_term(tree);
2531 break;
2532 case factor:
2533 res = validate_factor(tree);
2534 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002535 case power:
2536 res = validate_power(tree);
2537 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002538 case atom:
2539 res = validate_atom(tree);
2540 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002541
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002542 default:
2543 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002544 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002545 res = 0;
2546 break;
2547 }
2548 tree = next;
2549 }
2550 return (res);
2551
2552} /* validate_node() */
2553
2554
Guido van Rossum47478871996-08-21 14:32:37 +00002555static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002556validate_expr_tree(tree)
2557 node *tree;
2558{
2559 int res = validate_eval_input(tree);
2560
2561 if (!res && !PyErr_Occurred())
2562 err_string("Could not validate expression tuple.");
2563
2564 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002565
2566} /* validate_expr_tree() */
2567
2568
Guido van Rossum3d602e31996-07-21 02:33:56 +00002569/* file_input:
2570 * (NEWLINE | stmt)* ENDMARKER
2571 */
Guido van Rossum47478871996-08-21 14:32:37 +00002572static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002573validate_file_input(tree)
2574 node *tree;
2575{
2576 int j = 0;
2577 int nch = NCH(tree) - 1;
2578 int res = ((nch >= 0)
2579 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002580
Guido van Rossum3d602e31996-07-21 02:33:56 +00002581 for ( ; res && (j < nch); ++j) {
2582 if (TYPE(CHILD(tree, j)) == stmt)
2583 res = validate_stmt(CHILD(tree, j));
2584 else
2585 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002586 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002587 /* This stays in to prevent any internal failues from getting to the
2588 * user. Hopefully, this won't be needed. If a user reports getting
2589 * this, we have some debugging to do.
2590 */
2591 if (!res && !PyErr_Occurred())
2592 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2593
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002594 return (res);
2595
Guido van Rossum2a288461996-08-21 21:55:43 +00002596} /* validate_file_input() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002597
2598
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002599/* Functions exported by this module. Most of this should probably
2600 * be converted into an AST object with methods, but that is better
2601 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002602 * We'd really have to write a wrapper around it all anyway to allow
2603 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002604 */
2605static PyMethodDef parser_functions[] = {
Guido van Rossum3d602e31996-07-21 02:33:56 +00002606 {"ast2tuple", parser_ast2tuple, 1,
2607 "Creates a tuple-tree representation of an AST."},
Guido van Rossum47478871996-08-21 14:32:37 +00002608 {"ast2list", parser_ast2list, 1,
2609 "Creates a list-tree representation of an AST."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002610 {"compileast", parser_compileast, 1,
2611 "Compiles an AST object into a code object."},
2612 {"expr", parser_expr, 1,
2613 "Creates an AST object from an expression."},
2614 {"isexpr", parser_isexpr, 1,
2615 "Determines if an AST object was created from an expression."},
2616 {"issuite", parser_issuite, 1,
2617 "Determines if an AST object was created from a suite."},
2618 {"suite", parser_suite, 1,
2619 "Creates an AST object from a suite."},
Guido van Rossum47478871996-08-21 14:32:37 +00002620 {"sequence2ast", parser_tuple2ast, 1,
2621 "Creates an AST object from a tree representation."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002622 {"tuple2ast", parser_tuple2ast, 1,
Guido van Rossum47478871996-08-21 14:32:37 +00002623 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002624
2625 {0, 0, 0}
2626 };
2627
2628
Guido van Rossum52f2c051993-11-10 12:53:24 +00002629void
Guido van Rossum3d602e31996-07-21 02:33:56 +00002630initparser()
2631 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002632 PyObject* module;
2633 PyObject* dict;
2634
2635 PyAST_Type.ob_type = &PyType_Type;
2636 module = Py_InitModule("parser", parser_functions);
2637 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002638
Fred Drake0225a381997-10-07 19:32:00 +00002639 parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002640
2641 if ((parser_error == 0)
2642 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2643 /*
2644 * This is serious.
2645 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002646 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002647 }
2648 /*
2649 * Nice to have, but don't cry if we fail.
2650 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002651 Py_INCREF(&PyAST_Type);
2652 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2653
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002654 PyDict_SetItemString(dict, "__copyright__",
2655 PyString_FromString(parser_copyright_string));
2656 PyDict_SetItemString(dict, "__doc__",
2657 PyString_FromString(parser_doc_string));
2658 PyDict_SetItemString(dict, "__version__",
2659 PyString_FromString(parser_version_string));
2660
2661} /* initparser() */
2662
2663
2664/*
Guido van Rossum3d602e31996-07-21 02:33:56 +00002665 * end of parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002666 */