blob: 0c01ed3f6df228a9ba482876e9fb516230f559d7 [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
29/*
30 * All the "fudge" declarations are here:
Guido van Rossum3d602e31996-07-21 02:33:56 +000031 *
32 * This isn't part of the Python runtime, but it's in the library somewhere.
Guido van Rossum2a288461996-08-21 21:55:43 +000033 * Where it is varies a bit, so just declare it. Don't use any prototype;
34 * different systems declare it a little differently, and we don't need the
35 * extra warnings.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000036 */
Guido van Rossum3d602e31996-07-21 02:33:56 +000037extern char* strdup();
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000038
39
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000040/* String constants used to initialize module attributes.
41 *
42 */
43static char*
44parser_copyright_string
Guido van Rossum2a288461996-08-21 21:55:43 +000045= "Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
46University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
47Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\
48Centrum, Amsterdam, The Netherlands.";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000049
50
51static char*
52parser_doc_string
53= "This is an interface to Python's internal parser.";
54
55static char*
Guido van Rossum47478871996-08-21 14:32:37 +000056parser_version_string = "0.4";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000057
58
Guido van Rossum2a288461996-08-21 21:55:43 +000059typedef PyObject* (*SeqMaker) Py_PROTO((int length));
60typedef void (*SeqInserter) Py_PROTO((PyObject* sequence,
61 int index,
62 PyObject* element));
Guido van Rossum47478871996-08-21 14:32:37 +000063
Guido van Rossum3d602e31996-07-21 02:33:56 +000064/* The function below is copyrigthed by Stichting Mathematisch Centrum. The
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000065 * original copyright statement is included below, and continues to apply
66 * in full to the function immediately following. All other material is
67 * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
68 * Institute and State University. Changes were made to comply with the
Guido van Rossum2a288461996-08-21 21:55:43 +000069 * new naming conventions. Added arguments to provide support for creating
70 * lists as well as tuples, and optionally including the line numbers.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000071 */
72
Guido van Rossum52f2c051993-11-10 12:53:24 +000073/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +000074Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
75The Netherlands.
Guido van Rossum52f2c051993-11-10 12:53:24 +000076
77 All Rights Reserved
78
Guido van Rossum3d602e31996-07-21 02:33:56 +000079Permission to use, copy, modify, and distribute this software and its
80documentation for any purpose and without fee is hereby granted,
Guido van Rossum52f2c051993-11-10 12:53:24 +000081provided that the above copyright notice appear in all copies and that
Guido van Rossum3d602e31996-07-21 02:33:56 +000082both that copyright notice and this permission notice appear in
Guido van Rossum52f2c051993-11-10 12:53:24 +000083supporting documentation, and that the names of Stichting Mathematisch
84Centrum or CWI not be used in advertising or publicity pertaining to
85distribution of the software without specific, written prior permission.
86
87STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
88THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
89FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
90FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
91WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
92ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
93OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
94
95******************************************************************/
96
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000097static PyObject*
Guido van Rossum47478871996-08-21 14:32:37 +000098node2tuple(n, mkseq, addelem, lineno)
99 node *n; /* node to convert */
100 SeqMaker mkseq; /* create sequence */
101 SeqInserter addelem; /* func. to add elem. in seq. */
102 int lineno; /* include line numbers? */
103{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000104 if (n == NULL) {
105 Py_INCREF(Py_None);
106 return Py_None;
107 }
108 if (ISNONTERMINAL(TYPE(n))) {
109 int i;
110 PyObject *v, *w;
Guido van Rossum47478871996-08-21 14:32:37 +0000111 v = mkseq(1 + NCH(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000112 if (v == NULL)
113 return v;
114 w = PyInt_FromLong(TYPE(n));
115 if (w == NULL) {
116 Py_DECREF(v);
117 return NULL;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000118 }
Guido van Rossum47478871996-08-21 14:32:37 +0000119 addelem(v, 0, w);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000120 for (i = 0; i < NCH(n); i++) {
Guido van Rossum47478871996-08-21 14:32:37 +0000121 w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000122 if (w == NULL) {
123 Py_DECREF(v);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000124 return NULL;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000125 }
Guido van Rossum47478871996-08-21 14:32:37 +0000126 addelem(v, i+1, w);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000127 }
Guido van Rossum47478871996-08-21 14:32:37 +0000128 return (v);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000129 }
130 else if (ISTERMINAL(TYPE(n))) {
Guido van Rossum47478871996-08-21 14:32:37 +0000131 PyObject *result = mkseq(2 + lineno);
132 if (result != NULL) {
133 addelem(result, 0, PyInt_FromLong(TYPE(n)));
134 addelem(result, 1, PyString_FromString(STR(n)));
135 if (lineno == 1)
136 addelem(result, 2, PyInt_FromLong(n->n_lineno));
137 }
138 return (result);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000139 }
140 else {
141 PyErr_SetString(PyExc_SystemError,
142 "unrecognized parse tree node type");
143 return NULL;
144 }
Guido van Rossum47478871996-08-21 14:32:37 +0000145} /* node2tuple() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000146/*
147 * End of material copyrighted by Stichting Mathematisch Centrum.
148 */
Guido van Rossum52f2c051993-11-10 12:53:24 +0000149
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000150
151
152/* There are two types of intermediate objects we're interested in:
153 * 'eval' and 'exec' types. These constants can be used in the ast_type
154 * field of the object type to identify which any given object represents.
155 * These should probably go in an external header to allow other extensions
156 * to use them, but then, we really should be using C++ too. ;-)
157 *
Guido van Rossum3d602e31996-07-21 02:33:56 +0000158 * The PyAST_FRAGMENT type is not currently supported. Maybe not useful?
159 * Haven't decided yet.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000160 */
161
162#define PyAST_EXPR 1
163#define PyAST_SUITE 2
164#define PyAST_FRAGMENT 3
165
166
167/* These are the internal objects and definitions required to implement the
168 * AST type. Most of the internal names are more reminiscent of the 'old'
169 * naming style, but the code uses the new naming convention.
170 */
171
172static PyObject*
173parser_error = 0;
174
175
176typedef struct _PyAST_Object {
177
178 PyObject_HEAD /* standard object header */
179 node* ast_node; /* the node* returned by the parser */
180 int ast_type; /* EXPR or SUITE ? */
181
182} PyAST_Object;
183
184
Guido van Rossum2a288461996-08-21 21:55:43 +0000185staticforward void parser_free Py_PROTO((PyAST_Object *ast));
186staticforward int parser_compare Py_PROTO((PyAST_Object *left,
187 PyAST_Object *right));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000188
189
190/* static */
191PyTypeObject PyAST_Type = {
192
193 PyObject_HEAD_INIT(&PyType_Type)
194 0,
195 "ast", /* tp_name */
196 sizeof(PyAST_Object), /* tp_basicsize */
197 0, /* tp_itemsize */
198 (destructor)parser_free, /* tp_dealloc */
199 0, /* tp_print */
200 0, /* tp_getattr */
201 0, /* tp_setattr */
202 (cmpfunc)parser_compare, /* tp_compare */
203 0, /* tp_repr */
204 0, /* tp_as_number */
205 0, /* tp_as_sequence */
206 0, /* tp_as_mapping */
207 0, /* tp_hash */
208 0, /* tp_call */
209 0 /* tp_str */
210
211}; /* PyAST_Type */
212
213
214static int
215parser_compare_nodes(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000216 node *left;
217 node *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000218{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000219 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000220
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000221 if (TYPE(left) < TYPE(right))
222 return (-1);
223
224 if (TYPE(right) < TYPE(left))
225 return (1);
226
227 if (ISTERMINAL(TYPE(left)))
228 return (strcmp(STR(left), STR(right)));
229
230 if (NCH(left) < NCH(right))
231 return (-1);
232
233 if (NCH(right) < NCH(left))
234 return (1);
235
236 for (j = 0; j < NCH(left); ++j) {
237 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
238
239 if (v)
240 return (v);
241 }
242 return (0);
243
244} /* parser_compare_nodes() */
245
246
247/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
248 *
249 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
250 * This really just wraps a call to parser_compare_nodes() with some easy
251 * checks and protection code.
252 *
253 */
254static int
255parser_compare(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000256 PyAST_Object *left;
257 PyAST_Object *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000258{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000259 if (left == right)
260 return (0);
261
262 if ((left == 0) || (right == 0))
263 return (-1);
264
265 return (parser_compare_nodes(left->ast_node, right->ast_node));
266
267} /* parser_compare() */
268
269
270/* parser_newastobject(node* ast)
271 *
272 * Allocates a new Python object representing an AST. This is simply the
273 * 'wrapper' object that holds a node* and allows it to be passed around in
274 * Python code.
275 *
276 */
277static PyObject*
278parser_newastobject(ast, type)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000279 node *ast;
280 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000281{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000282 PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
283
284 if (o != 0) {
285 o->ast_node = ast;
286 o->ast_type = type;
287 }
288 return ((PyObject*)o);
289
290} /* parser_newastobject() */
291
292
293/* void parser_free(PyAST_Object* ast)
294 *
295 * This is called by a del statement that reduces the reference count to 0.
296 *
297 */
298static void
299parser_free(ast)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000300 PyAST_Object *ast;
Guido van Rossum47478871996-08-21 14:32:37 +0000301{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000302 PyNode_Free(ast->ast_node);
303 PyMem_DEL(ast);
304
305} /* parser_free() */
306
307
308/* parser_ast2tuple(PyObject* self, PyObject* args)
309 *
310 * This provides conversion from a node* to a tuple object that can be
311 * returned to the Python-level caller. The AST object is not modified.
312 *
313 */
314static PyObject*
315parser_ast2tuple(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000316 PyObject *self;
317 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000318{
319 PyObject *ast;
320 PyObject *line_option = 0;
321 PyObject *res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000322
Guido van Rossum47478871996-08-21 14:32:37 +0000323 if (PyArg_ParseTuple(args, "O!|O:ast2tuple", &PyAST_Type, &ast,
324 &line_option)) {
325 int lineno = 0;
326 if (line_option != 0) {
327 lineno = PyObject_IsTrue(line_option);
328 lineno = lineno ? 1 : 0;
329 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000330 /*
331 * Convert AST into a tuple representation. Use Guido's function,
332 * since it's known to work already.
333 */
Guido van Rossum47478871996-08-21 14:32:37 +0000334 res = node2tuple(((PyAST_Object*)ast)->ast_node,
335 PyTuple_New, PyTuple_SetItem, lineno);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000336 }
337 return (res);
338
339} /* parser_ast2tuple() */
340
341
Guido van Rossum47478871996-08-21 14:32:37 +0000342/* parser_ast2tuple(PyObject* self, PyObject* args)
343 *
344 * This provides conversion from a node* to a tuple object that can be
345 * returned to the Python-level caller. The AST object is not modified.
346 *
347 */
348static PyObject*
349parser_ast2list(self, args)
350 PyObject *self;
351 PyObject *args;
352{
353 PyObject *ast;
354 PyObject *line_option = 0;
355 PyObject *res = 0;
356
357 if (PyArg_ParseTuple(args, "O!|O:ast2list", &PyAST_Type, &ast,
358 &line_option)) {
359 int lineno = 0;
360 if (line_option != 0) {
361 lineno = PyObject_IsTrue(line_option);
362 lineno = lineno ? 1 : 0;
363 }
364 /*
365 * Convert AST into a tuple representation. Use Guido's function,
366 * since it's known to work already.
367 */
368 res = node2tuple(((PyAST_Object*)ast)->ast_node,
369 PyList_New, PyList_SetItem, lineno);
370 }
371 return (res);
372
373} /* parser_ast2list() */
374
375
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000376/* parser_compileast(PyObject* self, PyObject* args)
377 *
378 * This function creates code objects from the parse tree represented by
379 * the passed-in data object. An optional file name is passed in as well.
380 *
381 */
382static PyObject*
383parser_compileast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000384 PyObject *self;
385 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000386{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000387 PyAST_Object* ast;
388 PyObject* res = 0;
389 char* str = "<ast>";
390
391 if (PyArg_ParseTuple(args, "O!|s", &PyAST_Type, &ast, &str))
Guido van Rossum3d602e31996-07-21 02:33:56 +0000392 res = (PyObject*) PyNode_Compile(ast->ast_node, str);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000393
394 return (res);
395
396} /* parser_compileast() */
397
398
399/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
400 * PyObject* parser_issuite(PyObject* self, PyObject* args)
401 *
402 * Checks the passed-in AST object to determine if it is an expression or
403 * a statement suite, respectively. The return is a Python truth value.
404 *
405 */
406static PyObject*
407parser_isexpr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000408 PyObject *self;
409 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000410{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000411 PyAST_Object* ast;
412 PyObject* res = 0;
413
414 if (PyArg_ParseTuple(args, "O!:isexpr", &PyAST_Type, &ast)) {
415 /*
416 * Check to see if the AST represents an expression or not.
417 */
418 res = (ast->ast_type == PyAST_EXPR) ? Py_True : Py_False;
419 Py_INCREF(res);
420 }
421 return (res);
422
423} /* parser_isexpr() */
424
425
426static PyObject*
427parser_issuite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000428 PyObject *self;
429 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000430{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000431 PyAST_Object* ast;
432 PyObject* res = 0;
433
Guido van Rossum3d602e31996-07-21 02:33:56 +0000434 if (PyArg_ParseTuple(args, "O!:issuite", &PyAST_Type, &ast)) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000435 /*
436 * Check to see if the AST represents an expression or not.
437 */
438 res = (ast->ast_type == PyAST_EXPR) ? Py_False : Py_True;
439 Py_INCREF(res);
440 }
441 return (res);
442
443} /* parser_issuite() */
444
445
Guido van Rossum3d602e31996-07-21 02:33:56 +0000446/* err_string(char* message)
447 *
448 * Sets the error string for an exception of type ParserError.
449 *
450 */
451static void
452err_string(message)
453 char *message;
Guido van Rossum47478871996-08-21 14:32:37 +0000454{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000455 PyErr_SetString(parser_error, message);
456
457} /* err_string() */
458
459
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000460/* PyObject* parser_do_parse(PyObject* args, int type)
461 *
462 * Internal function to actually execute the parse and return the result if
463 * successful, or set an exception if not.
464 *
465 */
466static PyObject*
467parser_do_parse(args, type)
468 PyObject *args;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000469 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000470{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000471 char* string = 0;
472 PyObject* res = 0;
473
474 if (PyArg_ParseTuple(args, "s", &string)) {
475 node* n = PyParser_SimpleParseString(string,
476 (type == PyAST_EXPR)
477 ? eval_input : file_input);
478
479 if (n != 0)
480 res = parser_newastobject(n, type);
481 else
Guido van Rossum3d602e31996-07-21 02:33:56 +0000482 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000483 }
484 return (res);
485
486} /* parser_do_parse() */
487
488
489/* PyObject* parser_expr(PyObject* self, PyObject* args)
490 * PyObject* parser_suite(PyObject* self, PyObject* args)
491 *
492 * External interfaces to the parser itself. Which is called determines if
493 * the parser attempts to recognize an expression ('eval' form) or statement
494 * suite ('exec' form). The real work is done by parser_do_parse() above.
495 *
496 */
497static PyObject*
498parser_expr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000499 PyObject *self;
500 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000501{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000502 return (parser_do_parse(args, PyAST_EXPR));
503
504} /* parser_expr() */
505
506
507static PyObject*
508parser_suite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000509 PyObject *self;
510 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000511{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000512 return (parser_do_parse(args, PyAST_SUITE));
513
514} /* parser_suite() */
515
516
517
518/* This is the messy part of the code. Conversion from a tuple to an AST
519 * object requires that the input tuple be valid without having to rely on
520 * catching an exception from the compiler. This is done to allow the
521 * compiler itself to remain fast, since most of its input will come from
522 * the parser directly, and therefore be known to be syntactically correct.
523 * This validation is done to ensure that we don't core dump the compile
524 * phase, returning an exception instead.
525 *
526 * Two aspects can be broken out in this code: creating a node tree from
527 * the tuple passed in, and verifying that it is indeed valid. It may be
528 * advantageous to expand the number of AST types to include funcdefs and
529 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
530 * here. They are not necessary, and not quite as useful in a raw form.
531 * For now, let's get expressions and suites working reliably.
532 */
533
534
Guido van Rossum2a288461996-08-21 21:55:43 +0000535staticforward node* build_node_tree Py_PROTO((PyObject *tuple));
536staticforward int validate_expr_tree Py_PROTO((node *tree));
537staticforward int validate_file_input Py_PROTO((node *tree));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000538
539
540/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
541 *
542 * This is the public function, called from the Python code. It receives a
543 * single tuple object from the caller, and creates an AST object if the
544 * tuple can be validated. It does this by checking the first code of the
545 * tuple, and, if acceptable, builds the internal representation. If this
546 * step succeeds, the internal representation is validated as fully as
547 * possible with the various validate_*() routines defined below.
548 *
549 * This function must be changed if support is to be added for PyAST_FRAGMENT
550 * AST objects.
551 *
552 */
553static PyObject*
554parser_tuple2ast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000555 PyObject *self;
556 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000557{
558 PyObject *ast = 0;
559 PyObject *tuple = 0;
560 PyObject *temp = 0;
561 int ok;
562 int start_sym;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000563
Guido van Rossum47478871996-08-21 14:32:37 +0000564 if (!PyArg_ParseTuple(args, "O:tuple2ast", &tuple))
565 return (0);
566 if (!PySequence_Check(tuple)) {
567 PyErr_SetString(PyExc_ValueError,
568 "tuple2ast() requires a single sequence argument");
569 return (0);
570 }
571 /*
572 * This mess of tests is written this way so we can use the abstract
573 * object interface (AOI). Unfortunately, the AOI increments reference
574 * counts, which requires that we store a pointer to retrieved object
575 * so we can DECREF it after the check. But we really should accept
576 * lists as well as tuples at the very least.
577 */
578 ok = PyObject_Length(tuple) >= 2;
579 if (ok) {
580 temp = PySequence_GetItem(tuple, 0);
581 ok = (temp != NULL) && PyInt_Check(temp);
582 if (ok)
583 /* this is used after the initial checks: */
584 start_sym = PyInt_AsLong(temp);
585 Py_XDECREF(temp);
586 }
587 if (ok) {
588 temp = PySequence_GetItem(tuple, 1);
589 ok = (temp != NULL) && PySequence_Check(temp);
590 Py_XDECREF(temp);
591 }
592 if (ok) {
593 temp = PySequence_GetItem(tuple, 1);
594 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
595 if (ok) {
596 PyObject *temp2 = PySequence_GetItem(temp, 0);
597 if (temp2 != NULL) {
598 ok = PyInt_Check(temp2);
599 Py_DECREF(temp2);
600 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000601 }
Guido van Rossum47478871996-08-21 14:32:37 +0000602 Py_XDECREF(temp);
603 }
604 /* If we've failed at some point, get out of here. */
605 if (!ok) {
606 err_string("malformed sequence for tuple2ast()");
607 return (0);
608 }
609 /*
610 * This might be a valid parse tree, but let's do a quick check
611 * before we jump the gun.
612 */
613 if (start_sym == eval_input) {
614 /* Might be an eval form. */
615 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000616
Guido van Rossum47478871996-08-21 14:32:37 +0000617 if ((expression != 0) && validate_expr_tree(expression))
618 ast = parser_newastobject(expression, PyAST_EXPR);
619 }
620 else if (start_sym == file_input) {
621 /* This looks like an exec form so far. */
622 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000623
Guido van Rossum47478871996-08-21 14:32:37 +0000624 if ((suite_tree != 0) && validate_file_input(suite_tree))
625 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000626 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000627 else
Guido van Rossum47478871996-08-21 14:32:37 +0000628 /* This is a fragment, and is not yet supported. Maybe they
629 * will be if I find a use for them.
630 */
631 err_string("Fragmentary parse trees not supported.");
632
633 /* Make sure we throw an exception on all errors. We should never
634 * get this, but we'd do well to be sure something is done.
635 */
636 if ((ast == 0) && !PyErr_Occurred())
637 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000638
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000639 return (ast);
640
641} /* parser_tuple2ast() */
642
643
644/* int check_terminal_tuple()
645 *
Guido van Rossum47478871996-08-21 14:32:37 +0000646 * Check a tuple to determine that it is indeed a valid terminal
647 * node. The node is known to be required as a terminal, so we throw
648 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000649 *
Guido van Rossum47478871996-08-21 14:32:37 +0000650 * The format of an acceptable terminal tuple is "(is[i])": the fact
651 * that elem is a tuple and the integer is a valid terminal symbol
652 * has been established before this function is called. We must
653 * check the length of the tuple and the type of the second element
654 * and optional third element. We do *NOT* check the actual text of
655 * the string element, which we could do in many cases. This is done
656 * by the validate_*() functions which operate on the internal
657 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000658 */
659static int
Guido van Rossum47478871996-08-21 14:32:37 +0000660check_terminal_tuple(elem)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000661 PyObject *elem;
Guido van Rossum47478871996-08-21 14:32:37 +0000662{
663 int len = PyObject_Length(elem);
664 int res = 1;
665 char* str = "Illegal terminal symbol; bad node length.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000666
Guido van Rossum47478871996-08-21 14:32:37 +0000667 if ((len == 2) || (len == 3)) {
668 PyObject *temp = PySequence_GetItem(elem, 1);
669 res = PyString_Check(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000670 str = "Illegal terminal symbol; expected a string.";
Guido van Rossum47478871996-08-21 14:32:37 +0000671 if (res && (len == 3)) {
672 PyObject* third = PySequence_GetItem(elem, 2);
673 res = PyInt_Check(third);
674 str = "Invalid third element of terminal node.";
675 Py_XDECREF(third);
676 }
677 Py_XDECREF(temp);
678 }
679 else {
680 res = 0;
681 }
682 if (!res) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000683 elem = Py_BuildValue("(os)", elem, str);
684 PyErr_SetObject(parser_error, elem);
685 }
686 return (res);
687
688} /* check_terminal_tuple() */
689
690
691/* node* build_node_children()
692 *
693 * Iterate across the children of the current non-terminal node and build
694 * their structures. If successful, return the root of this portion of
695 * the tree, otherwise, 0. Any required exception will be specified already,
696 * and no memory will have been deallocated.
697 *
698 */
699static node*
700build_node_children(tuple, root, line_num)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000701 PyObject *tuple;
702 node *root;
703 int *line_num;
Guido van Rossum47478871996-08-21 14:32:37 +0000704{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000705 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000706 int i;
707
708 for (i = 1; i < len; ++i) {
709 /* elem must always be a tuple, however simple */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000710 PyObject* elem = PySequence_GetItem(tuple, i);
Guido van Rossum47478871996-08-21 14:32:37 +0000711 int ok = elem != NULL;
712 long type = 0;
713 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000714
Guido van Rossum47478871996-08-21 14:32:37 +0000715 if (ok)
716 ok = PySequence_Check(elem);
717 if (ok) {
718 PyObject *temp = PySequence_GetItem(elem, 0);
719 if (temp == NULL)
720 ok = 0;
721 else {
722 ok = PyInt_Check(temp);
723 if (ok)
724 type = PyInt_AsLong(temp);
725 Py_DECREF(temp);
726 }
727 }
728 if (!ok) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000729 PyErr_SetObject(parser_error,
730 Py_BuildValue("(os)", elem,
731 "Illegal node construct."));
Guido van Rossum47478871996-08-21 14:32:37 +0000732 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000733 return (0);
734 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000735 if (ISTERMINAL(type)) {
Guido van Rossum47478871996-08-21 14:32:37 +0000736 if (check_terminal_tuple(elem)) {
737 PyObject *temp = PySequence_GetItem(elem, 1);
738
739 strn = strdup(PyString_AsString(temp));
740 Py_XDECREF(temp);
741
742 if (PyObject_Length(elem) == 3) {
743 PyObject* temp = PySequence_GetItem(elem, 2);
744 *line_num = PyInt_AsLong(temp);
745 Py_DECREF(temp);
746 }
747 }
748 else {
749 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000750 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000751 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000752 }
753 else if (!ISNONTERMINAL(type)) {
754 /*
755 * It has to be one or the other; this is an error.
756 * Throw an exception.
757 */
758 PyErr_SetObject(parser_error,
759 Py_BuildValue("(os)", elem,
760 "Unknown node type."));
Guido van Rossum47478871996-08-21 14:32:37 +0000761 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000762 return (0);
763 }
764 PyNode_AddChild(root, type, strn, *line_num);
765
766 if (ISNONTERMINAL(type)) {
767 node* new_child = CHILD(root, i - 1);
768
Guido van Rossum47478871996-08-21 14:32:37 +0000769 if (new_child != build_node_children(elem, new_child, line_num)) {
770 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000771 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000772 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000773 }
Guido van Rossum47478871996-08-21 14:32:37 +0000774 else if (type == NEWLINE) { /* It's true: we increment the */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000775 ++(*line_num); /* line number *after* the newline! */
Guido van Rossum47478871996-08-21 14:32:37 +0000776 }
777 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000778 }
779 return (root);
780
781} /* build_node_children() */
782
783
784static node*
785build_node_tree(tuple)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000786 PyObject *tuple;
Guido van Rossum47478871996-08-21 14:32:37 +0000787{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000788 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000789 PyObject *temp = PySequence_GetItem(tuple, 0);
790 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000791
Guido van Rossum47478871996-08-21 14:32:37 +0000792 if (temp != NULL)
793 num = PyInt_AsLong(temp);
794 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000795 if (ISTERMINAL(num)) {
796 /*
797 * The tuple is simple, but it doesn't start with a start symbol.
798 * Throw an exception now and be done with it.
799 */
800 tuple = Py_BuildValue("(os)", tuple,
Guido van Rossum3d602e31996-07-21 02:33:56 +0000801 "Illegal ast tuple; cannot start with terminal symbol.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000802 PyErr_SetObject(parser_error, tuple);
803 }
804 else if (ISNONTERMINAL(num)) {
805 /*
806 * Not efficient, but that can be handled later.
807 */
808 int line_num = 0;
809
810 res = PyNode_New(num);
811 if (res != build_node_children(tuple, res, &line_num)) {
812 PyNode_Free(res);
813 res = 0;
814 }
815 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000816 else
817 /* The tuple is illegal -- if the number is neither TERMINAL nor
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000818 * NONTERMINAL, we can't use it.
819 */
820 PyErr_SetObject(parser_error,
821 Py_BuildValue("(os)", tuple,
822 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000823
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000824 return (res);
825
826} /* build_node_tree() */
827
828
Guido van Rossum360a9341996-08-21 19:04:10 +0000829#ifdef HAVE_OLD_CPP
Guido van Rossum2a288461996-08-21 21:55:43 +0000830#define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000831#else
Guido van Rossum2a288461996-08-21 21:55:43 +0000832#define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000833#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000834
835
836/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000837 * Validation routines used within the validation section:
838 */
Guido van Rossum2a288461996-08-21 21:55:43 +0000839staticforward int validate_terminal Py_PROTO((node *terminal,
840 int type, char *string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000841
842#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
843#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
844#define validate_colon(ch) validate_terminal(ch, COLON, ":")
845#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
846#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
847#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000848#define validate_indent(ch) validate_terminal(ch, INDENT, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000849#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000850#define validate_newline(ch) validate_terminal(ch, NEWLINE, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000851#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
852#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
853#define validate_star(ch) validate_terminal(ch, STAR, "*")
854#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000855#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
Guido van Rossum47478871996-08-21 14:32:37 +0000856#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000857#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000858
Guido van Rossum3d602e31996-07-21 02:33:56 +0000859VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000860VALIDATER(class); VALIDATER(node);
861VALIDATER(parameters); VALIDATER(suite);
862VALIDATER(testlist); VALIDATER(varargslist);
863VALIDATER(fpdef); VALIDATER(fplist);
864VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000865VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000866VALIDATER(print_stmt); VALIDATER(del_stmt);
867VALIDATER(return_stmt);
868VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000869VALIDATER(global_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000870VALIDATER(exec_stmt); VALIDATER(compound_stmt);
871VALIDATER(while); VALIDATER(for);
872VALIDATER(try); VALIDATER(except_clause);
873VALIDATER(test); VALIDATER(and_test);
874VALIDATER(not_test); VALIDATER(comparison);
875VALIDATER(comp_op); VALIDATER(expr);
876VALIDATER(xor_expr); VALIDATER(and_expr);
877VALIDATER(shift_expr); VALIDATER(arith_expr);
878VALIDATER(term); VALIDATER(factor);
879VALIDATER(atom); VALIDATER(lambdef);
880VALIDATER(trailer); VALIDATER(subscript);
Guido van Rossum47478871996-08-21 14:32:37 +0000881VALIDATER(subscriptlist); VALIDATER(sliceop);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000882VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000883VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000884
885
886#define is_even(n) (((n) & 1) == 0)
887#define is_odd(n) (((n) & 1) == 1)
888
889
890static int
891validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000892 node *n;
893 int t;
Guido van Rossum47478871996-08-21 14:32:37 +0000894{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000895 int res = (TYPE(n) == t);
896
897 if (!res) {
898 char buffer[128];
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000899 sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000900 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000901 }
902 return (res);
903
904} /* validate_ntype() */
905
906
907static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000908validate_numnodes(n, num, name)
909 node *n;
910 int num;
911 const char *const name;
Guido van Rossum47478871996-08-21 14:32:37 +0000912{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000913 if (NCH(n) != num) {
914 char buff[60];
915 sprintf(buff, "Illegal number of children for %s node.", name);
916 err_string(buff);
917 }
918 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000919
Guido van Rossum3d602e31996-07-21 02:33:56 +0000920} /* validate_numnodes() */
921
922
923static int
924validate_terminal(terminal, type, string)
925 node *terminal;
926 int type;
927 char *string;
Guido van Rossum47478871996-08-21 14:32:37 +0000928{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000929 int res = (validate_ntype(terminal, type)
930 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
931
932 if (!res && !PyErr_Occurred()) {
933 char buffer[60];
934 sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
935 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000936 }
937 return (res);
938
939} /* validate_terminal() */
940
941
Guido van Rossum47478871996-08-21 14:32:37 +0000942/* X (',' X) [',']
943 */
944static int
945validate_repeating_list(tree, ntype, vfunc, name)
946 node *tree;
947 int ntype;
948 int (*vfunc)();
949 const char *const name;
950{
951 int nch = NCH(tree);
952 int res = (nch && validate_ntype(tree, ntype)
953 && vfunc(CHILD(tree, 0)));
954
955 if (!res && !PyErr_Occurred())
956 validate_numnodes(tree, 1, name);
957 else {
958 if (is_even(nch))
959 res = validate_comma(CHILD(tree, --nch));
960 if (res && nch > 1) {
961 int pos = 1;
962 for ( ; res && pos < nch; pos += 2)
963 res = (validate_comma(CHILD(tree, pos))
964 && vfunc(CHILD(tree, pos + 1)));
965 }
966 }
967 return (res);
968
969} /* validate_repeating_list() */
970
971
Guido van Rossum3d602e31996-07-21 02:33:56 +0000972/* VALIDATE(class)
973 *
974 * classdef:
975 * 'class' NAME ['(' testlist ')'] ':' suite
976 */
Guido van Rossum47478871996-08-21 14:32:37 +0000977static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000978validate_class(tree)
979 node *tree;
980{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000981 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000982 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000983
Guido van Rossum3d602e31996-07-21 02:33:56 +0000984 if (res) {
985 res = (validate_name(CHILD(tree, 0), "class")
986 && validate_ntype(CHILD(tree, 1), NAME)
987 && validate_colon(CHILD(tree, nch - 2))
988 && validate_suite(CHILD(tree, nch - 1)));
989 }
990 else
991 validate_numnodes(tree, 4, "class");
992 if (res && (nch == 7)) {
993 res = (validate_lparen(CHILD(tree, 2))
994 && validate_testlist(CHILD(tree, 3))
995 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000996 }
997 return (res);
998
999} /* validate_class() */
1000
1001
Guido van Rossum3d602e31996-07-21 02:33:56 +00001002/* if_stmt:
1003 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1004 */
Guido van Rossum47478871996-08-21 14:32:37 +00001005static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001006validate_if(tree)
1007 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001008{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001009 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001010 int res = (validate_ntype(tree, if_stmt)
1011 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001012 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +00001013 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001014 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001015 && validate_suite(CHILD(tree, 3)));
1016
1017 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001018 /* ... 'else' ':' suite */
1019 res = (validate_name(CHILD(tree, nch - 3), "else")
1020 && validate_colon(CHILD(tree, nch - 2))
1021 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001022 nch -= 3;
1023 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001024 else if (!res && !PyErr_Occurred())
1025 validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001026 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001027 /* Will catch the case for nch < 4 */
1028 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001029 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001030 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001031 int j = 4;
1032 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001033 res = (validate_name(CHILD(tree, j), "elif")
1034 && validate_colon(CHILD(tree, j + 2))
1035 && validate_test(CHILD(tree, j + 1))
1036 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001037 j += 4;
1038 }
1039 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001040 return (res);
1041
1042} /* validate_if() */
1043
1044
Guido van Rossum3d602e31996-07-21 02:33:56 +00001045/* parameters:
1046 * '(' [varargslist] ')'
1047 *
1048 */
Guido van Rossum47478871996-08-21 14:32:37 +00001049static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001050validate_parameters(tree)
1051 node *tree;
1052{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001053 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001054 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001055
Guido van Rossum3d602e31996-07-21 02:33:56 +00001056 if (res) {
1057 res = (validate_lparen(CHILD(tree, 0))
1058 && validate_rparen(CHILD(tree, nch - 1)));
1059 if (res && (nch == 3))
1060 res = validate_varargslist(CHILD(tree, 1));
1061 }
1062 else
1063 validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001064
1065 return (res);
1066
1067} /* validate_parameters() */
1068
1069
Guido van Rossum3d602e31996-07-21 02:33:56 +00001070/* VALIDATE(suite)
1071 *
1072 * suite:
1073 * simple_stmt
1074 * | NEWLINE INDENT stmt+ DEDENT
1075 */
Guido van Rossum47478871996-08-21 14:32:37 +00001076static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001077validate_suite(tree)
1078 node *tree;
1079{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001080 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001081 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001082
Guido van Rossum3d602e31996-07-21 02:33:56 +00001083 if (res && (nch == 1))
1084 res = validate_simple_stmt(CHILD(tree, 0));
1085 else if (res) {
1086 /* NEWLINE INDENT stmt+ DEDENT */
1087 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001088 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001089 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001090 && validate_dedent(CHILD(tree, nch - 1)));
1091
Guido van Rossum3d602e31996-07-21 02:33:56 +00001092 if (res && (nch > 4)) {
1093 int i = 3;
1094 --nch; /* forget the DEDENT */
1095 for ( ; res && (i < nch); ++i)
1096 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001097 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001098 else if (nch < 4)
1099 validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001100 }
1101 return (res);
1102
1103} /* validate_suite() */
1104
1105
Guido van Rossum47478871996-08-21 14:32:37 +00001106static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001107validate_testlist(tree)
1108 node *tree;
1109{
Guido van Rossum47478871996-08-21 14:32:37 +00001110 return (validate_repeating_list(tree, testlist,
1111 validate_test, "testlist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001112
1113} /* validate_testlist() */
1114
1115
Guido van Rossum3d602e31996-07-21 02:33:56 +00001116/* VALIDATE(varargslist)
1117 *
1118 * varargslist:
1119 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1120 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1121 *
1122 * (fpdef ['=' test] ',')*
1123 * ('*' NAME [',' ('**'|'*' '*') NAME]
1124 * | ('**'|'*' '*') NAME)
1125 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1126 *
1127 */
Guido van Rossum47478871996-08-21 14:32:37 +00001128static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001129validate_varargslist(tree)
1130 node *tree;
1131{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001132 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001133 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001134
Guido van Rossum3d602e31996-07-21 02:33:56 +00001135 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1136 /* (fpdef ['=' test] ',')*
1137 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1138 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001139 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001140 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001141
Guido van Rossum3d602e31996-07-21 02:33:56 +00001142 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1143 res = validate_fpdef(CHILD(tree, pos));
1144 if (res) {
1145 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1146 res = validate_test(CHILD(tree, pos + 2));
1147 pos += 2;
1148 }
1149 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001150 pos += 2;
1151 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001152 }
1153 if (res) {
1154 remaining = nch - pos;
1155 res = ((remaining == 2) || (remaining == 3)
1156 || (remaining == 5) || (remaining == 6));
1157 if (!res)
1158 validate_numnodes(tree, 2, "varargslist");
1159 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1160 return ((remaining == 2)
1161 && validate_ntype(CHILD(tree, pos+1), NAME));
1162 else {
1163 res = validate_star(CHILD(tree, pos++));
1164 --remaining;
1165 }
1166 }
1167 if (res) {
1168 if (remaining == 2) {
1169 res = (validate_star(CHILD(tree, pos))
1170 && validate_ntype(CHILD(tree, pos + 1), NAME));
1171 }
1172 else {
1173 res = validate_ntype(CHILD(tree, pos++), NAME);
1174 if (res && (remaining >= 4)) {
1175 res = validate_comma(CHILD(tree, pos));
1176 if (--remaining == 3)
Fred Drakee1607a81996-09-11 21:58:26 +00001177 res = (validate_star(CHILD(tree, pos + 1))
1178 && validate_star(CHILD(tree, pos + 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001179 else
1180 validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1181 }
1182 }
1183 }
1184 if (!res && !PyErr_Occurred())
1185 err_string("Incorrect validation of variable arguments list.");
1186 }
1187 else if (res) {
1188 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1189 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1190 --nch;
1191
1192 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1193 res = (is_odd(nch)
1194 && validate_fpdef(CHILD(tree, 0)));
1195
1196 if (res && (nch > 1)) {
1197 int pos = 1;
1198 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1199 res = validate_test(CHILD(tree, 2));
1200 pos += 2;
1201 }
1202 /* ... (',' fpdef ['=' test])* */
1203 for ( ; res && (pos < nch); pos += 2) {
1204 /* ',' fpdef */
1205 res = (validate_comma(CHILD(tree, pos))
1206 && validate_fpdef(CHILD(tree, pos + 1)));
1207 if (res
1208 && ((nch - pos) > 2)
1209 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1210 /* ['=' test] */
1211 res = validate_test(CHILD(tree, pos + 3));
1212 pos += 2;
1213 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001214 }
1215 }
1216 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001217 else
1218 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001219
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001220 return (res);
1221
1222} /* validate_varargslist() */
1223
1224
Guido van Rossum3d602e31996-07-21 02:33:56 +00001225/* VALIDATE(fpdef)
1226 *
1227 * fpdef:
1228 * NAME
1229 * | '(' fplist ')'
1230 */
Guido van Rossum47478871996-08-21 14:32:37 +00001231static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001232validate_fpdef(tree)
1233 node *tree;
1234{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001235 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001236 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001237
Guido van Rossum3d602e31996-07-21 02:33:56 +00001238 if (res) {
1239 if (nch == 1)
1240 res = validate_ntype(CHILD(tree, 0), NAME);
1241 else if (nch == 3)
1242 res = (validate_lparen(CHILD(tree, 0))
1243 && validate_fplist(CHILD(tree, 1))
1244 && validate_rparen(CHILD(tree, 2)));
1245 else
1246 validate_numnodes(tree, 1, "fpdef");
1247 }
1248 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001249
1250} /* validate_fpdef() */
1251
1252
Guido van Rossum47478871996-08-21 14:32:37 +00001253static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001254validate_fplist(tree)
1255 node *tree;
1256{
Guido van Rossum47478871996-08-21 14:32:37 +00001257 return (validate_repeating_list(tree, fplist,
1258 validate_fpdef, "fplist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001259
1260} /* validate_fplist() */
1261
1262
Guido van Rossum3d602e31996-07-21 02:33:56 +00001263/* simple_stmt | compound_stmt
1264 *
1265 */
Guido van Rossum47478871996-08-21 14:32:37 +00001266static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001267validate_stmt(tree)
1268 node *tree;
1269{
1270 int res = (validate_ntype(tree, stmt)
1271 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001272
Guido van Rossum3d602e31996-07-21 02:33:56 +00001273 if (res) {
1274 tree = CHILD(tree, 0);
1275
1276 if (TYPE(tree) == simple_stmt)
1277 res = validate_simple_stmt(tree);
1278 else
1279 res = validate_compound_stmt(tree);
1280 }
1281 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001282
1283} /* validate_stmt() */
1284
1285
Guido van Rossum3d602e31996-07-21 02:33:56 +00001286/* small_stmt (';' small_stmt)* [';'] NEWLINE
1287 *
1288 */
Guido van Rossum47478871996-08-21 14:32:37 +00001289static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001290validate_simple_stmt(tree)
1291 node *tree;
1292{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001293 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001294 int res = (validate_ntype(tree, simple_stmt)
1295 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001296 && validate_small_stmt(CHILD(tree, 0))
1297 && validate_newline(CHILD(tree, nch - 1)));
1298
Guido van Rossum3d602e31996-07-21 02:33:56 +00001299 if (nch < 2)
1300 res = validate_numnodes(tree, 2, "simple_stmt");
1301 --nch; /* forget the NEWLINE */
1302 if (res && is_even(nch))
1303 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001304 if (res && (nch > 2)) {
1305 int i;
1306
Guido van Rossum3d602e31996-07-21 02:33:56 +00001307 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001308 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001309 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001310 }
1311 return (res);
1312
1313} /* validate_simple_stmt() */
1314
1315
Guido van Rossum47478871996-08-21 14:32:37 +00001316static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001317validate_small_stmt(tree)
1318 node *tree;
1319{
1320 int nch = NCH(tree);
1321 int res = (validate_numnodes(tree, 1, "small_stmt")
1322 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1323 || (TYPE(CHILD(tree, 0)) == print_stmt)
1324 || (TYPE(CHILD(tree, 0)) == del_stmt)
1325 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1326 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1327 || (TYPE(CHILD(tree, 0)) == import_stmt)
1328 || (TYPE(CHILD(tree, 0)) == global_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001329 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1330
1331 if (res)
1332 res = validate_node(CHILD(tree, 0));
1333 else if (nch == 1) {
1334 char buffer[60];
1335 sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1336 TYPE(CHILD(tree, 0)));
1337 err_string(buffer);
1338 }
1339 return (res);
1340
1341} /* validate_small_stmt */
1342
1343
1344/* compound_stmt:
1345 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1346 */
Guido van Rossum47478871996-08-21 14:32:37 +00001347static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001348validate_compound_stmt(tree)
1349 node *tree;
1350{
1351 int res = (validate_ntype(tree, compound_stmt)
1352 && validate_numnodes(tree, 1, "compound_stmt"));
1353
1354 if (!res)
1355 return (0);
1356
1357 tree = CHILD(tree, 0);
1358 res = ((TYPE(tree) == if_stmt)
1359 || (TYPE(tree) == while_stmt)
1360 || (TYPE(tree) == for_stmt)
1361 || (TYPE(tree) == try_stmt)
1362 || (TYPE(tree) == funcdef)
1363 || (TYPE(tree) == classdef));
1364 if (res)
1365 res = validate_node(tree);
1366 else {
1367 char buffer[60];
1368 sprintf(buffer, "Illegal compound statement type: %d.", TYPE(tree));
1369 err_string(buffer);
1370 }
1371 return (res);
1372
1373} /* validate_compound_stmt() */
1374
1375
Guido van Rossum47478871996-08-21 14:32:37 +00001376static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001377validate_expr_stmt(tree)
1378 node *tree;
1379{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001380 int j;
1381 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001382 int res = (validate_ntype(tree, expr_stmt)
1383 && is_odd(nch)
1384 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001385
Guido van Rossum3d602e31996-07-21 02:33:56 +00001386 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001387 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001388 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001389
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001390 return (res);
1391
1392} /* validate_expr_stmt() */
1393
1394
Guido van Rossum3d602e31996-07-21 02:33:56 +00001395/* print_stmt:
1396 *
1397 * 'print' (test ',')* [test]
1398 *
1399 */
Guido van Rossum47478871996-08-21 14:32:37 +00001400static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001401validate_print_stmt(tree)
1402 node *tree;
1403{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001404 int j;
1405 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001406 int res = (validate_ntype(tree, print_stmt)
1407 && (nch != 0)
1408 && validate_name(CHILD(tree, 0), "print"));
1409
1410 if (res && is_even(nch)) {
1411 res = validate_test(CHILD(tree, nch - 1));
1412 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001413 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001414 else if (!res && !PyErr_Occurred())
1415 validate_numnodes(tree, 1, "print_stmt");
1416 for (j = 1; res && (j < nch); j += 2)
1417 res = (validate_test(CHILD(tree, j))
1418 && validate_ntype(CHILD(tree, j + 1), COMMA));
1419
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001420 return (res);
1421
1422} /* validate_print_stmt() */
1423
1424
Guido van Rossum47478871996-08-21 14:32:37 +00001425static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001426validate_del_stmt(tree)
1427 node *tree;
1428{
1429 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001430 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001431 && validate_exprlist(CHILD(tree, 1)));
1432
1433} /* validate_del_stmt() */
1434
1435
Guido van Rossum47478871996-08-21 14:32:37 +00001436static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001437validate_return_stmt(tree)
1438 node *tree;
1439{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001440 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001441 int res = (validate_ntype(tree, return_stmt)
1442 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001443 && validate_name(CHILD(tree, 0), "return"));
1444
Guido van Rossum3d602e31996-07-21 02:33:56 +00001445 if (res && (nch == 2))
1446 res = validate_testlist(CHILD(tree, 1));
1447
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001448 return (res);
1449
1450} /* validate_return_stmt() */
1451
1452
Guido van Rossum47478871996-08-21 14:32:37 +00001453static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001454validate_raise_stmt(tree)
1455 node *tree;
1456{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001457 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001458 int res = (validate_ntype(tree, raise_stmt)
1459 && ((nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001460
Guido van Rossum3d602e31996-07-21 02:33:56 +00001461 if (res) {
1462 res = (validate_name(CHILD(tree, 0), "raise")
1463 && validate_test(CHILD(tree, 1)));
1464 if (res && nch > 2) {
1465 res = (validate_comma(CHILD(tree, 2))
1466 && validate_test(CHILD(tree, 3)));
1467 if (res && (nch > 4))
1468 res = (validate_comma(CHILD(tree, 4))
1469 && validate_test(CHILD(tree, 5)));
1470 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001471 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001472 else
1473 validate_numnodes(tree, 2, "raise");
1474 if (res && (nch == 4))
1475 res = (validate_comma(CHILD(tree, 2))
1476 && validate_test(CHILD(tree, 3)));
1477
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001478 return (res);
1479
1480} /* validate_raise_stmt() */
1481
1482
Guido van Rossum3d602e31996-07-21 02:33:56 +00001483/* import_stmt:
1484 *
1485 * 'import' dotted_name (',' dotted_name)*
1486 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1487 */
Guido van Rossum47478871996-08-21 14:32:37 +00001488static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001489validate_import_stmt(tree)
1490 node *tree;
1491{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001492 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001493 int res = (validate_ntype(tree, import_stmt)
1494 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001495 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001496 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001497
1498 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001499 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001500
Guido van Rossum3d602e31996-07-21 02:33:56 +00001501 for (j = 2; res && (j < nch); j += 2)
1502 res = (validate_comma(CHILD(tree, j))
1503 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001504 }
1505 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001506 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001507 && validate_name(CHILD(tree, 2), "import"));
1508 if (nch == 4) {
1509 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001510 || (TYPE(CHILD(tree, 3)) == STAR));
1511 if (!res)
1512 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001513 }
1514 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001515 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001516 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001517 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001518 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001519 res = (validate_comma(CHILD(tree, j))
1520 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001521 }
1522 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001523 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001524 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001525
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001526 return (res);
1527
1528} /* validate_import_stmt() */
1529
1530
Guido van Rossum47478871996-08-21 14:32:37 +00001531static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001532validate_global_stmt(tree)
1533 node *tree;
1534{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001535 int j;
1536 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001537 int res = (validate_ntype(tree, global_stmt)
1538 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001539
Guido van Rossum3d602e31996-07-21 02:33:56 +00001540 if (res)
1541 res = (validate_name(CHILD(tree, 0), "global")
1542 && validate_ntype(CHILD(tree, 1), NAME));
1543 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001544 res = (validate_comma(CHILD(tree, j))
1545 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001546
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001547 return (res);
1548
1549} /* validate_global_stmt() */
1550
1551
Guido van Rossum3d602e31996-07-21 02:33:56 +00001552/* exec_stmt:
1553 *
1554 * 'exec' expr ['in' test [',' test]]
1555 */
Guido van Rossum47478871996-08-21 14:32:37 +00001556static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001557validate_exec_stmt(tree)
1558 node *tree;
1559{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001560 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001561 int res = (validate_ntype(tree, exec_stmt)
1562 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001563 && validate_name(CHILD(tree, 0), "exec")
1564 && validate_expr(CHILD(tree, 1)));
1565
Guido van Rossum3d602e31996-07-21 02:33:56 +00001566 if (!res && !PyErr_Occurred())
1567 err_string("Illegal exec statement.");
1568 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001569 res = (validate_name(CHILD(tree, 2), "in")
1570 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001571 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001572 res = (validate_comma(CHILD(tree, 4))
1573 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001574
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001575 return (res);
1576
1577} /* validate_exec_stmt() */
1578
1579
Guido van Rossum47478871996-08-21 14:32:37 +00001580static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001581validate_while(tree)
1582 node *tree;
1583{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001584 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001585 int res = (validate_ntype(tree, while_stmt)
1586 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001587 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001588 && validate_test(CHILD(tree, 1))
1589 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001590 && validate_suite(CHILD(tree, 3)));
1591
Guido van Rossum3d602e31996-07-21 02:33:56 +00001592 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001593 res = (validate_name(CHILD(tree, 4), "else")
1594 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001595 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001596
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001597 return (res);
1598
1599} /* validate_while() */
1600
1601
Guido van Rossum47478871996-08-21 14:32:37 +00001602static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001603validate_for(tree)
1604 node *tree;
1605{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001606 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001607 int res = (validate_ntype(tree, for_stmt)
1608 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001609 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001610 && validate_exprlist(CHILD(tree, 1))
1611 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001612 && validate_testlist(CHILD(tree, 3))
1613 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001614 && validate_suite(CHILD(tree, 5)));
1615
Guido van Rossum3d602e31996-07-21 02:33:56 +00001616 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001617 res = (validate_name(CHILD(tree, 6), "else")
1618 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001619 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001620
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001621 return (res);
1622
1623} /* validate_for() */
1624
1625
Guido van Rossum3d602e31996-07-21 02:33:56 +00001626/* try_stmt:
1627 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1628 * | 'try' ':' suite 'finally' ':' suite
1629 *
1630 */
Guido van Rossum47478871996-08-21 14:32:37 +00001631static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001632validate_try(tree)
1633 node *tree;
1634{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001635 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001636 int pos = 3;
1637 int res = (validate_ntype(tree, try_stmt)
1638 && (nch >= 6) && ((nch % 3) == 0));
1639
1640 if (res)
1641 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001642 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001643 && validate_suite(CHILD(tree, 2))
1644 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001645 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001646 else {
1647 const char* name = "execpt";
1648 char buffer[60];
1649 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1650 name = STR(CHILD(tree, nch - 3));
1651 sprintf(buffer, "Illegal number of children for try/%s node.", name);
1652 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001653 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001654 /* Skip past except_clause sections: */
1655 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1656 res = (validate_except_clause(CHILD(tree, pos))
1657 && validate_colon(CHILD(tree, pos + 1))
1658 && validate_suite(CHILD(tree, pos + 2)));
1659 pos += 3;
1660 }
1661 if (res && (pos < nch)) {
1662 res = validate_ntype(CHILD(tree, pos), NAME);
1663 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1664 res = (validate_numnodes(tree, 6, "try/finally")
1665 && validate_colon(CHILD(tree, 4))
1666 && validate_suite(CHILD(tree, 5)));
1667 else if (res)
1668 if (nch == (pos + 3)) {
1669 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1670 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1671 if (!res)
1672 err_string("Illegal trailing triple in try statement.");
1673 }
1674 else if (nch == (pos + 6))
1675 res = (validate_name(CHILD(tree, pos), "except")
1676 && validate_colon(CHILD(tree, pos + 1))
1677 && validate_suite(CHILD(tree, pos + 2))
1678 && validate_name(CHILD(tree, pos + 3), "else"));
1679 else
1680 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001681 }
1682 return (res);
1683
1684} /* validate_try() */
1685
1686
Guido van Rossum47478871996-08-21 14:32:37 +00001687static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001688validate_except_clause(tree)
1689 node *tree;
1690{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001691 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001692 int res = (validate_ntype(tree, except_clause)
1693 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001694 && validate_name(CHILD(tree, 0), "except"));
1695
Guido van Rossum3d602e31996-07-21 02:33:56 +00001696 if (res && (nch > 1))
1697 res = validate_test(CHILD(tree, 1));
1698 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001699 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001700 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001701
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001702 return (res);
1703
1704} /* validate_except_clause() */
1705
1706
Guido van Rossum47478871996-08-21 14:32:37 +00001707static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001708validate_test(tree)
1709 node *tree;
1710{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001711 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001712 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001713
Guido van Rossum3d602e31996-07-21 02:33:56 +00001714 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001715 res = ((nch == 1)
1716 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001717 else if (res) {
1718 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001719 res = validate_and_test(CHILD(tree, 0));
1720 for (pos = 1; res && (pos < nch); pos += 2)
1721 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001722 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001723 }
1724 return (res);
1725
1726} /* validate_test() */
1727
1728
Guido van Rossum47478871996-08-21 14:32:37 +00001729static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001730validate_and_test(tree)
1731 node *tree;
1732{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001733 int pos;
1734 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001735 int res = (validate_ntype(tree, and_test)
1736 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001737 && validate_not_test(CHILD(tree, 0)));
1738
Guido van Rossum3d602e31996-07-21 02:33:56 +00001739 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001740 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001741 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001742
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001743 return (res);
1744
1745} /* validate_and_test() */
1746
1747
Guido van Rossum47478871996-08-21 14:32:37 +00001748static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001749validate_not_test(tree)
1750 node *tree;
1751{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001752 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001753 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001754
Guido van Rossum3d602e31996-07-21 02:33:56 +00001755 if (res) {
1756 if (nch == 2)
1757 res = (validate_name(CHILD(tree, 0), "not")
1758 && validate_not_test(CHILD(tree, 1)));
1759 else if (nch == 1)
1760 res = validate_comparison(CHILD(tree, 0));
1761 }
1762 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001763
1764} /* validate_not_test() */
1765
1766
Guido van Rossum47478871996-08-21 14:32:37 +00001767static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001768validate_comparison(tree)
1769 node *tree;
1770{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001771 int pos;
1772 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001773 int res = (validate_ntype(tree, comparison)
1774 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001775 && validate_expr(CHILD(tree, 0)));
1776
Guido van Rossum3d602e31996-07-21 02:33:56 +00001777 for (pos = 1; res && (pos < nch); pos += 2)
1778 res = (validate_comp_op(CHILD(tree, pos))
1779 && validate_expr(CHILD(tree, pos + 1)));
1780
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001781 return (res);
1782
1783} /* validate_comparison() */
1784
1785
Guido van Rossum47478871996-08-21 14:32:37 +00001786static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001787validate_comp_op(tree)
1788 node *tree;
1789{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001790 int res = 0;
1791 int nch = NCH(tree);
1792
Guido van Rossum3d602e31996-07-21 02:33:56 +00001793 if (!validate_ntype(tree, comp_op))
1794 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001795 if (nch == 1) {
1796 /*
1797 * Only child will be a terminal with a well-defined symbolic name
1798 * or a NAME with a string of either 'is' or 'in'
1799 */
1800 tree = CHILD(tree, 0);
1801 switch (TYPE(tree)) {
1802 case LESS:
1803 case GREATER:
1804 case EQEQUAL:
1805 case EQUAL:
1806 case LESSEQUAL:
1807 case GREATEREQUAL:
1808 case NOTEQUAL:
1809 res = 1;
1810 break;
1811 case NAME:
1812 res = ((strcmp(STR(tree), "in") == 0)
1813 || (strcmp(STR(tree), "is") == 0));
1814 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001815 char buff[128];
1816 sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1817 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001818 }
1819 break;
1820 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001821 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001822 break;
1823 }
1824 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001825 else if (res = validate_numnodes(tree, 2, "comp_op")) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001826 res = (validate_ntype(CHILD(tree, 0), NAME)
1827 && validate_ntype(CHILD(tree, 1), NAME)
1828 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1829 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1830 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1831 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001832 if (!res && !PyErr_Occurred())
1833 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001834 }
1835 return (res);
1836
1837} /* validate_comp_op() */
1838
1839
Guido van Rossum47478871996-08-21 14:32:37 +00001840static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001841validate_expr(tree)
1842 node *tree;
1843{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001844 int j;
1845 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001846 int res = (validate_ntype(tree, expr)
1847 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001848 && validate_xor_expr(CHILD(tree, 0)));
1849
Guido van Rossum3d602e31996-07-21 02:33:56 +00001850 for (j = 2; res && (j < nch); j += 2)
1851 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001852 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001853
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001854 return (res);
1855
1856} /* validate_expr() */
1857
1858
Guido van Rossum47478871996-08-21 14:32:37 +00001859static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001860validate_xor_expr(tree)
1861 node *tree;
1862{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001863 int j;
1864 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001865 int res = (validate_ntype(tree, xor_expr)
1866 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001867 && validate_and_expr(CHILD(tree, 0)));
1868
Guido van Rossum3d602e31996-07-21 02:33:56 +00001869 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001870 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001871 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001872
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001873 return (res);
1874
1875} /* validate_xor_expr() */
1876
1877
Guido van Rossum47478871996-08-21 14:32:37 +00001878static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001879validate_and_expr(tree)
1880 node *tree;
1881{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001882 int pos;
1883 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001884 int res = (validate_ntype(tree, and_expr)
1885 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001886 && validate_shift_expr(CHILD(tree, 0)));
1887
Guido van Rossum3d602e31996-07-21 02:33:56 +00001888 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001889 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001890 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001891
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001892 return (res);
1893
1894} /* validate_and_expr() */
1895
1896
1897static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001898validate_chain_two_ops(tree, termvalid, op1, op2)
1899 node *tree;
1900 int (*termvalid)();
1901 int op1;
1902 int op2;
1903 {
1904 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001905 int nch = NCH(tree);
1906 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001907 && (*termvalid)(CHILD(tree, 0)));
1908
Guido van Rossum3d602e31996-07-21 02:33:56 +00001909 for ( ; res && (pos < nch); pos += 2) {
1910 if (TYPE(CHILD(tree, pos)) != op1)
1911 res = validate_ntype(CHILD(tree, pos), op2);
1912 if (res)
1913 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001914 }
1915 return (res);
1916
1917} /* validate_chain_two_ops() */
1918
1919
Guido van Rossum47478871996-08-21 14:32:37 +00001920static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001921validate_shift_expr(tree)
1922 node *tree;
1923{
1924 return (validate_ntype(tree, shift_expr)
1925 && validate_chain_two_ops(tree, validate_arith_expr,
1926 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001927
1928} /* validate_shift_expr() */
1929
1930
Guido van Rossum47478871996-08-21 14:32:37 +00001931static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001932validate_arith_expr(tree)
1933 node *tree;
1934{
1935 return (validate_ntype(tree, arith_expr)
1936 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001937
1938} /* validate_arith_expr() */
1939
1940
Guido van Rossum47478871996-08-21 14:32:37 +00001941static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001942validate_term(tree)
1943 node *tree;
1944{
1945 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001946 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001947 int res = (validate_ntype(tree, term)
1948 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001949 && validate_factor(CHILD(tree, 0)));
1950
Guido van Rossum3d602e31996-07-21 02:33:56 +00001951 for ( ; res && (pos < nch); pos += 2)
1952 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001953 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001954 || (TYPE(CHILD(tree, pos)) == PERCENT))
1955 && validate_factor(CHILD(tree, pos + 1)));
1956
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001957 return (res);
1958
1959} /* validate_term() */
1960
1961
Guido van Rossum3d602e31996-07-21 02:33:56 +00001962/* factor:
1963 *
1964 * factor: ('+'|'-'|'~') factor | power
1965 */
Guido van Rossum47478871996-08-21 14:32:37 +00001966static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001967validate_factor(tree)
1968 node *tree;
1969{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001970 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001971 int res = (validate_ntype(tree, factor)
1972 && (((nch == 2)
1973 && ((TYPE(CHILD(tree, 0)) == PLUS)
1974 || (TYPE(CHILD(tree, 0)) == MINUS)
1975 || (TYPE(CHILD(tree, 0)) == TILDE))
1976 && validate_factor(CHILD(tree, 1)))
1977 || ((nch == 1)
1978 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001979 return (res);
1980
1981} /* validate_factor() */
1982
1983
Guido van Rossum3d602e31996-07-21 02:33:56 +00001984/* power:
1985 *
1986 * power: atom trailer* ('**' factor)*
1987 */
Guido van Rossum47478871996-08-21 14:32:37 +00001988static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001989validate_power(tree)
1990 node *tree;
1991{
1992 int pos = 1;
1993 int nch = NCH(tree);
1994 int res = (validate_ntype(tree, power) && (nch >= 1)
1995 && validate_atom(CHILD(tree, 0)));
1996
1997 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
1998 res = validate_trailer(CHILD(tree, pos++));
1999 if (res && (pos < nch)) {
2000 if (!is_even(nch - pos)) {
2001 err_string("Illegal number of nodes for 'power'.");
2002 return (0);
2003 }
2004 for ( ; res && (pos < (nch - 1)); pos += 2)
2005 res = (validate_doublestar(CHILD(tree, pos))
2006 && validate_factor(CHILD(tree, pos + 1)));
2007 }
2008 return (res);
2009
2010} /* validate_power() */
2011
2012
Guido van Rossum47478871996-08-21 14:32:37 +00002013static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002014validate_atom(tree)
2015 node *tree;
2016{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002017 int pos;
2018 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002019 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002020
2021 if (res) {
2022 switch (TYPE(CHILD(tree, 0))) {
2023 case LPAR:
2024 res = ((nch <= 3)
2025 && (validate_rparen(CHILD(tree, nch - 1))));
2026
Guido van Rossum3d602e31996-07-21 02:33:56 +00002027 if (res && (nch == 3))
2028 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002029 break;
2030 case LSQB:
2031 res = ((nch <= 3)
2032 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2033
Guido van Rossum3d602e31996-07-21 02:33:56 +00002034 if (res && (nch == 3))
2035 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002036 break;
2037 case LBRACE:
2038 res = ((nch <= 3)
2039 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2040
Guido van Rossum3d602e31996-07-21 02:33:56 +00002041 if (res && (nch == 3))
2042 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002043 break;
2044 case BACKQUOTE:
2045 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002046 && validate_testlist(CHILD(tree, 1))
2047 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2048 break;
2049 case NAME:
2050 case NUMBER:
2051 res = (nch == 1);
2052 break;
2053 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002054 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002055 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002056 break;
2057 default:
2058 res = 0;
2059 break;
2060 }
2061 }
2062 return (res);
2063
2064} /* validate_atom() */
2065
2066
Guido van Rossum3d602e31996-07-21 02:33:56 +00002067/* funcdef:
2068 * 'def' NAME parameters ':' suite
2069 *
2070 */
Guido van Rossum47478871996-08-21 14:32:37 +00002071static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002072validate_funcdef(tree)
2073 node *tree;
2074{
2075 return (validate_ntype(tree, funcdef)
2076 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002077 && validate_name(CHILD(tree, 0), "def")
2078 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002079 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002080 && validate_parameters(CHILD(tree, 2))
2081 && validate_suite(CHILD(tree, 4)));
2082
2083} /* validate_funcdef() */
2084
2085
Guido van Rossum47478871996-08-21 14:32:37 +00002086static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002087validate_lambdef(tree)
2088 node *tree;
2089{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002090 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002091 int res = (validate_ntype(tree, lambdef)
2092 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002093 && validate_name(CHILD(tree, 0), "lambda")
2094 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002095 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002096
Guido van Rossum3d602e31996-07-21 02:33:56 +00002097 if (res && (nch == 4))
2098 res = validate_varargslist(CHILD(tree, 1));
2099 else if (!res && !PyErr_Occurred())
2100 validate_numnodes(tree, 3, "lambdef");
2101
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002102 return (res);
2103
2104} /* validate_lambdef() */
2105
2106
Guido van Rossum3d602e31996-07-21 02:33:56 +00002107/* arglist:
2108 *
2109 * argument (',' argument)* [',']
2110 */
Guido van Rossum47478871996-08-21 14:32:37 +00002111static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002112validate_arglist(tree)
2113 node *tree;
2114{
Guido van Rossum47478871996-08-21 14:32:37 +00002115 return (validate_repeating_list(tree, arglist,
2116 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002117
2118} /* validate_arglist() */
2119
2120
2121
2122/* argument:
2123 *
2124 * [test '='] test
2125 */
Guido van Rossum47478871996-08-21 14:32:37 +00002126static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002127validate_argument(tree)
2128 node *tree;
2129{
2130 int nch = NCH(tree);
2131 int res = (validate_ntype(tree, argument)
2132 && ((nch == 1) || (nch == 3))
2133 && validate_test(CHILD(tree, 0)));
2134
2135 if (res && (nch == 3))
2136 res = (validate_equal(CHILD(tree, 1))
2137 && validate_test(CHILD(tree, 2)));
2138
2139 return (res);
2140
2141} /* validate_argument() */
2142
2143
2144
2145/* trailer:
2146 *
Guido van Rossum47478871996-08-21 14:32:37 +00002147 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002148 */
Guido van Rossum47478871996-08-21 14:32:37 +00002149static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002150validate_trailer(tree)
2151 node *tree;
2152{
2153 int nch = NCH(tree);
2154 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002155
2156 if (res) {
2157 switch (TYPE(CHILD(tree, 0))) {
2158 case LPAR:
2159 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002160 if (res && (nch == 3))
2161 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002162 break;
2163 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002164 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002165 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002166 && validate_ntype(CHILD(tree, 2), RSQB));
2167 break;
2168 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002169 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002170 && validate_ntype(CHILD(tree, 1), NAME));
2171 break;
2172 default:
2173 res = 0;
2174 break;
2175 }
2176 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002177 else
2178 validate_numnodes(tree, 2, "trailer");
2179
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002180 return (res);
2181
2182} /* validate_trailer() */
2183
2184
Guido van Rossum47478871996-08-21 14:32:37 +00002185/* subscriptlist:
2186 *
2187 * subscript (',' subscript)* [',']
2188 */
2189static int
2190validate_subscriptlist(tree)
2191 node *tree;
2192{
2193 return (validate_repeating_list(tree, subscriptlist,
2194 validate_subscript, "subscriptlist"));
2195
2196} /* validate_subscriptlist() */
2197
2198
Guido van Rossum3d602e31996-07-21 02:33:56 +00002199/* subscript:
2200 *
Guido van Rossum47478871996-08-21 14:32:37 +00002201 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002202 */
Guido van Rossum47478871996-08-21 14:32:37 +00002203static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002204validate_subscript(tree)
2205 node *tree;
2206{
Guido van Rossum47478871996-08-21 14:32:37 +00002207 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002208 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002209 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002210
Guido van Rossum47478871996-08-21 14:32:37 +00002211 if (!res) {
2212 if (!PyErr_Occurred())
2213 err_string("invalid number of arguments for subscript node");
2214 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002215 }
Guido van Rossum47478871996-08-21 14:32:37 +00002216 if (TYPE(CHILD(tree, 0)) == DOT)
2217 /* take care of ('.' '.' '.') possibility */
2218 return (validate_numnodes(tree, 3, "subscript")
2219 && validate_dot(CHILD(tree, 0))
2220 && validate_dot(CHILD(tree, 1))
2221 && validate_dot(CHILD(tree, 2)));
2222 if (nch == 1) {
2223 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002224 res = validate_test(CHILD(tree, 0));
2225 else
Guido van Rossum47478871996-08-21 14:32:37 +00002226 res = validate_colon(CHILD(tree, 0));
2227 return (res);
2228 }
2229 /* Must be [test] ':' [test] [sliceop],
2230 * but at least one of the optional components will
2231 * be present, but we don't know which yet.
2232 */
2233 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2234 res = validate_test(CHILD(tree, 0));
2235 offset = 1;
2236 }
2237 if (res)
2238 res = validate_colon(CHILD(tree, offset));
2239 if (res) {
2240 int rem = nch - ++offset;
2241 if (rem) {
2242 if (TYPE(CHILD(tree, offset)) == test) {
2243 res = validate_test(CHILD(tree, offset));
2244 ++offset;
2245 --rem;
2246 }
2247 if (res && rem)
2248 res = validate_sliceop(CHILD(tree, offset));
2249 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002250 }
2251 return (res);
2252
2253} /* validate_subscript() */
2254
2255
Guido van Rossum47478871996-08-21 14:32:37 +00002256static int
2257validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002258 node *tree;
2259{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002260 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002261 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2262 && validate_ntype(tree, sliceop);
2263 if (!res && !PyErr_Occurred()) {
2264 validate_numnodes(tree, 1, "sliceop");
2265 res = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002266 }
Guido van Rossum47478871996-08-21 14:32:37 +00002267 if (res)
2268 res = validate_colon(CHILD(tree, 0));
2269 if (res && (nch == 2))
2270 res = validate_test(CHILD(tree, 1));
2271
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002272 return (res);
2273
Guido van Rossum47478871996-08-21 14:32:37 +00002274} /* validate_sliceop() */
2275
2276
2277static int
2278validate_exprlist(tree)
2279 node *tree;
2280{
2281 return (validate_repeating_list(tree, exprlist,
2282 validate_expr, "exprlist"));
2283
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002284} /* validate_exprlist() */
2285
2286
Guido van Rossum47478871996-08-21 14:32:37 +00002287static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002288validate_dictmaker(tree)
2289 node *tree;
2290{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002291 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002292 int res = (validate_ntype(tree, dictmaker)
2293 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002294 && validate_test(CHILD(tree, 0))
2295 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002296 && validate_test(CHILD(tree, 2)));
2297
Guido van Rossum3d602e31996-07-21 02:33:56 +00002298 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002299 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002300 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002301 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002302
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002303 if (res && (nch > 3)) {
2304 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002305 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002306 while (res && (pos < nch)) {
2307 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002308 && validate_test(CHILD(tree, pos + 1))
2309 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002310 && validate_test(CHILD(tree, pos + 3)));
2311 pos += 4;
2312 }
2313 }
2314 return (res);
2315
2316} /* validate_dictmaker() */
2317
2318
Guido van Rossum47478871996-08-21 14:32:37 +00002319static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002320validate_eval_input(tree)
2321 node *tree;
2322{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002323 int pos;
2324 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002325 int res = (validate_ntype(tree, eval_input)
2326 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002327 && validate_testlist(CHILD(tree, 0))
2328 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2329
Guido van Rossum3d602e31996-07-21 02:33:56 +00002330 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002331 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002332
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002333 return (res);
2334
2335} /* validate_eval_input() */
2336
2337
Guido van Rossum47478871996-08-21 14:32:37 +00002338static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002339validate_node(tree)
2340 node *tree;
2341{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002342 int nch = 0; /* num. children on current node */
2343 int res = 1; /* result value */
2344 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002345
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002346 while (res & (tree != 0)) {
2347 nch = NCH(tree);
2348 next = 0;
2349 switch (TYPE(tree)) {
2350 /*
2351 * Definition nodes.
2352 */
2353 case funcdef:
2354 res = validate_funcdef(tree);
2355 break;
2356 case classdef:
2357 res = validate_class(tree);
2358 break;
2359 /*
2360 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002361 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002362 */
2363 case stmt:
2364 res = validate_stmt(tree);
2365 break;
2366 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002367 /*
2368 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum47478871996-08-21 14:32:37 +00002369 * | import_stmt | global_stmt | exec_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002370 */
2371 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002372 break;
2373 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002374 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002375 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2376 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2377 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002378 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2379 if (res)
2380 next = CHILD(tree, 0);
2381 else if (nch == 1)
2382 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002383 break;
2384 /*
2385 * Compound statements.
2386 */
2387 case simple_stmt:
2388 res = validate_simple_stmt(tree);
2389 break;
2390 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002391 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002392 break;
2393 /*
2394 * Fundemental statements.
2395 */
2396 case expr_stmt:
2397 res = validate_expr_stmt(tree);
2398 break;
2399 case print_stmt:
2400 res = validate_print_stmt(tree);
2401 break;
2402 case del_stmt:
2403 res = validate_del_stmt(tree);
2404 break;
2405 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002406 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002407 && validate_name(CHILD(tree, 0), "pass"));
2408 break;
2409 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002410 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002411 && validate_name(CHILD(tree, 0), "break"));
2412 break;
2413 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002414 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002415 && validate_name(CHILD(tree, 0), "continue"));
2416 break;
2417 case return_stmt:
2418 res = validate_return_stmt(tree);
2419 break;
2420 case raise_stmt:
2421 res = validate_raise_stmt(tree);
2422 break;
2423 case import_stmt:
2424 res = validate_import_stmt(tree);
2425 break;
2426 case global_stmt:
2427 res = validate_global_stmt(tree);
2428 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002429 case exec_stmt:
2430 res = validate_exec_stmt(tree);
2431 break;
2432 case if_stmt:
2433 res = validate_if(tree);
2434 break;
2435 case while_stmt:
2436 res = validate_while(tree);
2437 break;
2438 case for_stmt:
2439 res = validate_for(tree);
2440 break;
2441 case try_stmt:
2442 res = validate_try(tree);
2443 break;
2444 case suite:
2445 res = validate_suite(tree);
2446 break;
2447 /*
2448 * Expression nodes.
2449 */
2450 case testlist:
2451 res = validate_testlist(tree);
2452 break;
2453 case test:
2454 res = validate_test(tree);
2455 break;
2456 case and_test:
2457 res = validate_and_test(tree);
2458 break;
2459 case not_test:
2460 res = validate_not_test(tree);
2461 break;
2462 case comparison:
2463 res = validate_comparison(tree);
2464 break;
2465 case exprlist:
2466 res = validate_exprlist(tree);
2467 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002468 case comp_op:
2469 res = validate_comp_op(tree);
2470 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002471 case expr:
2472 res = validate_expr(tree);
2473 break;
2474 case xor_expr:
2475 res = validate_xor_expr(tree);
2476 break;
2477 case and_expr:
2478 res = validate_and_expr(tree);
2479 break;
2480 case shift_expr:
2481 res = validate_shift_expr(tree);
2482 break;
2483 case arith_expr:
2484 res = validate_arith_expr(tree);
2485 break;
2486 case term:
2487 res = validate_term(tree);
2488 break;
2489 case factor:
2490 res = validate_factor(tree);
2491 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002492 case power:
2493 res = validate_power(tree);
2494 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002495 case atom:
2496 res = validate_atom(tree);
2497 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002498
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002499 default:
2500 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002501 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002502 res = 0;
2503 break;
2504 }
2505 tree = next;
2506 }
2507 return (res);
2508
2509} /* validate_node() */
2510
2511
Guido van Rossum47478871996-08-21 14:32:37 +00002512static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002513validate_expr_tree(tree)
2514 node *tree;
2515{
2516 int res = validate_eval_input(tree);
2517
2518 if (!res && !PyErr_Occurred())
2519 err_string("Could not validate expression tuple.");
2520
2521 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002522
2523} /* validate_expr_tree() */
2524
2525
Guido van Rossum3d602e31996-07-21 02:33:56 +00002526/* file_input:
2527 * (NEWLINE | stmt)* ENDMARKER
2528 */
Guido van Rossum47478871996-08-21 14:32:37 +00002529static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002530validate_file_input(tree)
2531 node *tree;
2532{
2533 int j = 0;
2534 int nch = NCH(tree) - 1;
2535 int res = ((nch >= 0)
2536 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002537
Guido van Rossum3d602e31996-07-21 02:33:56 +00002538 for ( ; res && (j < nch); ++j) {
2539 if (TYPE(CHILD(tree, j)) == stmt)
2540 res = validate_stmt(CHILD(tree, j));
2541 else
2542 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002543 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002544 /* This stays in to prevent any internal failues from getting to the
2545 * user. Hopefully, this won't be needed. If a user reports getting
2546 * this, we have some debugging to do.
2547 */
2548 if (!res && !PyErr_Occurred())
2549 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2550
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002551 return (res);
2552
Guido van Rossum2a288461996-08-21 21:55:43 +00002553} /* validate_file_input() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002554
2555
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002556/* Functions exported by this module. Most of this should probably
2557 * be converted into an AST object with methods, but that is better
2558 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002559 * We'd really have to write a wrapper around it all anyway to allow
2560 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002561 */
2562static PyMethodDef parser_functions[] = {
Guido van Rossum3d602e31996-07-21 02:33:56 +00002563 {"ast2tuple", parser_ast2tuple, 1,
2564 "Creates a tuple-tree representation of an AST."},
Guido van Rossum47478871996-08-21 14:32:37 +00002565 {"ast2list", parser_ast2list, 1,
2566 "Creates a list-tree representation of an AST."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002567 {"compileast", parser_compileast, 1,
2568 "Compiles an AST object into a code object."},
2569 {"expr", parser_expr, 1,
2570 "Creates an AST object from an expression."},
2571 {"isexpr", parser_isexpr, 1,
2572 "Determines if an AST object was created from an expression."},
2573 {"issuite", parser_issuite, 1,
2574 "Determines if an AST object was created from a suite."},
2575 {"suite", parser_suite, 1,
2576 "Creates an AST object from a suite."},
Guido van Rossum47478871996-08-21 14:32:37 +00002577 {"sequence2ast", parser_tuple2ast, 1,
2578 "Creates an AST object from a tree representation."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002579 {"tuple2ast", parser_tuple2ast, 1,
Guido van Rossum47478871996-08-21 14:32:37 +00002580 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002581
2582 {0, 0, 0}
2583 };
2584
2585
Guido van Rossum52f2c051993-11-10 12:53:24 +00002586void
Guido van Rossum3d602e31996-07-21 02:33:56 +00002587initparser()
2588 {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002589 PyObject* module = Py_InitModule("parser", parser_functions);
2590 PyObject* dict = PyModule_GetDict(module);
2591
2592 parser_error = PyString_FromString("parser.ParserError");
2593
2594 if ((parser_error == 0)
2595 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2596 /*
2597 * This is serious.
2598 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002599 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002600 }
2601 /*
2602 * Nice to have, but don't cry if we fail.
2603 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002604 Py_INCREF(&PyAST_Type);
2605 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2606
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002607 PyDict_SetItemString(dict, "__copyright__",
2608 PyString_FromString(parser_copyright_string));
2609 PyDict_SetItemString(dict, "__doc__",
2610 PyString_FromString(parser_doc_string));
2611 PyDict_SetItemString(dict, "__version__",
2612 PyString_FromString(parser_version_string));
2613
2614} /* initparser() */
2615
2616
2617/*
Guido van Rossum3d602e31996-07-21 02:33:56 +00002618 * end of parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002619 */