blob: bd1be627942472a5769ea1b5da435fe779f9a547 [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
Guido van Rossumd266eb41996-10-25 14:44:06 +000084Centrum or CWI or Corporation for National Research Initiatives or
85CNRI not be used in advertising or publicity pertaining to
86distribution of the software without specific, written prior
87permission.
Guido van Rossum52f2c051993-11-10 12:53:24 +000088
Guido van Rossumd266eb41996-10-25 14:44:06 +000089While CWI is the initial source for this software, a modified version
90is made available by the Corporation for National Research Initiatives
91(CNRI) at the Internet address ftp://ftp.python.org.
92
93STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
94REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
95MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
96CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
97DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
98PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
99TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
100PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum52f2c051993-11-10 12:53:24 +0000101
102******************************************************************/
103
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000104static PyObject*
Guido van Rossum47478871996-08-21 14:32:37 +0000105node2tuple(n, mkseq, addelem, lineno)
106 node *n; /* node to convert */
107 SeqMaker mkseq; /* create sequence */
108 SeqInserter addelem; /* func. to add elem. in seq. */
109 int lineno; /* include line numbers? */
110{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000111 if (n == NULL) {
112 Py_INCREF(Py_None);
113 return Py_None;
114 }
115 if (ISNONTERMINAL(TYPE(n))) {
116 int i;
117 PyObject *v, *w;
Guido van Rossum47478871996-08-21 14:32:37 +0000118 v = mkseq(1 + NCH(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000119 if (v == NULL)
120 return v;
121 w = PyInt_FromLong(TYPE(n));
122 if (w == NULL) {
123 Py_DECREF(v);
124 return NULL;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000125 }
Guido van Rossum47478871996-08-21 14:32:37 +0000126 addelem(v, 0, w);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000127 for (i = 0; i < NCH(n); i++) {
Guido van Rossum47478871996-08-21 14:32:37 +0000128 w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000129 if (w == NULL) {
130 Py_DECREF(v);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000131 return NULL;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000132 }
Guido van Rossum47478871996-08-21 14:32:37 +0000133 addelem(v, i+1, w);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000134 }
Guido van Rossum47478871996-08-21 14:32:37 +0000135 return (v);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000136 }
137 else if (ISTERMINAL(TYPE(n))) {
Guido van Rossum47478871996-08-21 14:32:37 +0000138 PyObject *result = mkseq(2 + lineno);
139 if (result != NULL) {
140 addelem(result, 0, PyInt_FromLong(TYPE(n)));
141 addelem(result, 1, PyString_FromString(STR(n)));
142 if (lineno == 1)
143 addelem(result, 2, PyInt_FromLong(n->n_lineno));
144 }
145 return (result);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000146 }
147 else {
148 PyErr_SetString(PyExc_SystemError,
149 "unrecognized parse tree node type");
150 return NULL;
151 }
Guido van Rossum47478871996-08-21 14:32:37 +0000152} /* node2tuple() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000153/*
154 * End of material copyrighted by Stichting Mathematisch Centrum.
155 */
Guido van Rossum52f2c051993-11-10 12:53:24 +0000156
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000157
158
159/* There are two types of intermediate objects we're interested in:
160 * 'eval' and 'exec' types. These constants can be used in the ast_type
161 * field of the object type to identify which any given object represents.
162 * These should probably go in an external header to allow other extensions
163 * to use them, but then, we really should be using C++ too. ;-)
164 *
Guido van Rossum3d602e31996-07-21 02:33:56 +0000165 * The PyAST_FRAGMENT type is not currently supported. Maybe not useful?
166 * Haven't decided yet.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000167 */
168
169#define PyAST_EXPR 1
170#define PyAST_SUITE 2
171#define PyAST_FRAGMENT 3
172
173
174/* These are the internal objects and definitions required to implement the
175 * AST type. Most of the internal names are more reminiscent of the 'old'
176 * naming style, but the code uses the new naming convention.
177 */
178
179static PyObject*
180parser_error = 0;
181
182
183typedef struct _PyAST_Object {
184
185 PyObject_HEAD /* standard object header */
186 node* ast_node; /* the node* returned by the parser */
187 int ast_type; /* EXPR or SUITE ? */
188
189} PyAST_Object;
190
191
Guido van Rossum2a288461996-08-21 21:55:43 +0000192staticforward void parser_free Py_PROTO((PyAST_Object *ast));
193staticforward int parser_compare Py_PROTO((PyAST_Object *left,
194 PyAST_Object *right));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000195
196
197/* static */
198PyTypeObject PyAST_Type = {
199
Guido van Rossumf2b2dac1997-01-23 23:29:44 +0000200 PyObject_HEAD_INIT(NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000201 0,
202 "ast", /* tp_name */
203 sizeof(PyAST_Object), /* tp_basicsize */
204 0, /* tp_itemsize */
205 (destructor)parser_free, /* tp_dealloc */
206 0, /* tp_print */
207 0, /* tp_getattr */
208 0, /* tp_setattr */
209 (cmpfunc)parser_compare, /* tp_compare */
210 0, /* tp_repr */
211 0, /* tp_as_number */
212 0, /* tp_as_sequence */
213 0, /* tp_as_mapping */
214 0, /* tp_hash */
215 0, /* tp_call */
216 0 /* tp_str */
217
218}; /* PyAST_Type */
219
220
221static int
222parser_compare_nodes(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000223 node *left;
224 node *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000225{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000226 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000227
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000228 if (TYPE(left) < TYPE(right))
229 return (-1);
230
231 if (TYPE(right) < TYPE(left))
232 return (1);
233
234 if (ISTERMINAL(TYPE(left)))
235 return (strcmp(STR(left), STR(right)));
236
237 if (NCH(left) < NCH(right))
238 return (-1);
239
240 if (NCH(right) < NCH(left))
241 return (1);
242
243 for (j = 0; j < NCH(left); ++j) {
244 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
245
246 if (v)
247 return (v);
248 }
249 return (0);
250
251} /* parser_compare_nodes() */
252
253
254/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
255 *
256 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
257 * This really just wraps a call to parser_compare_nodes() with some easy
258 * checks and protection code.
259 *
260 */
261static int
262parser_compare(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000263 PyAST_Object *left;
264 PyAST_Object *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000265{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000266 if (left == right)
267 return (0);
268
269 if ((left == 0) || (right == 0))
270 return (-1);
271
272 return (parser_compare_nodes(left->ast_node, right->ast_node));
273
274} /* parser_compare() */
275
276
277/* parser_newastobject(node* ast)
278 *
279 * Allocates a new Python object representing an AST. This is simply the
280 * 'wrapper' object that holds a node* and allows it to be passed around in
281 * Python code.
282 *
283 */
284static PyObject*
285parser_newastobject(ast, type)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000286 node *ast;
287 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000288{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000289 PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
290
291 if (o != 0) {
292 o->ast_node = ast;
293 o->ast_type = type;
294 }
295 return ((PyObject*)o);
296
297} /* parser_newastobject() */
298
299
300/* void parser_free(PyAST_Object* ast)
301 *
302 * This is called by a del statement that reduces the reference count to 0.
303 *
304 */
305static void
306parser_free(ast)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000307 PyAST_Object *ast;
Guido van Rossum47478871996-08-21 14:32:37 +0000308{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000309 PyNode_Free(ast->ast_node);
310 PyMem_DEL(ast);
311
312} /* parser_free() */
313
314
315/* parser_ast2tuple(PyObject* self, PyObject* args)
316 *
317 * This provides conversion from a node* to a tuple object that can be
318 * returned to the Python-level caller. The AST object is not modified.
319 *
320 */
321static PyObject*
322parser_ast2tuple(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000323 PyObject *self;
324 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000325{
326 PyObject *ast;
327 PyObject *line_option = 0;
328 PyObject *res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000329
Guido van Rossum47478871996-08-21 14:32:37 +0000330 if (PyArg_ParseTuple(args, "O!|O:ast2tuple", &PyAST_Type, &ast,
331 &line_option)) {
332 int lineno = 0;
333 if (line_option != 0) {
334 lineno = PyObject_IsTrue(line_option);
335 lineno = lineno ? 1 : 0;
336 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000337 /*
338 * Convert AST into a tuple representation. Use Guido's function,
339 * since it's known to work already.
340 */
Guido van Rossum47478871996-08-21 14:32:37 +0000341 res = node2tuple(((PyAST_Object*)ast)->ast_node,
342 PyTuple_New, PyTuple_SetItem, lineno);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000343 }
344 return (res);
345
346} /* parser_ast2tuple() */
347
348
Guido van Rossum47478871996-08-21 14:32:37 +0000349/* parser_ast2tuple(PyObject* self, PyObject* args)
350 *
351 * This provides conversion from a node* to a tuple object that can be
352 * returned to the Python-level caller. The AST object is not modified.
353 *
354 */
355static PyObject*
356parser_ast2list(self, args)
357 PyObject *self;
358 PyObject *args;
359{
360 PyObject *ast;
361 PyObject *line_option = 0;
362 PyObject *res = 0;
363
364 if (PyArg_ParseTuple(args, "O!|O:ast2list", &PyAST_Type, &ast,
365 &line_option)) {
366 int lineno = 0;
367 if (line_option != 0) {
368 lineno = PyObject_IsTrue(line_option);
369 lineno = lineno ? 1 : 0;
370 }
371 /*
372 * Convert AST into a tuple representation. Use Guido's function,
373 * since it's known to work already.
374 */
375 res = node2tuple(((PyAST_Object*)ast)->ast_node,
376 PyList_New, PyList_SetItem, lineno);
377 }
378 return (res);
379
380} /* parser_ast2list() */
381
382
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000383/* parser_compileast(PyObject* self, PyObject* args)
384 *
385 * This function creates code objects from the parse tree represented by
386 * the passed-in data object. An optional file name is passed in as well.
387 *
388 */
389static PyObject*
390parser_compileast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000391 PyObject *self;
392 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000393{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000394 PyAST_Object* ast;
395 PyObject* res = 0;
396 char* str = "<ast>";
397
398 if (PyArg_ParseTuple(args, "O!|s", &PyAST_Type, &ast, &str))
Guido van Rossum3d602e31996-07-21 02:33:56 +0000399 res = (PyObject*) PyNode_Compile(ast->ast_node, str);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000400
401 return (res);
402
403} /* parser_compileast() */
404
405
406/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
407 * PyObject* parser_issuite(PyObject* self, PyObject* args)
408 *
409 * Checks the passed-in AST object to determine if it is an expression or
410 * a statement suite, respectively. The return is a Python truth value.
411 *
412 */
413static PyObject*
414parser_isexpr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000415 PyObject *self;
416 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000417{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000418 PyAST_Object* ast;
419 PyObject* res = 0;
420
421 if (PyArg_ParseTuple(args, "O!:isexpr", &PyAST_Type, &ast)) {
422 /*
423 * Check to see if the AST represents an expression or not.
424 */
425 res = (ast->ast_type == PyAST_EXPR) ? Py_True : Py_False;
426 Py_INCREF(res);
427 }
428 return (res);
429
430} /* parser_isexpr() */
431
432
433static PyObject*
434parser_issuite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000435 PyObject *self;
436 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000437{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000438 PyAST_Object* ast;
439 PyObject* res = 0;
440
Guido van Rossum3d602e31996-07-21 02:33:56 +0000441 if (PyArg_ParseTuple(args, "O!:issuite", &PyAST_Type, &ast)) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000442 /*
443 * Check to see if the AST represents an expression or not.
444 */
445 res = (ast->ast_type == PyAST_EXPR) ? Py_False : Py_True;
446 Py_INCREF(res);
447 }
448 return (res);
449
450} /* parser_issuite() */
451
452
Guido van Rossum3d602e31996-07-21 02:33:56 +0000453/* err_string(char* message)
454 *
455 * Sets the error string for an exception of type ParserError.
456 *
457 */
458static void
459err_string(message)
460 char *message;
Guido van Rossum47478871996-08-21 14:32:37 +0000461{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000462 PyErr_SetString(parser_error, message);
463
464} /* err_string() */
465
466
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000467/* PyObject* parser_do_parse(PyObject* args, int type)
468 *
469 * Internal function to actually execute the parse and return the result if
470 * successful, or set an exception if not.
471 *
472 */
473static PyObject*
474parser_do_parse(args, type)
475 PyObject *args;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000476 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000477{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000478 char* string = 0;
479 PyObject* res = 0;
480
481 if (PyArg_ParseTuple(args, "s", &string)) {
482 node* n = PyParser_SimpleParseString(string,
483 (type == PyAST_EXPR)
484 ? eval_input : file_input);
485
486 if (n != 0)
487 res = parser_newastobject(n, type);
488 else
Guido van Rossum3d602e31996-07-21 02:33:56 +0000489 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000490 }
491 return (res);
492
493} /* parser_do_parse() */
494
495
496/* PyObject* parser_expr(PyObject* self, PyObject* args)
497 * PyObject* parser_suite(PyObject* self, PyObject* args)
498 *
499 * External interfaces to the parser itself. Which is called determines if
500 * the parser attempts to recognize an expression ('eval' form) or statement
501 * suite ('exec' form). The real work is done by parser_do_parse() above.
502 *
503 */
504static PyObject*
505parser_expr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000506 PyObject *self;
507 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000508{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000509 return (parser_do_parse(args, PyAST_EXPR));
510
511} /* parser_expr() */
512
513
514static PyObject*
515parser_suite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000516 PyObject *self;
517 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000518{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000519 return (parser_do_parse(args, PyAST_SUITE));
520
521} /* parser_suite() */
522
523
524
525/* This is the messy part of the code. Conversion from a tuple to an AST
526 * object requires that the input tuple be valid without having to rely on
527 * catching an exception from the compiler. This is done to allow the
528 * compiler itself to remain fast, since most of its input will come from
529 * the parser directly, and therefore be known to be syntactically correct.
530 * This validation is done to ensure that we don't core dump the compile
531 * phase, returning an exception instead.
532 *
533 * Two aspects can be broken out in this code: creating a node tree from
534 * the tuple passed in, and verifying that it is indeed valid. It may be
535 * advantageous to expand the number of AST types to include funcdefs and
536 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
537 * here. They are not necessary, and not quite as useful in a raw form.
538 * For now, let's get expressions and suites working reliably.
539 */
540
541
Guido van Rossum2a288461996-08-21 21:55:43 +0000542staticforward node* build_node_tree Py_PROTO((PyObject *tuple));
543staticforward int validate_expr_tree Py_PROTO((node *tree));
544staticforward int validate_file_input Py_PROTO((node *tree));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000545
546
547/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
548 *
549 * This is the public function, called from the Python code. It receives a
550 * single tuple object from the caller, and creates an AST object if the
551 * tuple can be validated. It does this by checking the first code of the
552 * tuple, and, if acceptable, builds the internal representation. If this
553 * step succeeds, the internal representation is validated as fully as
554 * possible with the various validate_*() routines defined below.
555 *
556 * This function must be changed if support is to be added for PyAST_FRAGMENT
557 * AST objects.
558 *
559 */
560static PyObject*
561parser_tuple2ast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000562 PyObject *self;
563 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000564{
565 PyObject *ast = 0;
566 PyObject *tuple = 0;
567 PyObject *temp = 0;
568 int ok;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000569 int start_sym = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000570
Guido van Rossum47478871996-08-21 14:32:37 +0000571 if (!PyArg_ParseTuple(args, "O:tuple2ast", &tuple))
572 return (0);
573 if (!PySequence_Check(tuple)) {
574 PyErr_SetString(PyExc_ValueError,
575 "tuple2ast() requires a single sequence argument");
576 return (0);
577 }
578 /*
579 * This mess of tests is written this way so we can use the abstract
580 * object interface (AOI). Unfortunately, the AOI increments reference
581 * counts, which requires that we store a pointer to retrieved object
582 * so we can DECREF it after the check. But we really should accept
583 * lists as well as tuples at the very least.
584 */
585 ok = PyObject_Length(tuple) >= 2;
586 if (ok) {
587 temp = PySequence_GetItem(tuple, 0);
588 ok = (temp != NULL) && PyInt_Check(temp);
589 if (ok)
590 /* this is used after the initial checks: */
591 start_sym = PyInt_AsLong(temp);
592 Py_XDECREF(temp);
593 }
594 if (ok) {
595 temp = PySequence_GetItem(tuple, 1);
596 ok = (temp != NULL) && PySequence_Check(temp);
597 Py_XDECREF(temp);
598 }
599 if (ok) {
600 temp = PySequence_GetItem(tuple, 1);
601 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
602 if (ok) {
603 PyObject *temp2 = PySequence_GetItem(temp, 0);
604 if (temp2 != NULL) {
605 ok = PyInt_Check(temp2);
606 Py_DECREF(temp2);
607 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000608 }
Guido van Rossum47478871996-08-21 14:32:37 +0000609 Py_XDECREF(temp);
610 }
611 /* If we've failed at some point, get out of here. */
612 if (!ok) {
613 err_string("malformed sequence for tuple2ast()");
614 return (0);
615 }
616 /*
617 * This might be a valid parse tree, but let's do a quick check
618 * before we jump the gun.
619 */
620 if (start_sym == eval_input) {
621 /* Might be an eval form. */
622 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000623
Guido van Rossum47478871996-08-21 14:32:37 +0000624 if ((expression != 0) && validate_expr_tree(expression))
625 ast = parser_newastobject(expression, PyAST_EXPR);
626 }
627 else if (start_sym == file_input) {
628 /* This looks like an exec form so far. */
629 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000630
Guido van Rossum47478871996-08-21 14:32:37 +0000631 if ((suite_tree != 0) && validate_file_input(suite_tree))
632 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000633 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000634 else
Guido van Rossum47478871996-08-21 14:32:37 +0000635 /* This is a fragment, and is not yet supported. Maybe they
636 * will be if I find a use for them.
637 */
638 err_string("Fragmentary parse trees not supported.");
639
640 /* Make sure we throw an exception on all errors. We should never
641 * get this, but we'd do well to be sure something is done.
642 */
643 if ((ast == 0) && !PyErr_Occurred())
644 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000645
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000646 return (ast);
647
648} /* parser_tuple2ast() */
649
650
651/* int check_terminal_tuple()
652 *
Guido van Rossum47478871996-08-21 14:32:37 +0000653 * Check a tuple to determine that it is indeed a valid terminal
654 * node. The node is known to be required as a terminal, so we throw
655 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000656 *
Guido van Rossum47478871996-08-21 14:32:37 +0000657 * The format of an acceptable terminal tuple is "(is[i])": the fact
658 * that elem is a tuple and the integer is a valid terminal symbol
659 * has been established before this function is called. We must
660 * check the length of the tuple and the type of the second element
661 * and optional third element. We do *NOT* check the actual text of
662 * the string element, which we could do in many cases. This is done
663 * by the validate_*() functions which operate on the internal
664 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000665 */
666static int
Guido van Rossum47478871996-08-21 14:32:37 +0000667check_terminal_tuple(elem)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000668 PyObject *elem;
Guido van Rossum47478871996-08-21 14:32:37 +0000669{
670 int len = PyObject_Length(elem);
671 int res = 1;
672 char* str = "Illegal terminal symbol; bad node length.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000673
Guido van Rossum47478871996-08-21 14:32:37 +0000674 if ((len == 2) || (len == 3)) {
675 PyObject *temp = PySequence_GetItem(elem, 1);
676 res = PyString_Check(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000677 str = "Illegal terminal symbol; expected a string.";
Guido van Rossum47478871996-08-21 14:32:37 +0000678 if (res && (len == 3)) {
679 PyObject* third = PySequence_GetItem(elem, 2);
680 res = PyInt_Check(third);
681 str = "Invalid third element of terminal node.";
682 Py_XDECREF(third);
683 }
684 Py_XDECREF(temp);
685 }
686 else {
687 res = 0;
688 }
689 if (!res) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000690 elem = Py_BuildValue("(os)", elem, str);
691 PyErr_SetObject(parser_error, elem);
692 }
693 return (res);
694
695} /* check_terminal_tuple() */
696
697
698/* node* build_node_children()
699 *
700 * Iterate across the children of the current non-terminal node and build
701 * their structures. If successful, return the root of this portion of
702 * the tree, otherwise, 0. Any required exception will be specified already,
703 * and no memory will have been deallocated.
704 *
705 */
706static node*
707build_node_children(tuple, root, line_num)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000708 PyObject *tuple;
709 node *root;
710 int *line_num;
Guido van Rossum47478871996-08-21 14:32:37 +0000711{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000712 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000713 int i;
714
715 for (i = 1; i < len; ++i) {
716 /* elem must always be a tuple, however simple */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000717 PyObject* elem = PySequence_GetItem(tuple, i);
Guido van Rossum47478871996-08-21 14:32:37 +0000718 int ok = elem != NULL;
719 long type = 0;
720 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000721
Guido van Rossum47478871996-08-21 14:32:37 +0000722 if (ok)
723 ok = PySequence_Check(elem);
724 if (ok) {
725 PyObject *temp = PySequence_GetItem(elem, 0);
726 if (temp == NULL)
727 ok = 0;
728 else {
729 ok = PyInt_Check(temp);
730 if (ok)
731 type = PyInt_AsLong(temp);
732 Py_DECREF(temp);
733 }
734 }
735 if (!ok) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000736 PyErr_SetObject(parser_error,
737 Py_BuildValue("(os)", elem,
738 "Illegal node construct."));
Guido van Rossum47478871996-08-21 14:32:37 +0000739 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000740 return (0);
741 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000742 if (ISTERMINAL(type)) {
Guido van Rossum47478871996-08-21 14:32:37 +0000743 if (check_terminal_tuple(elem)) {
744 PyObject *temp = PySequence_GetItem(elem, 1);
745
746 strn = strdup(PyString_AsString(temp));
747 Py_XDECREF(temp);
748
749 if (PyObject_Length(elem) == 3) {
750 PyObject* temp = PySequence_GetItem(elem, 2);
751 *line_num = PyInt_AsLong(temp);
752 Py_DECREF(temp);
753 }
754 }
755 else {
756 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000757 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000758 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000759 }
760 else if (!ISNONTERMINAL(type)) {
761 /*
762 * It has to be one or the other; this is an error.
763 * Throw an exception.
764 */
765 PyErr_SetObject(parser_error,
766 Py_BuildValue("(os)", elem,
767 "Unknown node type."));
Guido van Rossum47478871996-08-21 14:32:37 +0000768 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000769 return (0);
770 }
771 PyNode_AddChild(root, type, strn, *line_num);
772
773 if (ISNONTERMINAL(type)) {
774 node* new_child = CHILD(root, i - 1);
775
Guido van Rossum47478871996-08-21 14:32:37 +0000776 if (new_child != build_node_children(elem, new_child, line_num)) {
777 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000778 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000779 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000780 }
Guido van Rossum47478871996-08-21 14:32:37 +0000781 else if (type == NEWLINE) { /* It's true: we increment the */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000782 ++(*line_num); /* line number *after* the newline! */
Guido van Rossum47478871996-08-21 14:32:37 +0000783 }
784 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000785 }
786 return (root);
787
788} /* build_node_children() */
789
790
791static node*
792build_node_tree(tuple)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000793 PyObject *tuple;
Guido van Rossum47478871996-08-21 14:32:37 +0000794{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000795 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000796 PyObject *temp = PySequence_GetItem(tuple, 0);
797 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000798
Guido van Rossum47478871996-08-21 14:32:37 +0000799 if (temp != NULL)
800 num = PyInt_AsLong(temp);
801 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000802 if (ISTERMINAL(num)) {
803 /*
804 * The tuple is simple, but it doesn't start with a start symbol.
805 * Throw an exception now and be done with it.
806 */
807 tuple = Py_BuildValue("(os)", tuple,
Guido van Rossum3d602e31996-07-21 02:33:56 +0000808 "Illegal ast tuple; cannot start with terminal symbol.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000809 PyErr_SetObject(parser_error, tuple);
810 }
811 else if (ISNONTERMINAL(num)) {
812 /*
813 * Not efficient, but that can be handled later.
814 */
815 int line_num = 0;
816
817 res = PyNode_New(num);
818 if (res != build_node_children(tuple, res, &line_num)) {
819 PyNode_Free(res);
820 res = 0;
821 }
822 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000823 else
824 /* The tuple is illegal -- if the number is neither TERMINAL nor
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000825 * NONTERMINAL, we can't use it.
826 */
827 PyErr_SetObject(parser_error,
828 Py_BuildValue("(os)", tuple,
829 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000830
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000831 return (res);
832
833} /* build_node_tree() */
834
835
Guido van Rossum360a9341996-08-21 19:04:10 +0000836#ifdef HAVE_OLD_CPP
Guido van Rossum2a288461996-08-21 21:55:43 +0000837#define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000838#else
Guido van Rossum2a288461996-08-21 21:55:43 +0000839#define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000840#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000841
842
843/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000844 * Validation routines used within the validation section:
845 */
Guido van Rossum2a288461996-08-21 21:55:43 +0000846staticforward int validate_terminal Py_PROTO((node *terminal,
847 int type, char *string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000848
849#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
850#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
851#define validate_colon(ch) validate_terminal(ch, COLON, ":")
852#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
853#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
854#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000855#define validate_indent(ch) validate_terminal(ch, INDENT, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000856#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000857#define validate_newline(ch) validate_terminal(ch, NEWLINE, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000858#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
859#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
860#define validate_star(ch) validate_terminal(ch, STAR, "*")
861#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000862#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
Guido van Rossum47478871996-08-21 14:32:37 +0000863#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000864#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000865
Guido van Rossum3d602e31996-07-21 02:33:56 +0000866VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000867VALIDATER(class); VALIDATER(node);
868VALIDATER(parameters); VALIDATER(suite);
869VALIDATER(testlist); VALIDATER(varargslist);
870VALIDATER(fpdef); VALIDATER(fplist);
871VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000872VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000873VALIDATER(print_stmt); VALIDATER(del_stmt);
874VALIDATER(return_stmt);
875VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000876VALIDATER(global_stmt);
Guido van Rossum925e5471997-04-02 05:32:13 +0000877VALIDATER(assert_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000878VALIDATER(exec_stmt); VALIDATER(compound_stmt);
879VALIDATER(while); VALIDATER(for);
880VALIDATER(try); VALIDATER(except_clause);
881VALIDATER(test); VALIDATER(and_test);
882VALIDATER(not_test); VALIDATER(comparison);
883VALIDATER(comp_op); VALIDATER(expr);
884VALIDATER(xor_expr); VALIDATER(and_expr);
885VALIDATER(shift_expr); VALIDATER(arith_expr);
886VALIDATER(term); VALIDATER(factor);
887VALIDATER(atom); VALIDATER(lambdef);
888VALIDATER(trailer); VALIDATER(subscript);
Guido van Rossum47478871996-08-21 14:32:37 +0000889VALIDATER(subscriptlist); VALIDATER(sliceop);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000890VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000891VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000892
893
894#define is_even(n) (((n) & 1) == 0)
895#define is_odd(n) (((n) & 1) == 1)
896
897
898static int
899validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000900 node *n;
901 int t;
Guido van Rossum47478871996-08-21 14:32:37 +0000902{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000903 int res = (TYPE(n) == t);
904
905 if (!res) {
906 char buffer[128];
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000907 sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000908 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000909 }
910 return (res);
911
912} /* validate_ntype() */
913
914
915static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000916validate_numnodes(n, num, name)
917 node *n;
918 int num;
919 const char *const name;
Guido van Rossum47478871996-08-21 14:32:37 +0000920{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000921 if (NCH(n) != num) {
922 char buff[60];
923 sprintf(buff, "Illegal number of children for %s node.", name);
924 err_string(buff);
925 }
926 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000927
Guido van Rossum3d602e31996-07-21 02:33:56 +0000928} /* validate_numnodes() */
929
930
931static int
932validate_terminal(terminal, type, string)
933 node *terminal;
934 int type;
935 char *string;
Guido van Rossum47478871996-08-21 14:32:37 +0000936{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000937 int res = (validate_ntype(terminal, type)
938 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
939
940 if (!res && !PyErr_Occurred()) {
941 char buffer[60];
942 sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
943 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000944 }
945 return (res);
946
947} /* validate_terminal() */
948
949
Guido van Rossum47478871996-08-21 14:32:37 +0000950/* X (',' X) [',']
951 */
952static int
953validate_repeating_list(tree, ntype, vfunc, name)
954 node *tree;
955 int ntype;
956 int (*vfunc)();
957 const char *const name;
958{
959 int nch = NCH(tree);
960 int res = (nch && validate_ntype(tree, ntype)
961 && vfunc(CHILD(tree, 0)));
962
963 if (!res && !PyErr_Occurred())
964 validate_numnodes(tree, 1, name);
965 else {
966 if (is_even(nch))
967 res = validate_comma(CHILD(tree, --nch));
968 if (res && nch > 1) {
969 int pos = 1;
970 for ( ; res && pos < nch; pos += 2)
971 res = (validate_comma(CHILD(tree, pos))
972 && vfunc(CHILD(tree, pos + 1)));
973 }
974 }
975 return (res);
976
977} /* validate_repeating_list() */
978
979
Guido van Rossum3d602e31996-07-21 02:33:56 +0000980/* VALIDATE(class)
981 *
982 * classdef:
983 * 'class' NAME ['(' testlist ')'] ':' suite
984 */
Guido van Rossum47478871996-08-21 14:32:37 +0000985static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000986validate_class(tree)
987 node *tree;
988{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000989 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000990 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000991
Guido van Rossum3d602e31996-07-21 02:33:56 +0000992 if (res) {
993 res = (validate_name(CHILD(tree, 0), "class")
994 && validate_ntype(CHILD(tree, 1), NAME)
995 && validate_colon(CHILD(tree, nch - 2))
996 && validate_suite(CHILD(tree, nch - 1)));
997 }
998 else
999 validate_numnodes(tree, 4, "class");
1000 if (res && (nch == 7)) {
1001 res = (validate_lparen(CHILD(tree, 2))
1002 && validate_testlist(CHILD(tree, 3))
1003 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001004 }
1005 return (res);
1006
1007} /* validate_class() */
1008
1009
Guido van Rossum3d602e31996-07-21 02:33:56 +00001010/* if_stmt:
1011 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1012 */
Guido van Rossum47478871996-08-21 14:32:37 +00001013static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001014validate_if(tree)
1015 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001016{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001017 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001018 int res = (validate_ntype(tree, if_stmt)
1019 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001020 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +00001021 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001022 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001023 && validate_suite(CHILD(tree, 3)));
1024
1025 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001026 /* ... 'else' ':' suite */
1027 res = (validate_name(CHILD(tree, nch - 3), "else")
1028 && validate_colon(CHILD(tree, nch - 2))
1029 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001030 nch -= 3;
1031 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001032 else if (!res && !PyErr_Occurred())
1033 validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001034 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001035 /* Will catch the case for nch < 4 */
1036 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001037 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001038 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001039 int j = 4;
1040 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001041 res = (validate_name(CHILD(tree, j), "elif")
1042 && validate_colon(CHILD(tree, j + 2))
1043 && validate_test(CHILD(tree, j + 1))
1044 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001045 j += 4;
1046 }
1047 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001048 return (res);
1049
1050} /* validate_if() */
1051
1052
Guido van Rossum3d602e31996-07-21 02:33:56 +00001053/* parameters:
1054 * '(' [varargslist] ')'
1055 *
1056 */
Guido van Rossum47478871996-08-21 14:32:37 +00001057static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001058validate_parameters(tree)
1059 node *tree;
1060{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001061 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001062 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001063
Guido van Rossum3d602e31996-07-21 02:33:56 +00001064 if (res) {
1065 res = (validate_lparen(CHILD(tree, 0))
1066 && validate_rparen(CHILD(tree, nch - 1)));
1067 if (res && (nch == 3))
1068 res = validate_varargslist(CHILD(tree, 1));
1069 }
1070 else
1071 validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001072
1073 return (res);
1074
1075} /* validate_parameters() */
1076
1077
Guido van Rossum3d602e31996-07-21 02:33:56 +00001078/* VALIDATE(suite)
1079 *
1080 * suite:
1081 * simple_stmt
1082 * | NEWLINE INDENT stmt+ DEDENT
1083 */
Guido van Rossum47478871996-08-21 14:32:37 +00001084static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001085validate_suite(tree)
1086 node *tree;
1087{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001088 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001089 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001090
Guido van Rossum3d602e31996-07-21 02:33:56 +00001091 if (res && (nch == 1))
1092 res = validate_simple_stmt(CHILD(tree, 0));
1093 else if (res) {
1094 /* NEWLINE INDENT stmt+ DEDENT */
1095 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001096 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001097 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001098 && validate_dedent(CHILD(tree, nch - 1)));
1099
Guido van Rossum3d602e31996-07-21 02:33:56 +00001100 if (res && (nch > 4)) {
1101 int i = 3;
1102 --nch; /* forget the DEDENT */
1103 for ( ; res && (i < nch); ++i)
1104 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001105 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001106 else if (nch < 4)
1107 validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001108 }
1109 return (res);
1110
1111} /* validate_suite() */
1112
1113
Guido van Rossum47478871996-08-21 14:32:37 +00001114static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001115validate_testlist(tree)
1116 node *tree;
1117{
Guido van Rossum47478871996-08-21 14:32:37 +00001118 return (validate_repeating_list(tree, testlist,
1119 validate_test, "testlist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001120
1121} /* validate_testlist() */
1122
1123
Guido van Rossum3d602e31996-07-21 02:33:56 +00001124/* VALIDATE(varargslist)
1125 *
1126 * varargslist:
1127 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1128 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1129 *
1130 * (fpdef ['=' test] ',')*
1131 * ('*' NAME [',' ('**'|'*' '*') NAME]
1132 * | ('**'|'*' '*') NAME)
1133 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1134 *
1135 */
Guido van Rossum47478871996-08-21 14:32:37 +00001136static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001137validate_varargslist(tree)
1138 node *tree;
1139{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001140 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001141 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001142
Guido van Rossum3d602e31996-07-21 02:33:56 +00001143 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1144 /* (fpdef ['=' test] ',')*
1145 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1146 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001147 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001148 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001149
Guido van Rossum3d602e31996-07-21 02:33:56 +00001150 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1151 res = validate_fpdef(CHILD(tree, pos));
1152 if (res) {
1153 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1154 res = validate_test(CHILD(tree, pos + 2));
1155 pos += 2;
1156 }
1157 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001158 pos += 2;
1159 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001160 }
1161 if (res) {
1162 remaining = nch - pos;
1163 res = ((remaining == 2) || (remaining == 3)
1164 || (remaining == 5) || (remaining == 6));
1165 if (!res)
1166 validate_numnodes(tree, 2, "varargslist");
1167 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1168 return ((remaining == 2)
1169 && validate_ntype(CHILD(tree, pos+1), NAME));
1170 else {
1171 res = validate_star(CHILD(tree, pos++));
1172 --remaining;
1173 }
1174 }
1175 if (res) {
1176 if (remaining == 2) {
1177 res = (validate_star(CHILD(tree, pos))
1178 && validate_ntype(CHILD(tree, pos + 1), NAME));
1179 }
1180 else {
1181 res = validate_ntype(CHILD(tree, pos++), NAME);
1182 if (res && (remaining >= 4)) {
1183 res = validate_comma(CHILD(tree, pos));
1184 if (--remaining == 3)
Fred Drakee1607a81996-09-11 21:58:26 +00001185 res = (validate_star(CHILD(tree, pos + 1))
1186 && validate_star(CHILD(tree, pos + 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001187 else
1188 validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1189 }
1190 }
1191 }
1192 if (!res && !PyErr_Occurred())
1193 err_string("Incorrect validation of variable arguments list.");
1194 }
1195 else if (res) {
1196 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1197 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1198 --nch;
1199
1200 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1201 res = (is_odd(nch)
1202 && validate_fpdef(CHILD(tree, 0)));
1203
1204 if (res && (nch > 1)) {
1205 int pos = 1;
1206 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1207 res = validate_test(CHILD(tree, 2));
1208 pos += 2;
1209 }
1210 /* ... (',' fpdef ['=' test])* */
1211 for ( ; res && (pos < nch); pos += 2) {
1212 /* ',' fpdef */
1213 res = (validate_comma(CHILD(tree, pos))
1214 && validate_fpdef(CHILD(tree, pos + 1)));
1215 if (res
1216 && ((nch - pos) > 2)
1217 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1218 /* ['=' test] */
1219 res = validate_test(CHILD(tree, pos + 3));
1220 pos += 2;
1221 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001222 }
1223 }
1224 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001225 else
1226 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001227
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001228 return (res);
1229
1230} /* validate_varargslist() */
1231
1232
Guido van Rossum3d602e31996-07-21 02:33:56 +00001233/* VALIDATE(fpdef)
1234 *
1235 * fpdef:
1236 * NAME
1237 * | '(' fplist ')'
1238 */
Guido van Rossum47478871996-08-21 14:32:37 +00001239static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001240validate_fpdef(tree)
1241 node *tree;
1242{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001243 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001244 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001245
Guido van Rossum3d602e31996-07-21 02:33:56 +00001246 if (res) {
1247 if (nch == 1)
1248 res = validate_ntype(CHILD(tree, 0), NAME);
1249 else if (nch == 3)
1250 res = (validate_lparen(CHILD(tree, 0))
1251 && validate_fplist(CHILD(tree, 1))
1252 && validate_rparen(CHILD(tree, 2)));
1253 else
1254 validate_numnodes(tree, 1, "fpdef");
1255 }
1256 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001257
1258} /* validate_fpdef() */
1259
1260
Guido van Rossum47478871996-08-21 14:32:37 +00001261static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001262validate_fplist(tree)
1263 node *tree;
1264{
Guido van Rossum47478871996-08-21 14:32:37 +00001265 return (validate_repeating_list(tree, fplist,
1266 validate_fpdef, "fplist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001267
1268} /* validate_fplist() */
1269
1270
Guido van Rossum3d602e31996-07-21 02:33:56 +00001271/* simple_stmt | compound_stmt
1272 *
1273 */
Guido van Rossum47478871996-08-21 14:32:37 +00001274static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001275validate_stmt(tree)
1276 node *tree;
1277{
1278 int res = (validate_ntype(tree, stmt)
1279 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001280
Guido van Rossum3d602e31996-07-21 02:33:56 +00001281 if (res) {
1282 tree = CHILD(tree, 0);
1283
1284 if (TYPE(tree) == simple_stmt)
1285 res = validate_simple_stmt(tree);
1286 else
1287 res = validate_compound_stmt(tree);
1288 }
1289 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001290
1291} /* validate_stmt() */
1292
1293
Guido van Rossum3d602e31996-07-21 02:33:56 +00001294/* small_stmt (';' small_stmt)* [';'] NEWLINE
1295 *
1296 */
Guido van Rossum47478871996-08-21 14:32:37 +00001297static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001298validate_simple_stmt(tree)
1299 node *tree;
1300{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001301 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001302 int res = (validate_ntype(tree, simple_stmt)
1303 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001304 && validate_small_stmt(CHILD(tree, 0))
1305 && validate_newline(CHILD(tree, nch - 1)));
1306
Guido van Rossum3d602e31996-07-21 02:33:56 +00001307 if (nch < 2)
1308 res = validate_numnodes(tree, 2, "simple_stmt");
1309 --nch; /* forget the NEWLINE */
1310 if (res && is_even(nch))
1311 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001312 if (res && (nch > 2)) {
1313 int i;
1314
Guido van Rossum3d602e31996-07-21 02:33:56 +00001315 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001316 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001317 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001318 }
1319 return (res);
1320
1321} /* validate_simple_stmt() */
1322
1323
Guido van Rossum47478871996-08-21 14:32:37 +00001324static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001325validate_small_stmt(tree)
1326 node *tree;
1327{
1328 int nch = NCH(tree);
1329 int res = (validate_numnodes(tree, 1, "small_stmt")
1330 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1331 || (TYPE(CHILD(tree, 0)) == print_stmt)
1332 || (TYPE(CHILD(tree, 0)) == del_stmt)
1333 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1334 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1335 || (TYPE(CHILD(tree, 0)) == import_stmt)
1336 || (TYPE(CHILD(tree, 0)) == global_stmt)
Guido van Rossum925e5471997-04-02 05:32:13 +00001337 || (TYPE(CHILD(tree, 0)) == assert_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001338 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1339
1340 if (res)
1341 res = validate_node(CHILD(tree, 0));
1342 else if (nch == 1) {
1343 char buffer[60];
1344 sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1345 TYPE(CHILD(tree, 0)));
1346 err_string(buffer);
1347 }
1348 return (res);
1349
1350} /* validate_small_stmt */
1351
1352
1353/* compound_stmt:
1354 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1355 */
Guido van Rossum47478871996-08-21 14:32:37 +00001356static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001357validate_compound_stmt(tree)
1358 node *tree;
1359{
1360 int res = (validate_ntype(tree, compound_stmt)
1361 && validate_numnodes(tree, 1, "compound_stmt"));
1362
1363 if (!res)
1364 return (0);
1365
1366 tree = CHILD(tree, 0);
1367 res = ((TYPE(tree) == if_stmt)
1368 || (TYPE(tree) == while_stmt)
1369 || (TYPE(tree) == for_stmt)
1370 || (TYPE(tree) == try_stmt)
1371 || (TYPE(tree) == funcdef)
1372 || (TYPE(tree) == classdef));
1373 if (res)
1374 res = validate_node(tree);
1375 else {
1376 char buffer[60];
1377 sprintf(buffer, "Illegal compound statement type: %d.", TYPE(tree));
1378 err_string(buffer);
1379 }
1380 return (res);
1381
1382} /* validate_compound_stmt() */
1383
1384
Guido van Rossum47478871996-08-21 14:32:37 +00001385static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001386validate_expr_stmt(tree)
1387 node *tree;
1388{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001389 int j;
1390 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001391 int res = (validate_ntype(tree, expr_stmt)
1392 && is_odd(nch)
1393 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001394
Guido van Rossum3d602e31996-07-21 02:33:56 +00001395 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001396 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001397 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001398
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001399 return (res);
1400
1401} /* validate_expr_stmt() */
1402
1403
Guido van Rossum3d602e31996-07-21 02:33:56 +00001404/* print_stmt:
1405 *
1406 * 'print' (test ',')* [test]
1407 *
1408 */
Guido van Rossum47478871996-08-21 14:32:37 +00001409static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001410validate_print_stmt(tree)
1411 node *tree;
1412{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001413 int j;
1414 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001415 int res = (validate_ntype(tree, print_stmt)
1416 && (nch != 0)
1417 && validate_name(CHILD(tree, 0), "print"));
1418
1419 if (res && is_even(nch)) {
1420 res = validate_test(CHILD(tree, nch - 1));
1421 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001422 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001423 else if (!res && !PyErr_Occurred())
1424 validate_numnodes(tree, 1, "print_stmt");
1425 for (j = 1; res && (j < nch); j += 2)
1426 res = (validate_test(CHILD(tree, j))
1427 && validate_ntype(CHILD(tree, j + 1), COMMA));
1428
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001429 return (res);
1430
1431} /* validate_print_stmt() */
1432
1433
Guido van Rossum47478871996-08-21 14:32:37 +00001434static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001435validate_del_stmt(tree)
1436 node *tree;
1437{
1438 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001439 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001440 && validate_exprlist(CHILD(tree, 1)));
1441
1442} /* validate_del_stmt() */
1443
1444
Guido van Rossum47478871996-08-21 14:32:37 +00001445static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001446validate_return_stmt(tree)
1447 node *tree;
1448{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001449 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001450 int res = (validate_ntype(tree, return_stmt)
1451 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001452 && validate_name(CHILD(tree, 0), "return"));
1453
Guido van Rossum3d602e31996-07-21 02:33:56 +00001454 if (res && (nch == 2))
1455 res = validate_testlist(CHILD(tree, 1));
1456
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001457 return (res);
1458
1459} /* validate_return_stmt() */
1460
1461
Guido van Rossum47478871996-08-21 14:32:37 +00001462static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001463validate_raise_stmt(tree)
1464 node *tree;
1465{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001466 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001467 int res = (validate_ntype(tree, raise_stmt)
1468 && ((nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001469
Guido van Rossum3d602e31996-07-21 02:33:56 +00001470 if (res) {
1471 res = (validate_name(CHILD(tree, 0), "raise")
1472 && validate_test(CHILD(tree, 1)));
1473 if (res && nch > 2) {
1474 res = (validate_comma(CHILD(tree, 2))
1475 && validate_test(CHILD(tree, 3)));
1476 if (res && (nch > 4))
1477 res = (validate_comma(CHILD(tree, 4))
1478 && validate_test(CHILD(tree, 5)));
1479 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001480 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001481 else
1482 validate_numnodes(tree, 2, "raise");
1483 if (res && (nch == 4))
1484 res = (validate_comma(CHILD(tree, 2))
1485 && validate_test(CHILD(tree, 3)));
1486
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001487 return (res);
1488
1489} /* validate_raise_stmt() */
1490
1491
Guido van Rossum3d602e31996-07-21 02:33:56 +00001492/* import_stmt:
1493 *
1494 * 'import' dotted_name (',' dotted_name)*
1495 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1496 */
Guido van Rossum47478871996-08-21 14:32:37 +00001497static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001498validate_import_stmt(tree)
1499 node *tree;
1500{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001501 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001502 int res = (validate_ntype(tree, import_stmt)
1503 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001504 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001505 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001506
1507 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001508 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001509
Guido van Rossum3d602e31996-07-21 02:33:56 +00001510 for (j = 2; res && (j < nch); j += 2)
1511 res = (validate_comma(CHILD(tree, j))
1512 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001513 }
1514 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001515 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001516 && validate_name(CHILD(tree, 2), "import"));
1517 if (nch == 4) {
1518 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001519 || (TYPE(CHILD(tree, 3)) == STAR));
1520 if (!res)
1521 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001522 }
1523 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001524 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001525 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001526 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001527 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001528 res = (validate_comma(CHILD(tree, j))
1529 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001530 }
1531 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001532 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001533 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001534
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001535 return (res);
1536
1537} /* validate_import_stmt() */
1538
1539
Guido van Rossum47478871996-08-21 14:32:37 +00001540static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001541validate_global_stmt(tree)
1542 node *tree;
1543{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001544 int j;
1545 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001546 int res = (validate_ntype(tree, global_stmt)
1547 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001548
Guido van Rossum3d602e31996-07-21 02:33:56 +00001549 if (res)
1550 res = (validate_name(CHILD(tree, 0), "global")
1551 && validate_ntype(CHILD(tree, 1), NAME));
1552 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001553 res = (validate_comma(CHILD(tree, j))
1554 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001555
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001556 return (res);
1557
1558} /* validate_global_stmt() */
1559
1560
Guido van Rossum3d602e31996-07-21 02:33:56 +00001561/* exec_stmt:
1562 *
1563 * 'exec' expr ['in' test [',' test]]
1564 */
Guido van Rossum47478871996-08-21 14:32:37 +00001565static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001566validate_exec_stmt(tree)
1567 node *tree;
1568{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001569 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001570 int res = (validate_ntype(tree, exec_stmt)
1571 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001572 && validate_name(CHILD(tree, 0), "exec")
1573 && validate_expr(CHILD(tree, 1)));
1574
Guido van Rossum3d602e31996-07-21 02:33:56 +00001575 if (!res && !PyErr_Occurred())
1576 err_string("Illegal exec statement.");
1577 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001578 res = (validate_name(CHILD(tree, 2), "in")
1579 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001580 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001581 res = (validate_comma(CHILD(tree, 4))
1582 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001583
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001584 return (res);
1585
1586} /* validate_exec_stmt() */
1587
1588
Guido van Rossum925e5471997-04-02 05:32:13 +00001589/* assert_stmt:
1590 *
1591 * 'assert' test [',' test]
1592 */
1593static int
1594validate_assert_stmt(tree)
1595 node *tree;
1596{
1597 int nch = NCH(tree);
1598 int res = (validate_ntype(tree, assert_stmt)
1599 && ((nch == 2) || (nch == 4))
1600 && (validate_name(CHILD(tree, 0), "__assert__") ||
1601 validate_name(CHILD(tree, 0), "assert"))
1602 && validate_test(CHILD(tree, 1)));
1603
1604 if (!res && !PyErr_Occurred())
1605 err_string("Illegal assert statement.");
1606 if (res && (nch > 2))
1607 res = (validate_comma(CHILD(tree, 2))
1608 && validate_test(CHILD(tree, 3)));
1609
1610 return (res);
1611
1612} /* validate_assert_stmt() */
1613
1614
Guido van Rossum47478871996-08-21 14:32:37 +00001615static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001616validate_while(tree)
1617 node *tree;
1618{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001619 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001620 int res = (validate_ntype(tree, while_stmt)
1621 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001622 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001623 && validate_test(CHILD(tree, 1))
1624 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001625 && validate_suite(CHILD(tree, 3)));
1626
Guido van Rossum3d602e31996-07-21 02:33:56 +00001627 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001628 res = (validate_name(CHILD(tree, 4), "else")
1629 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001630 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001631
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001632 return (res);
1633
1634} /* validate_while() */
1635
1636
Guido van Rossum47478871996-08-21 14:32:37 +00001637static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001638validate_for(tree)
1639 node *tree;
1640{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001641 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001642 int res = (validate_ntype(tree, for_stmt)
1643 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001644 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001645 && validate_exprlist(CHILD(tree, 1))
1646 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001647 && validate_testlist(CHILD(tree, 3))
1648 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001649 && validate_suite(CHILD(tree, 5)));
1650
Guido van Rossum3d602e31996-07-21 02:33:56 +00001651 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001652 res = (validate_name(CHILD(tree, 6), "else")
1653 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001654 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001655
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001656 return (res);
1657
1658} /* validate_for() */
1659
1660
Guido van Rossum3d602e31996-07-21 02:33:56 +00001661/* try_stmt:
1662 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1663 * | 'try' ':' suite 'finally' ':' suite
1664 *
1665 */
Guido van Rossum47478871996-08-21 14:32:37 +00001666static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001667validate_try(tree)
1668 node *tree;
1669{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001670 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001671 int pos = 3;
1672 int res = (validate_ntype(tree, try_stmt)
1673 && (nch >= 6) && ((nch % 3) == 0));
1674
1675 if (res)
1676 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001677 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001678 && validate_suite(CHILD(tree, 2))
1679 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001680 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001681 else {
1682 const char* name = "execpt";
1683 char buffer[60];
1684 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1685 name = STR(CHILD(tree, nch - 3));
1686 sprintf(buffer, "Illegal number of children for try/%s node.", name);
1687 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001688 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001689 /* Skip past except_clause sections: */
1690 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1691 res = (validate_except_clause(CHILD(tree, pos))
1692 && validate_colon(CHILD(tree, pos + 1))
1693 && validate_suite(CHILD(tree, pos + 2)));
1694 pos += 3;
1695 }
1696 if (res && (pos < nch)) {
1697 res = validate_ntype(CHILD(tree, pos), NAME);
1698 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1699 res = (validate_numnodes(tree, 6, "try/finally")
1700 && validate_colon(CHILD(tree, 4))
1701 && validate_suite(CHILD(tree, 5)));
1702 else if (res)
1703 if (nch == (pos + 3)) {
1704 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1705 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1706 if (!res)
1707 err_string("Illegal trailing triple in try statement.");
1708 }
1709 else if (nch == (pos + 6))
1710 res = (validate_name(CHILD(tree, pos), "except")
1711 && validate_colon(CHILD(tree, pos + 1))
1712 && validate_suite(CHILD(tree, pos + 2))
1713 && validate_name(CHILD(tree, pos + 3), "else"));
1714 else
1715 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001716 }
1717 return (res);
1718
1719} /* validate_try() */
1720
1721
Guido van Rossum47478871996-08-21 14:32:37 +00001722static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001723validate_except_clause(tree)
1724 node *tree;
1725{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001726 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001727 int res = (validate_ntype(tree, except_clause)
1728 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001729 && validate_name(CHILD(tree, 0), "except"));
1730
Guido van Rossum3d602e31996-07-21 02:33:56 +00001731 if (res && (nch > 1))
1732 res = validate_test(CHILD(tree, 1));
1733 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001734 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001735 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001736
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001737 return (res);
1738
1739} /* validate_except_clause() */
1740
1741
Guido van Rossum47478871996-08-21 14:32:37 +00001742static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001743validate_test(tree)
1744 node *tree;
1745{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001746 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001747 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001748
Guido van Rossum3d602e31996-07-21 02:33:56 +00001749 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001750 res = ((nch == 1)
1751 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001752 else if (res) {
1753 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001754 res = validate_and_test(CHILD(tree, 0));
1755 for (pos = 1; res && (pos < nch); pos += 2)
1756 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001757 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001758 }
1759 return (res);
1760
1761} /* validate_test() */
1762
1763
Guido van Rossum47478871996-08-21 14:32:37 +00001764static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001765validate_and_test(tree)
1766 node *tree;
1767{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001768 int pos;
1769 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001770 int res = (validate_ntype(tree, and_test)
1771 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001772 && validate_not_test(CHILD(tree, 0)));
1773
Guido van Rossum3d602e31996-07-21 02:33:56 +00001774 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001775 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001776 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001777
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001778 return (res);
1779
1780} /* validate_and_test() */
1781
1782
Guido van Rossum47478871996-08-21 14:32:37 +00001783static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001784validate_not_test(tree)
1785 node *tree;
1786{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001787 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001788 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001789
Guido van Rossum3d602e31996-07-21 02:33:56 +00001790 if (res) {
1791 if (nch == 2)
1792 res = (validate_name(CHILD(tree, 0), "not")
1793 && validate_not_test(CHILD(tree, 1)));
1794 else if (nch == 1)
1795 res = validate_comparison(CHILD(tree, 0));
1796 }
1797 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001798
1799} /* validate_not_test() */
1800
1801
Guido van Rossum47478871996-08-21 14:32:37 +00001802static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001803validate_comparison(tree)
1804 node *tree;
1805{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001806 int pos;
1807 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001808 int res = (validate_ntype(tree, comparison)
1809 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001810 && validate_expr(CHILD(tree, 0)));
1811
Guido van Rossum3d602e31996-07-21 02:33:56 +00001812 for (pos = 1; res && (pos < nch); pos += 2)
1813 res = (validate_comp_op(CHILD(tree, pos))
1814 && validate_expr(CHILD(tree, pos + 1)));
1815
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001816 return (res);
1817
1818} /* validate_comparison() */
1819
1820
Guido van Rossum47478871996-08-21 14:32:37 +00001821static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001822validate_comp_op(tree)
1823 node *tree;
1824{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001825 int res = 0;
1826 int nch = NCH(tree);
1827
Guido van Rossum3d602e31996-07-21 02:33:56 +00001828 if (!validate_ntype(tree, comp_op))
1829 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001830 if (nch == 1) {
1831 /*
1832 * Only child will be a terminal with a well-defined symbolic name
1833 * or a NAME with a string of either 'is' or 'in'
1834 */
1835 tree = CHILD(tree, 0);
1836 switch (TYPE(tree)) {
1837 case LESS:
1838 case GREATER:
1839 case EQEQUAL:
1840 case EQUAL:
1841 case LESSEQUAL:
1842 case GREATEREQUAL:
1843 case NOTEQUAL:
1844 res = 1;
1845 break;
1846 case NAME:
1847 res = ((strcmp(STR(tree), "in") == 0)
1848 || (strcmp(STR(tree), "is") == 0));
1849 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001850 char buff[128];
1851 sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1852 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001853 }
1854 break;
1855 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001856 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001857 break;
1858 }
1859 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001860 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001861 res = (validate_ntype(CHILD(tree, 0), NAME)
1862 && validate_ntype(CHILD(tree, 1), NAME)
1863 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1864 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1865 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1866 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001867 if (!res && !PyErr_Occurred())
1868 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001869 }
1870 return (res);
1871
1872} /* validate_comp_op() */
1873
1874
Guido van Rossum47478871996-08-21 14:32:37 +00001875static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001876validate_expr(tree)
1877 node *tree;
1878{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001879 int j;
1880 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001881 int res = (validate_ntype(tree, expr)
1882 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001883 && validate_xor_expr(CHILD(tree, 0)));
1884
Guido van Rossum3d602e31996-07-21 02:33:56 +00001885 for (j = 2; res && (j < nch); j += 2)
1886 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001887 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001888
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001889 return (res);
1890
1891} /* validate_expr() */
1892
1893
Guido van Rossum47478871996-08-21 14:32:37 +00001894static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001895validate_xor_expr(tree)
1896 node *tree;
1897{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001898 int j;
1899 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001900 int res = (validate_ntype(tree, xor_expr)
1901 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001902 && validate_and_expr(CHILD(tree, 0)));
1903
Guido van Rossum3d602e31996-07-21 02:33:56 +00001904 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001905 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001906 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001907
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001908 return (res);
1909
1910} /* validate_xor_expr() */
1911
1912
Guido van Rossum47478871996-08-21 14:32:37 +00001913static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001914validate_and_expr(tree)
1915 node *tree;
1916{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001917 int pos;
1918 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001919 int res = (validate_ntype(tree, and_expr)
1920 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001921 && validate_shift_expr(CHILD(tree, 0)));
1922
Guido van Rossum3d602e31996-07-21 02:33:56 +00001923 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001924 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001925 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001926
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001927 return (res);
1928
1929} /* validate_and_expr() */
1930
1931
1932static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001933validate_chain_two_ops(tree, termvalid, op1, op2)
1934 node *tree;
1935 int (*termvalid)();
1936 int op1;
1937 int op2;
1938 {
1939 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001940 int nch = NCH(tree);
1941 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001942 && (*termvalid)(CHILD(tree, 0)));
1943
Guido van Rossum3d602e31996-07-21 02:33:56 +00001944 for ( ; res && (pos < nch); pos += 2) {
1945 if (TYPE(CHILD(tree, pos)) != op1)
1946 res = validate_ntype(CHILD(tree, pos), op2);
1947 if (res)
1948 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001949 }
1950 return (res);
1951
1952} /* validate_chain_two_ops() */
1953
1954
Guido van Rossum47478871996-08-21 14:32:37 +00001955static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001956validate_shift_expr(tree)
1957 node *tree;
1958{
1959 return (validate_ntype(tree, shift_expr)
1960 && validate_chain_two_ops(tree, validate_arith_expr,
1961 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001962
1963} /* validate_shift_expr() */
1964
1965
Guido van Rossum47478871996-08-21 14:32:37 +00001966static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001967validate_arith_expr(tree)
1968 node *tree;
1969{
1970 return (validate_ntype(tree, arith_expr)
1971 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001972
1973} /* validate_arith_expr() */
1974
1975
Guido van Rossum47478871996-08-21 14:32:37 +00001976static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001977validate_term(tree)
1978 node *tree;
1979{
1980 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001981 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001982 int res = (validate_ntype(tree, term)
1983 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001984 && validate_factor(CHILD(tree, 0)));
1985
Guido van Rossum3d602e31996-07-21 02:33:56 +00001986 for ( ; res && (pos < nch); pos += 2)
1987 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001988 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001989 || (TYPE(CHILD(tree, pos)) == PERCENT))
1990 && validate_factor(CHILD(tree, pos + 1)));
1991
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001992 return (res);
1993
1994} /* validate_term() */
1995
1996
Guido van Rossum3d602e31996-07-21 02:33:56 +00001997/* factor:
1998 *
1999 * factor: ('+'|'-'|'~') factor | power
2000 */
Guido van Rossum47478871996-08-21 14:32:37 +00002001static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002002validate_factor(tree)
2003 node *tree;
2004{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002005 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002006 int res = (validate_ntype(tree, factor)
2007 && (((nch == 2)
2008 && ((TYPE(CHILD(tree, 0)) == PLUS)
2009 || (TYPE(CHILD(tree, 0)) == MINUS)
2010 || (TYPE(CHILD(tree, 0)) == TILDE))
2011 && validate_factor(CHILD(tree, 1)))
2012 || ((nch == 1)
2013 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002014 return (res);
2015
2016} /* validate_factor() */
2017
2018
Guido van Rossum3d602e31996-07-21 02:33:56 +00002019/* power:
2020 *
2021 * power: atom trailer* ('**' factor)*
2022 */
Guido van Rossum47478871996-08-21 14:32:37 +00002023static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002024validate_power(tree)
2025 node *tree;
2026{
2027 int pos = 1;
2028 int nch = NCH(tree);
2029 int res = (validate_ntype(tree, power) && (nch >= 1)
2030 && validate_atom(CHILD(tree, 0)));
2031
2032 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2033 res = validate_trailer(CHILD(tree, pos++));
2034 if (res && (pos < nch)) {
2035 if (!is_even(nch - pos)) {
2036 err_string("Illegal number of nodes for 'power'.");
2037 return (0);
2038 }
2039 for ( ; res && (pos < (nch - 1)); pos += 2)
2040 res = (validate_doublestar(CHILD(tree, pos))
2041 && validate_factor(CHILD(tree, pos + 1)));
2042 }
2043 return (res);
2044
2045} /* validate_power() */
2046
2047
Guido van Rossum47478871996-08-21 14:32:37 +00002048static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002049validate_atom(tree)
2050 node *tree;
2051{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002052 int pos;
2053 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002054 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002055
2056 if (res) {
2057 switch (TYPE(CHILD(tree, 0))) {
2058 case LPAR:
2059 res = ((nch <= 3)
2060 && (validate_rparen(CHILD(tree, nch - 1))));
2061
Guido van Rossum3d602e31996-07-21 02:33:56 +00002062 if (res && (nch == 3))
2063 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002064 break;
2065 case LSQB:
2066 res = ((nch <= 3)
2067 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2068
Guido van Rossum3d602e31996-07-21 02:33:56 +00002069 if (res && (nch == 3))
2070 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002071 break;
2072 case LBRACE:
2073 res = ((nch <= 3)
2074 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2075
Guido van Rossum3d602e31996-07-21 02:33:56 +00002076 if (res && (nch == 3))
2077 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002078 break;
2079 case BACKQUOTE:
2080 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002081 && validate_testlist(CHILD(tree, 1))
2082 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2083 break;
2084 case NAME:
2085 case NUMBER:
2086 res = (nch == 1);
2087 break;
2088 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002089 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002090 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002091 break;
2092 default:
2093 res = 0;
2094 break;
2095 }
2096 }
2097 return (res);
2098
2099} /* validate_atom() */
2100
2101
Guido van Rossum3d602e31996-07-21 02:33:56 +00002102/* funcdef:
2103 * 'def' NAME parameters ':' suite
2104 *
2105 */
Guido van Rossum47478871996-08-21 14:32:37 +00002106static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002107validate_funcdef(tree)
2108 node *tree;
2109{
2110 return (validate_ntype(tree, funcdef)
2111 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002112 && validate_name(CHILD(tree, 0), "def")
2113 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002114 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002115 && validate_parameters(CHILD(tree, 2))
2116 && validate_suite(CHILD(tree, 4)));
2117
2118} /* validate_funcdef() */
2119
2120
Guido van Rossum47478871996-08-21 14:32:37 +00002121static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002122validate_lambdef(tree)
2123 node *tree;
2124{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002125 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002126 int res = (validate_ntype(tree, lambdef)
2127 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002128 && validate_name(CHILD(tree, 0), "lambda")
2129 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002130 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002131
Guido van Rossum3d602e31996-07-21 02:33:56 +00002132 if (res && (nch == 4))
2133 res = validate_varargslist(CHILD(tree, 1));
2134 else if (!res && !PyErr_Occurred())
2135 validate_numnodes(tree, 3, "lambdef");
2136
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002137 return (res);
2138
2139} /* validate_lambdef() */
2140
2141
Guido van Rossum3d602e31996-07-21 02:33:56 +00002142/* arglist:
2143 *
2144 * argument (',' argument)* [',']
2145 */
Guido van Rossum47478871996-08-21 14:32:37 +00002146static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002147validate_arglist(tree)
2148 node *tree;
2149{
Guido van Rossum47478871996-08-21 14:32:37 +00002150 return (validate_repeating_list(tree, arglist,
2151 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002152
2153} /* validate_arglist() */
2154
2155
2156
2157/* argument:
2158 *
2159 * [test '='] test
2160 */
Guido van Rossum47478871996-08-21 14:32:37 +00002161static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002162validate_argument(tree)
2163 node *tree;
2164{
2165 int nch = NCH(tree);
2166 int res = (validate_ntype(tree, argument)
2167 && ((nch == 1) || (nch == 3))
2168 && validate_test(CHILD(tree, 0)));
2169
2170 if (res && (nch == 3))
2171 res = (validate_equal(CHILD(tree, 1))
2172 && validate_test(CHILD(tree, 2)));
2173
2174 return (res);
2175
2176} /* validate_argument() */
2177
2178
2179
2180/* trailer:
2181 *
Guido van Rossum47478871996-08-21 14:32:37 +00002182 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002183 */
Guido van Rossum47478871996-08-21 14:32:37 +00002184static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002185validate_trailer(tree)
2186 node *tree;
2187{
2188 int nch = NCH(tree);
2189 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002190
2191 if (res) {
2192 switch (TYPE(CHILD(tree, 0))) {
2193 case LPAR:
2194 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002195 if (res && (nch == 3))
2196 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002197 break;
2198 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002199 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002200 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002201 && validate_ntype(CHILD(tree, 2), RSQB));
2202 break;
2203 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002204 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002205 && validate_ntype(CHILD(tree, 1), NAME));
2206 break;
2207 default:
2208 res = 0;
2209 break;
2210 }
2211 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002212 else
2213 validate_numnodes(tree, 2, "trailer");
2214
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002215 return (res);
2216
2217} /* validate_trailer() */
2218
2219
Guido van Rossum47478871996-08-21 14:32:37 +00002220/* subscriptlist:
2221 *
2222 * subscript (',' subscript)* [',']
2223 */
2224static int
2225validate_subscriptlist(tree)
2226 node *tree;
2227{
2228 return (validate_repeating_list(tree, subscriptlist,
2229 validate_subscript, "subscriptlist"));
2230
2231} /* validate_subscriptlist() */
2232
2233
Guido van Rossum3d602e31996-07-21 02:33:56 +00002234/* subscript:
2235 *
Guido van Rossum47478871996-08-21 14:32:37 +00002236 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002237 */
Guido van Rossum47478871996-08-21 14:32:37 +00002238static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002239validate_subscript(tree)
2240 node *tree;
2241{
Guido van Rossum47478871996-08-21 14:32:37 +00002242 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002243 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002244 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002245
Guido van Rossum47478871996-08-21 14:32:37 +00002246 if (!res) {
2247 if (!PyErr_Occurred())
2248 err_string("invalid number of arguments for subscript node");
2249 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002250 }
Guido van Rossum47478871996-08-21 14:32:37 +00002251 if (TYPE(CHILD(tree, 0)) == DOT)
2252 /* take care of ('.' '.' '.') possibility */
2253 return (validate_numnodes(tree, 3, "subscript")
2254 && validate_dot(CHILD(tree, 0))
2255 && validate_dot(CHILD(tree, 1))
2256 && validate_dot(CHILD(tree, 2)));
2257 if (nch == 1) {
2258 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002259 res = validate_test(CHILD(tree, 0));
2260 else
Guido van Rossum47478871996-08-21 14:32:37 +00002261 res = validate_colon(CHILD(tree, 0));
2262 return (res);
2263 }
2264 /* Must be [test] ':' [test] [sliceop],
2265 * but at least one of the optional components will
2266 * be present, but we don't know which yet.
2267 */
2268 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2269 res = validate_test(CHILD(tree, 0));
2270 offset = 1;
2271 }
2272 if (res)
2273 res = validate_colon(CHILD(tree, offset));
2274 if (res) {
2275 int rem = nch - ++offset;
2276 if (rem) {
2277 if (TYPE(CHILD(tree, offset)) == test) {
2278 res = validate_test(CHILD(tree, offset));
2279 ++offset;
2280 --rem;
2281 }
2282 if (res && rem)
2283 res = validate_sliceop(CHILD(tree, offset));
2284 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002285 }
2286 return (res);
2287
2288} /* validate_subscript() */
2289
2290
Guido van Rossum47478871996-08-21 14:32:37 +00002291static int
2292validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002293 node *tree;
2294{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002295 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002296 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2297 && validate_ntype(tree, sliceop);
2298 if (!res && !PyErr_Occurred()) {
2299 validate_numnodes(tree, 1, "sliceop");
2300 res = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002301 }
Guido van Rossum47478871996-08-21 14:32:37 +00002302 if (res)
2303 res = validate_colon(CHILD(tree, 0));
2304 if (res && (nch == 2))
2305 res = validate_test(CHILD(tree, 1));
2306
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002307 return (res);
2308
Guido van Rossum47478871996-08-21 14:32:37 +00002309} /* validate_sliceop() */
2310
2311
2312static int
2313validate_exprlist(tree)
2314 node *tree;
2315{
2316 return (validate_repeating_list(tree, exprlist,
2317 validate_expr, "exprlist"));
2318
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002319} /* validate_exprlist() */
2320
2321
Guido van Rossum47478871996-08-21 14:32:37 +00002322static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002323validate_dictmaker(tree)
2324 node *tree;
2325{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002326 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002327 int res = (validate_ntype(tree, dictmaker)
2328 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002329 && validate_test(CHILD(tree, 0))
2330 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002331 && validate_test(CHILD(tree, 2)));
2332
Guido van Rossum3d602e31996-07-21 02:33:56 +00002333 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002334 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002335 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002336 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002337
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002338 if (res && (nch > 3)) {
2339 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002340 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002341 while (res && (pos < nch)) {
2342 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002343 && validate_test(CHILD(tree, pos + 1))
2344 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002345 && validate_test(CHILD(tree, pos + 3)));
2346 pos += 4;
2347 }
2348 }
2349 return (res);
2350
2351} /* validate_dictmaker() */
2352
2353
Guido van Rossum47478871996-08-21 14:32:37 +00002354static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002355validate_eval_input(tree)
2356 node *tree;
2357{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002358 int pos;
2359 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002360 int res = (validate_ntype(tree, eval_input)
2361 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002362 && validate_testlist(CHILD(tree, 0))
2363 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2364
Guido van Rossum3d602e31996-07-21 02:33:56 +00002365 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002366 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002367
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002368 return (res);
2369
2370} /* validate_eval_input() */
2371
2372
Guido van Rossum47478871996-08-21 14:32:37 +00002373static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002374validate_node(tree)
2375 node *tree;
2376{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002377 int nch = 0; /* num. children on current node */
2378 int res = 1; /* result value */
2379 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002380
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002381 while (res & (tree != 0)) {
2382 nch = NCH(tree);
2383 next = 0;
2384 switch (TYPE(tree)) {
2385 /*
2386 * Definition nodes.
2387 */
2388 case funcdef:
2389 res = validate_funcdef(tree);
2390 break;
2391 case classdef:
2392 res = validate_class(tree);
2393 break;
2394 /*
2395 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002396 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002397 */
2398 case stmt:
2399 res = validate_stmt(tree);
2400 break;
2401 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002402 /*
2403 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum925e5471997-04-02 05:32:13 +00002404 * | import_stmt | global_stmt | exec_stmt | assert_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002405 */
2406 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002407 break;
2408 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002409 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002410 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2411 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2412 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002413 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2414 if (res)
2415 next = CHILD(tree, 0);
2416 else if (nch == 1)
2417 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002418 break;
2419 /*
2420 * Compound statements.
2421 */
2422 case simple_stmt:
2423 res = validate_simple_stmt(tree);
2424 break;
2425 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002426 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002427 break;
2428 /*
2429 * Fundemental statements.
2430 */
2431 case expr_stmt:
2432 res = validate_expr_stmt(tree);
2433 break;
2434 case print_stmt:
2435 res = validate_print_stmt(tree);
2436 break;
2437 case del_stmt:
2438 res = validate_del_stmt(tree);
2439 break;
2440 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002441 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002442 && validate_name(CHILD(tree, 0), "pass"));
2443 break;
2444 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002445 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002446 && validate_name(CHILD(tree, 0), "break"));
2447 break;
2448 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002449 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002450 && validate_name(CHILD(tree, 0), "continue"));
2451 break;
2452 case return_stmt:
2453 res = validate_return_stmt(tree);
2454 break;
2455 case raise_stmt:
2456 res = validate_raise_stmt(tree);
2457 break;
2458 case import_stmt:
2459 res = validate_import_stmt(tree);
2460 break;
2461 case global_stmt:
2462 res = validate_global_stmt(tree);
2463 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002464 case exec_stmt:
2465 res = validate_exec_stmt(tree);
2466 break;
Guido van Rossum925e5471997-04-02 05:32:13 +00002467 case assert_stmt:
2468 res = validate_assert_stmt(tree);
2469 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002470 case if_stmt:
2471 res = validate_if(tree);
2472 break;
2473 case while_stmt:
2474 res = validate_while(tree);
2475 break;
2476 case for_stmt:
2477 res = validate_for(tree);
2478 break;
2479 case try_stmt:
2480 res = validate_try(tree);
2481 break;
2482 case suite:
2483 res = validate_suite(tree);
2484 break;
2485 /*
2486 * Expression nodes.
2487 */
2488 case testlist:
2489 res = validate_testlist(tree);
2490 break;
2491 case test:
2492 res = validate_test(tree);
2493 break;
2494 case and_test:
2495 res = validate_and_test(tree);
2496 break;
2497 case not_test:
2498 res = validate_not_test(tree);
2499 break;
2500 case comparison:
2501 res = validate_comparison(tree);
2502 break;
2503 case exprlist:
2504 res = validate_exprlist(tree);
2505 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002506 case comp_op:
2507 res = validate_comp_op(tree);
2508 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002509 case expr:
2510 res = validate_expr(tree);
2511 break;
2512 case xor_expr:
2513 res = validate_xor_expr(tree);
2514 break;
2515 case and_expr:
2516 res = validate_and_expr(tree);
2517 break;
2518 case shift_expr:
2519 res = validate_shift_expr(tree);
2520 break;
2521 case arith_expr:
2522 res = validate_arith_expr(tree);
2523 break;
2524 case term:
2525 res = validate_term(tree);
2526 break;
2527 case factor:
2528 res = validate_factor(tree);
2529 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002530 case power:
2531 res = validate_power(tree);
2532 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002533 case atom:
2534 res = validate_atom(tree);
2535 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002536
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002537 default:
2538 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002539 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002540 res = 0;
2541 break;
2542 }
2543 tree = next;
2544 }
2545 return (res);
2546
2547} /* validate_node() */
2548
2549
Guido van Rossum47478871996-08-21 14:32:37 +00002550static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002551validate_expr_tree(tree)
2552 node *tree;
2553{
2554 int res = validate_eval_input(tree);
2555
2556 if (!res && !PyErr_Occurred())
2557 err_string("Could not validate expression tuple.");
2558
2559 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002560
2561} /* validate_expr_tree() */
2562
2563
Guido van Rossum3d602e31996-07-21 02:33:56 +00002564/* file_input:
2565 * (NEWLINE | stmt)* ENDMARKER
2566 */
Guido van Rossum47478871996-08-21 14:32:37 +00002567static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002568validate_file_input(tree)
2569 node *tree;
2570{
2571 int j = 0;
2572 int nch = NCH(tree) - 1;
2573 int res = ((nch >= 0)
2574 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002575
Guido van Rossum3d602e31996-07-21 02:33:56 +00002576 for ( ; res && (j < nch); ++j) {
2577 if (TYPE(CHILD(tree, j)) == stmt)
2578 res = validate_stmt(CHILD(tree, j));
2579 else
2580 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002581 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002582 /* This stays in to prevent any internal failues from getting to the
2583 * user. Hopefully, this won't be needed. If a user reports getting
2584 * this, we have some debugging to do.
2585 */
2586 if (!res && !PyErr_Occurred())
2587 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2588
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002589 return (res);
2590
Guido van Rossum2a288461996-08-21 21:55:43 +00002591} /* validate_file_input() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002592
2593
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002594/* Functions exported by this module. Most of this should probably
2595 * be converted into an AST object with methods, but that is better
2596 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002597 * We'd really have to write a wrapper around it all anyway to allow
2598 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002599 */
2600static PyMethodDef parser_functions[] = {
Guido van Rossum3d602e31996-07-21 02:33:56 +00002601 {"ast2tuple", parser_ast2tuple, 1,
2602 "Creates a tuple-tree representation of an AST."},
Guido van Rossum47478871996-08-21 14:32:37 +00002603 {"ast2list", parser_ast2list, 1,
2604 "Creates a list-tree representation of an AST."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002605 {"compileast", parser_compileast, 1,
2606 "Compiles an AST object into a code object."},
2607 {"expr", parser_expr, 1,
2608 "Creates an AST object from an expression."},
2609 {"isexpr", parser_isexpr, 1,
2610 "Determines if an AST object was created from an expression."},
2611 {"issuite", parser_issuite, 1,
2612 "Determines if an AST object was created from a suite."},
2613 {"suite", parser_suite, 1,
2614 "Creates an AST object from a suite."},
Guido van Rossum47478871996-08-21 14:32:37 +00002615 {"sequence2ast", parser_tuple2ast, 1,
2616 "Creates an AST object from a tree representation."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002617 {"tuple2ast", parser_tuple2ast, 1,
Guido van Rossum47478871996-08-21 14:32:37 +00002618 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002619
2620 {0, 0, 0}
2621 };
2622
2623
Guido van Rossum52f2c051993-11-10 12:53:24 +00002624void
Guido van Rossum3d602e31996-07-21 02:33:56 +00002625initparser()
2626 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002627 PyObject* module;
2628 PyObject* dict;
2629
2630 PyAST_Type.ob_type = &PyType_Type;
2631 module = Py_InitModule("parser", parser_functions);
2632 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002633
2634 parser_error = PyString_FromString("parser.ParserError");
2635
2636 if ((parser_error == 0)
2637 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2638 /*
2639 * This is serious.
2640 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002641 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002642 }
2643 /*
2644 * Nice to have, but don't cry if we fail.
2645 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002646 Py_INCREF(&PyAST_Type);
2647 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2648
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002649 PyDict_SetItemString(dict, "__copyright__",
2650 PyString_FromString(parser_copyright_string));
2651 PyDict_SetItemString(dict, "__doc__",
2652 PyString_FromString(parser_doc_string));
2653 PyDict_SetItemString(dict, "__version__",
2654 PyString_FromString(parser_version_string));
2655
2656} /* initparser() */
2657
2658
2659/*
Guido van Rossum3d602e31996-07-21 02:33:56 +00002660 * end of parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002661 */