blob: 75b929beb087bc670da30d842e63dfac8313eb3e [file] [log] [blame]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001/* parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002 *
Guido van Rossum47478871996-08-21 14:32:37 +00003 * Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic
4 * Institute and State University, Blacksburg, Virginia, USA.
5 * Portions copyright 1991-1995 by Stichting Mathematisch Centrum,
6 * Amsterdam, The Netherlands. Copying is permitted under the terms
7 * associated with the main Python distribution, with the additional
8 * restriction that this additional notice be included and maintained
9 * on all distributed copies.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000010 *
Guido van Rossum47478871996-08-21 14:32:37 +000011 * This module serves to replace the original parser module written
12 * by Guido. The functionality is not matched precisely, but the
13 * original may be implemented on top of this. This is desirable
14 * since the source of the text to be parsed is now divorced from
15 * this interface.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000016 *
Guido van Rossum47478871996-08-21 14:32:37 +000017 * Unlike the prior interface, the ability to give a parse tree
18 * produced by Python code as a tuple to the compiler is enabled by
19 * this module. See the documentation for more details.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000020 */
21
22#include "Python.h" /* general Python API */
23#include "graminit.h" /* symbols defined in the grammar */
24#include "node.h" /* internal parser structure */
25#include "token.h" /* token definitions */
26 /* ISTERMINAL() / ISNONTERMINAL() */
Guido van Rossum3d602e31996-07-21 02:33:56 +000027#include "compile.h" /* PyNode_Compile() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000028
Guido van Rossum1f14ccf1997-10-08 15:45:53 +000029#ifndef MS_WINDOWS
30char *strdup();
31#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000032
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000033/* String constants used to initialize module attributes.
34 *
35 */
36static char*
37parser_copyright_string
Guido van Rossum2a288461996-08-21 21:55:43 +000038= "Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
39University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
40Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\
41Centrum, Amsterdam, The Netherlands.";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000042
43
44static char*
45parser_doc_string
46= "This is an interface to Python's internal parser.";
47
48static char*
Guido van Rossum47478871996-08-21 14:32:37 +000049parser_version_string = "0.4";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000050
51
Guido van Rossum2a288461996-08-21 21:55:43 +000052typedef PyObject* (*SeqMaker) Py_PROTO((int length));
53typedef void (*SeqInserter) Py_PROTO((PyObject* sequence,
54 int index,
55 PyObject* element));
Guido van Rossum47478871996-08-21 14:32:37 +000056
Guido van Rossum3d602e31996-07-21 02:33:56 +000057/* The function below is copyrigthed by Stichting Mathematisch Centrum. The
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000058 * original copyright statement is included below, and continues to apply
59 * in full to the function immediately following. All other material is
60 * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
61 * Institute and State University. Changes were made to comply with the
Guido van Rossum2a288461996-08-21 21:55:43 +000062 * new naming conventions. Added arguments to provide support for creating
63 * lists as well as tuples, and optionally including the line numbers.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000064 */
65
Guido van Rossum52f2c051993-11-10 12:53:24 +000066/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +000067Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
68The Netherlands.
Guido van Rossum52f2c051993-11-10 12:53:24 +000069
70 All Rights Reserved
71
Guido van Rossum3d602e31996-07-21 02:33:56 +000072Permission to use, copy, modify, and distribute this software and its
73documentation for any purpose and without fee is hereby granted,
Guido van Rossum52f2c051993-11-10 12:53:24 +000074provided that the above copyright notice appear in all copies and that
Guido van Rossum3d602e31996-07-21 02:33:56 +000075both that copyright notice and this permission notice appear in
Guido van Rossum52f2c051993-11-10 12:53:24 +000076supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000077Centrum or CWI or Corporation for National Research Initiatives or
78CNRI not be used in advertising or publicity pertaining to
79distribution of the software without specific, written prior
80permission.
Guido van Rossum52f2c051993-11-10 12:53:24 +000081
Guido van Rossumd266eb41996-10-25 14:44:06 +000082While CWI is the initial source for this software, a modified version
83is made available by the Corporation for National Research Initiatives
84(CNRI) at the Internet address ftp://ftp.python.org.
85
86STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
87REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
88MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
89CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
90DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
91PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
92TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
93PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum52f2c051993-11-10 12:53:24 +000094
95******************************************************************/
96
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000097static PyObject*
Guido van Rossum47478871996-08-21 14:32:37 +000098node2tuple(n, mkseq, addelem, lineno)
99 node *n; /* node to convert */
100 SeqMaker mkseq; /* create sequence */
101 SeqInserter addelem; /* func. to add elem. in seq. */
102 int lineno; /* include line numbers? */
103{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000104 if (n == NULL) {
105 Py_INCREF(Py_None);
106 return Py_None;
107 }
108 if (ISNONTERMINAL(TYPE(n))) {
109 int i;
110 PyObject *v, *w;
Guido van Rossum47478871996-08-21 14:32:37 +0000111 v = mkseq(1 + NCH(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000112 if (v == NULL)
113 return v;
114 w = PyInt_FromLong(TYPE(n));
115 if (w == NULL) {
116 Py_DECREF(v);
117 return NULL;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000118 }
Guido van Rossum47478871996-08-21 14:32:37 +0000119 addelem(v, 0, w);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000120 for (i = 0; i < NCH(n); i++) {
Guido van Rossum47478871996-08-21 14:32:37 +0000121 w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000122 if (w == NULL) {
123 Py_DECREF(v);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000124 return NULL;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000125 }
Guido van Rossum47478871996-08-21 14:32:37 +0000126 addelem(v, i+1, w);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000127 }
Guido van Rossum47478871996-08-21 14:32:37 +0000128 return (v);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000129 }
130 else if (ISTERMINAL(TYPE(n))) {
Guido van Rossum47478871996-08-21 14:32:37 +0000131 PyObject *result = mkseq(2 + lineno);
132 if (result != NULL) {
133 addelem(result, 0, PyInt_FromLong(TYPE(n)));
134 addelem(result, 1, PyString_FromString(STR(n)));
135 if (lineno == 1)
136 addelem(result, 2, PyInt_FromLong(n->n_lineno));
137 }
138 return (result);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000139 }
140 else {
141 PyErr_SetString(PyExc_SystemError,
142 "unrecognized parse tree node type");
143 return NULL;
144 }
Guido van Rossum47478871996-08-21 14:32:37 +0000145} /* node2tuple() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000146/*
147 * End of material copyrighted by Stichting Mathematisch Centrum.
148 */
Guido van Rossum52f2c051993-11-10 12:53:24 +0000149
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000150
151
152/* There are two types of intermediate objects we're interested in:
153 * 'eval' and 'exec' types. These constants can be used in the ast_type
154 * field of the object type to identify which any given object represents.
155 * These should probably go in an external header to allow other extensions
156 * to use them, but then, we really should be using C++ too. ;-)
157 *
Guido van Rossum3d602e31996-07-21 02:33:56 +0000158 * The PyAST_FRAGMENT type is not currently supported. Maybe not useful?
159 * Haven't decided yet.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000160 */
161
162#define PyAST_EXPR 1
163#define PyAST_SUITE 2
164#define PyAST_FRAGMENT 3
165
166
167/* These are the internal objects and definitions required to implement the
168 * AST type. Most of the internal names are more reminiscent of the 'old'
169 * naming style, but the code uses the new naming convention.
170 */
171
172static PyObject*
173parser_error = 0;
174
175
176typedef struct _PyAST_Object {
177
178 PyObject_HEAD /* standard object header */
179 node* ast_node; /* the node* returned by the parser */
180 int ast_type; /* EXPR or SUITE ? */
181
182} PyAST_Object;
183
184
Guido van Rossum2a288461996-08-21 21:55:43 +0000185staticforward void parser_free Py_PROTO((PyAST_Object *ast));
186staticforward int parser_compare Py_PROTO((PyAST_Object *left,
187 PyAST_Object *right));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000188
189
190/* static */
191PyTypeObject PyAST_Type = {
192
Guido van Rossumf2b2dac1997-01-23 23:29:44 +0000193 PyObject_HEAD_INIT(NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000194 0,
195 "ast", /* tp_name */
196 sizeof(PyAST_Object), /* tp_basicsize */
197 0, /* tp_itemsize */
198 (destructor)parser_free, /* tp_dealloc */
199 0, /* tp_print */
200 0, /* tp_getattr */
201 0, /* tp_setattr */
202 (cmpfunc)parser_compare, /* tp_compare */
203 0, /* tp_repr */
204 0, /* tp_as_number */
205 0, /* tp_as_sequence */
206 0, /* tp_as_mapping */
207 0, /* tp_hash */
208 0, /* tp_call */
Fred Drake69b9ae41997-05-23 04:04:17 +0000209 0, /* tp_str */
210 0, /* tp_getattro */
211 0, /* tp_setattro */
212
213 /* Functions to access object as input/output buffer */
214 0, /* tp_as_buffer */
215
216 /* Space for future expansion */
217 0, /* tp_xxx4 */
218
219 /* __doc__ */
220 "Intermediate representation of a Python parse tree."
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000221
222}; /* PyAST_Type */
223
224
225static int
226parser_compare_nodes(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000227 node *left;
228 node *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000229{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000230 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000231
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000232 if (TYPE(left) < TYPE(right))
233 return (-1);
234
235 if (TYPE(right) < TYPE(left))
236 return (1);
237
238 if (ISTERMINAL(TYPE(left)))
239 return (strcmp(STR(left), STR(right)));
240
241 if (NCH(left) < NCH(right))
242 return (-1);
243
244 if (NCH(right) < NCH(left))
245 return (1);
246
247 for (j = 0; j < NCH(left); ++j) {
248 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
249
250 if (v)
251 return (v);
252 }
253 return (0);
254
255} /* parser_compare_nodes() */
256
257
258/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
259 *
260 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
261 * This really just wraps a call to parser_compare_nodes() with some easy
262 * checks and protection code.
263 *
264 */
265static int
266parser_compare(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000267 PyAST_Object *left;
268 PyAST_Object *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000269{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000270 if (left == right)
271 return (0);
272
273 if ((left == 0) || (right == 0))
274 return (-1);
275
276 return (parser_compare_nodes(left->ast_node, right->ast_node));
277
278} /* parser_compare() */
279
280
281/* parser_newastobject(node* ast)
282 *
283 * Allocates a new Python object representing an AST. This is simply the
284 * 'wrapper' object that holds a node* and allows it to be passed around in
285 * Python code.
286 *
287 */
288static PyObject*
289parser_newastobject(ast, type)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000290 node *ast;
291 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000292{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000293 PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
294
295 if (o != 0) {
296 o->ast_node = ast;
297 o->ast_type = type;
298 }
299 return ((PyObject*)o);
300
301} /* parser_newastobject() */
302
303
304/* void parser_free(PyAST_Object* ast)
305 *
306 * This is called by a del statement that reduces the reference count to 0.
307 *
308 */
309static void
310parser_free(ast)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000311 PyAST_Object *ast;
Guido van Rossum47478871996-08-21 14:32:37 +0000312{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000313 PyNode_Free(ast->ast_node);
314 PyMem_DEL(ast);
315
316} /* parser_free() */
317
318
319/* parser_ast2tuple(PyObject* self, PyObject* args)
320 *
321 * This provides conversion from a node* to a tuple object that can be
322 * returned to the Python-level caller. The AST object is not modified.
323 *
324 */
325static PyObject*
326parser_ast2tuple(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000327 PyObject *self;
328 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000329{
330 PyObject *ast;
331 PyObject *line_option = 0;
332 PyObject *res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000333
Guido van Rossum47478871996-08-21 14:32:37 +0000334 if (PyArg_ParseTuple(args, "O!|O:ast2tuple", &PyAST_Type, &ast,
335 &line_option)) {
336 int lineno = 0;
337 if (line_option != 0) {
338 lineno = PyObject_IsTrue(line_option);
339 lineno = lineno ? 1 : 0;
340 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000341 /*
342 * Convert AST into a tuple representation. Use Guido's function,
343 * since it's known to work already.
344 */
Guido van Rossum47478871996-08-21 14:32:37 +0000345 res = node2tuple(((PyAST_Object*)ast)->ast_node,
346 PyTuple_New, PyTuple_SetItem, lineno);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000347 }
348 return (res);
349
350} /* parser_ast2tuple() */
351
352
Guido van Rossum47478871996-08-21 14:32:37 +0000353/* parser_ast2tuple(PyObject* self, PyObject* args)
354 *
355 * This provides conversion from a node* to a tuple object that can be
356 * returned to the Python-level caller. The AST object is not modified.
357 *
358 */
359static PyObject*
360parser_ast2list(self, args)
361 PyObject *self;
362 PyObject *args;
363{
364 PyObject *ast;
365 PyObject *line_option = 0;
366 PyObject *res = 0;
367
368 if (PyArg_ParseTuple(args, "O!|O:ast2list", &PyAST_Type, &ast,
369 &line_option)) {
370 int lineno = 0;
371 if (line_option != 0) {
372 lineno = PyObject_IsTrue(line_option);
373 lineno = lineno ? 1 : 0;
374 }
375 /*
376 * Convert AST into a tuple representation. Use Guido's function,
377 * since it's known to work already.
378 */
379 res = node2tuple(((PyAST_Object*)ast)->ast_node,
380 PyList_New, PyList_SetItem, lineno);
381 }
382 return (res);
383
384} /* parser_ast2list() */
385
386
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000387/* parser_compileast(PyObject* self, PyObject* args)
388 *
389 * This function creates code objects from the parse tree represented by
390 * the passed-in data object. An optional file name is passed in as well.
391 *
392 */
393static PyObject*
394parser_compileast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000395 PyObject *self;
396 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000397{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000398 PyAST_Object* ast;
399 PyObject* res = 0;
400 char* str = "<ast>";
401
402 if (PyArg_ParseTuple(args, "O!|s", &PyAST_Type, &ast, &str))
Guido van Rossum3d602e31996-07-21 02:33:56 +0000403 res = (PyObject*) PyNode_Compile(ast->ast_node, str);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000404
405 return (res);
406
407} /* parser_compileast() */
408
409
410/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
411 * PyObject* parser_issuite(PyObject* self, PyObject* args)
412 *
413 * Checks the passed-in AST object to determine if it is an expression or
414 * a statement suite, respectively. The return is a Python truth value.
415 *
416 */
417static PyObject*
418parser_isexpr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000419 PyObject *self;
420 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000421{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000422 PyAST_Object* ast;
423 PyObject* res = 0;
424
425 if (PyArg_ParseTuple(args, "O!:isexpr", &PyAST_Type, &ast)) {
426 /*
427 * Check to see if the AST represents an expression or not.
428 */
429 res = (ast->ast_type == PyAST_EXPR) ? Py_True : Py_False;
430 Py_INCREF(res);
431 }
432 return (res);
433
434} /* parser_isexpr() */
435
436
437static PyObject*
438parser_issuite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000439 PyObject *self;
440 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000441{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000442 PyAST_Object* ast;
443 PyObject* res = 0;
444
Guido van Rossum3d602e31996-07-21 02:33:56 +0000445 if (PyArg_ParseTuple(args, "O!:issuite", &PyAST_Type, &ast)) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000446 /*
447 * Check to see if the AST represents an expression or not.
448 */
449 res = (ast->ast_type == PyAST_EXPR) ? Py_False : Py_True;
450 Py_INCREF(res);
451 }
452 return (res);
453
454} /* parser_issuite() */
455
456
Guido van Rossum3d602e31996-07-21 02:33:56 +0000457/* err_string(char* message)
458 *
459 * Sets the error string for an exception of type ParserError.
460 *
461 */
462static void
463err_string(message)
464 char *message;
Guido van Rossum47478871996-08-21 14:32:37 +0000465{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000466 PyErr_SetString(parser_error, message);
467
468} /* err_string() */
469
470
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000471/* PyObject* parser_do_parse(PyObject* args, int type)
472 *
473 * Internal function to actually execute the parse and return the result if
474 * successful, or set an exception if not.
475 *
476 */
477static PyObject*
478parser_do_parse(args, type)
479 PyObject *args;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000480 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000481{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000482 char* string = 0;
483 PyObject* res = 0;
484
485 if (PyArg_ParseTuple(args, "s", &string)) {
486 node* n = PyParser_SimpleParseString(string,
487 (type == PyAST_EXPR)
488 ? eval_input : file_input);
489
490 if (n != 0)
491 res = parser_newastobject(n, type);
492 else
Guido van Rossum3d602e31996-07-21 02:33:56 +0000493 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000494 }
495 return (res);
496
497} /* parser_do_parse() */
498
499
500/* PyObject* parser_expr(PyObject* self, PyObject* args)
501 * PyObject* parser_suite(PyObject* self, PyObject* args)
502 *
503 * External interfaces to the parser itself. Which is called determines if
504 * the parser attempts to recognize an expression ('eval' form) or statement
505 * suite ('exec' form). The real work is done by parser_do_parse() above.
506 *
507 */
508static PyObject*
509parser_expr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000510 PyObject *self;
511 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000512{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000513 return (parser_do_parse(args, PyAST_EXPR));
514
515} /* parser_expr() */
516
517
518static PyObject*
519parser_suite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000520 PyObject *self;
521 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000522{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000523 return (parser_do_parse(args, PyAST_SUITE));
524
525} /* parser_suite() */
526
527
528
529/* This is the messy part of the code. Conversion from a tuple to an AST
530 * object requires that the input tuple be valid without having to rely on
531 * catching an exception from the compiler. This is done to allow the
532 * compiler itself to remain fast, since most of its input will come from
533 * the parser directly, and therefore be known to be syntactically correct.
534 * This validation is done to ensure that we don't core dump the compile
535 * phase, returning an exception instead.
536 *
537 * Two aspects can be broken out in this code: creating a node tree from
538 * the tuple passed in, and verifying that it is indeed valid. It may be
539 * advantageous to expand the number of AST types to include funcdefs and
540 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
541 * here. They are not necessary, and not quite as useful in a raw form.
542 * For now, let's get expressions and suites working reliably.
543 */
544
545
Guido van Rossum2a288461996-08-21 21:55:43 +0000546staticforward node* build_node_tree Py_PROTO((PyObject *tuple));
547staticforward int validate_expr_tree Py_PROTO((node *tree));
548staticforward int validate_file_input Py_PROTO((node *tree));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000549
550
551/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
552 *
553 * This is the public function, called from the Python code. It receives a
554 * single tuple object from the caller, and creates an AST object if the
555 * tuple can be validated. It does this by checking the first code of the
556 * tuple, and, if acceptable, builds the internal representation. If this
557 * step succeeds, the internal representation is validated as fully as
558 * possible with the various validate_*() routines defined below.
559 *
560 * This function must be changed if support is to be added for PyAST_FRAGMENT
561 * AST objects.
562 *
563 */
564static PyObject*
565parser_tuple2ast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000566 PyObject *self;
567 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000568{
569 PyObject *ast = 0;
570 PyObject *tuple = 0;
571 PyObject *temp = 0;
572 int ok;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000573 int start_sym = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000574
Guido van Rossum47478871996-08-21 14:32:37 +0000575 if (!PyArg_ParseTuple(args, "O:tuple2ast", &tuple))
576 return (0);
577 if (!PySequence_Check(tuple)) {
578 PyErr_SetString(PyExc_ValueError,
579 "tuple2ast() requires a single sequence argument");
580 return (0);
581 }
582 /*
583 * This mess of tests is written this way so we can use the abstract
584 * object interface (AOI). Unfortunately, the AOI increments reference
585 * counts, which requires that we store a pointer to retrieved object
586 * so we can DECREF it after the check. But we really should accept
587 * lists as well as tuples at the very least.
588 */
589 ok = PyObject_Length(tuple) >= 2;
590 if (ok) {
591 temp = PySequence_GetItem(tuple, 0);
592 ok = (temp != NULL) && PyInt_Check(temp);
593 if (ok)
594 /* this is used after the initial checks: */
595 start_sym = PyInt_AsLong(temp);
596 Py_XDECREF(temp);
597 }
598 if (ok) {
599 temp = PySequence_GetItem(tuple, 1);
600 ok = (temp != NULL) && PySequence_Check(temp);
601 Py_XDECREF(temp);
602 }
603 if (ok) {
604 temp = PySequence_GetItem(tuple, 1);
605 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
606 if (ok) {
607 PyObject *temp2 = PySequence_GetItem(temp, 0);
608 if (temp2 != NULL) {
609 ok = PyInt_Check(temp2);
610 Py_DECREF(temp2);
611 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000612 }
Guido van Rossum47478871996-08-21 14:32:37 +0000613 Py_XDECREF(temp);
614 }
615 /* If we've failed at some point, get out of here. */
616 if (!ok) {
617 err_string("malformed sequence for tuple2ast()");
618 return (0);
619 }
620 /*
621 * This might be a valid parse tree, but let's do a quick check
622 * before we jump the gun.
623 */
624 if (start_sym == eval_input) {
625 /* Might be an eval form. */
626 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000627
Guido van Rossum47478871996-08-21 14:32:37 +0000628 if ((expression != 0) && validate_expr_tree(expression))
629 ast = parser_newastobject(expression, PyAST_EXPR);
630 }
631 else if (start_sym == file_input) {
632 /* This looks like an exec form so far. */
633 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000634
Guido van Rossum47478871996-08-21 14:32:37 +0000635 if ((suite_tree != 0) && validate_file_input(suite_tree))
636 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000637 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000638 else
Guido van Rossum47478871996-08-21 14:32:37 +0000639 /* This is a fragment, and is not yet supported. Maybe they
640 * will be if I find a use for them.
641 */
642 err_string("Fragmentary parse trees not supported.");
643
644 /* Make sure we throw an exception on all errors. We should never
645 * get this, but we'd do well to be sure something is done.
646 */
647 if ((ast == 0) && !PyErr_Occurred())
648 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000649
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000650 return (ast);
651
652} /* parser_tuple2ast() */
653
654
655/* int check_terminal_tuple()
656 *
Guido van Rossum47478871996-08-21 14:32:37 +0000657 * Check a tuple to determine that it is indeed a valid terminal
658 * node. The node is known to be required as a terminal, so we throw
659 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000660 *
Guido van Rossum47478871996-08-21 14:32:37 +0000661 * The format of an acceptable terminal tuple is "(is[i])": the fact
662 * that elem is a tuple and the integer is a valid terminal symbol
663 * has been established before this function is called. We must
664 * check the length of the tuple and the type of the second element
665 * and optional third element. We do *NOT* check the actual text of
666 * the string element, which we could do in many cases. This is done
667 * by the validate_*() functions which operate on the internal
668 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000669 */
670static int
Guido van Rossum47478871996-08-21 14:32:37 +0000671check_terminal_tuple(elem)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000672 PyObject *elem;
Guido van Rossum47478871996-08-21 14:32:37 +0000673{
674 int len = PyObject_Length(elem);
675 int res = 1;
676 char* str = "Illegal terminal symbol; bad node length.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000677
Guido van Rossum47478871996-08-21 14:32:37 +0000678 if ((len == 2) || (len == 3)) {
679 PyObject *temp = PySequence_GetItem(elem, 1);
680 res = PyString_Check(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000681 str = "Illegal terminal symbol; expected a string.";
Guido van Rossum47478871996-08-21 14:32:37 +0000682 if (res && (len == 3)) {
683 PyObject* third = PySequence_GetItem(elem, 2);
684 res = PyInt_Check(third);
685 str = "Invalid third element of terminal node.";
686 Py_XDECREF(third);
687 }
688 Py_XDECREF(temp);
689 }
690 else {
691 res = 0;
692 }
693 if (!res) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000694 elem = Py_BuildValue("(os)", elem, str);
695 PyErr_SetObject(parser_error, elem);
696 }
697 return (res);
698
699} /* check_terminal_tuple() */
700
701
702/* node* build_node_children()
703 *
704 * Iterate across the children of the current non-terminal node and build
705 * their structures. If successful, return the root of this portion of
706 * the tree, otherwise, 0. Any required exception will be specified already,
707 * and no memory will have been deallocated.
708 *
709 */
710static node*
711build_node_children(tuple, root, line_num)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000712 PyObject *tuple;
713 node *root;
714 int *line_num;
Guido van Rossum47478871996-08-21 14:32:37 +0000715{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000716 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000717 int i;
718
719 for (i = 1; i < len; ++i) {
720 /* elem must always be a tuple, however simple */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000721 PyObject* elem = PySequence_GetItem(tuple, i);
Guido van Rossum47478871996-08-21 14:32:37 +0000722 int ok = elem != NULL;
723 long type = 0;
724 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000725
Guido van Rossum47478871996-08-21 14:32:37 +0000726 if (ok)
727 ok = PySequence_Check(elem);
728 if (ok) {
729 PyObject *temp = PySequence_GetItem(elem, 0);
730 if (temp == NULL)
731 ok = 0;
732 else {
733 ok = PyInt_Check(temp);
734 if (ok)
735 type = PyInt_AsLong(temp);
736 Py_DECREF(temp);
737 }
738 }
739 if (!ok) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000740 PyErr_SetObject(parser_error,
741 Py_BuildValue("(os)", elem,
742 "Illegal node construct."));
Guido van Rossum47478871996-08-21 14:32:37 +0000743 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000744 return (0);
745 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000746 if (ISTERMINAL(type)) {
Guido van Rossum47478871996-08-21 14:32:37 +0000747 if (check_terminal_tuple(elem)) {
748 PyObject *temp = PySequence_GetItem(elem, 1);
749
750 strn = strdup(PyString_AsString(temp));
751 Py_XDECREF(temp);
752
753 if (PyObject_Length(elem) == 3) {
754 PyObject* temp = PySequence_GetItem(elem, 2);
755 *line_num = PyInt_AsLong(temp);
756 Py_DECREF(temp);
757 }
758 }
759 else {
760 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000761 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000762 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000763 }
764 else if (!ISNONTERMINAL(type)) {
765 /*
766 * It has to be one or the other; this is an error.
767 * Throw an exception.
768 */
769 PyErr_SetObject(parser_error,
770 Py_BuildValue("(os)", elem,
771 "Unknown node type."));
Guido van Rossum47478871996-08-21 14:32:37 +0000772 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000773 return (0);
774 }
775 PyNode_AddChild(root, type, strn, *line_num);
776
777 if (ISNONTERMINAL(type)) {
778 node* new_child = CHILD(root, i - 1);
779
Guido van Rossum47478871996-08-21 14:32:37 +0000780 if (new_child != build_node_children(elem, new_child, line_num)) {
781 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000782 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000783 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000784 }
Guido van Rossum47478871996-08-21 14:32:37 +0000785 else if (type == NEWLINE) { /* It's true: we increment the */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000786 ++(*line_num); /* line number *after* the newline! */
Guido van Rossum47478871996-08-21 14:32:37 +0000787 }
788 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000789 }
790 return (root);
791
792} /* build_node_children() */
793
794
795static node*
796build_node_tree(tuple)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000797 PyObject *tuple;
Guido van Rossum47478871996-08-21 14:32:37 +0000798{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000799 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000800 PyObject *temp = PySequence_GetItem(tuple, 0);
801 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000802
Guido van Rossum47478871996-08-21 14:32:37 +0000803 if (temp != NULL)
804 num = PyInt_AsLong(temp);
805 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000806 if (ISTERMINAL(num)) {
807 /*
808 * The tuple is simple, but it doesn't start with a start symbol.
809 * Throw an exception now and be done with it.
810 */
811 tuple = Py_BuildValue("(os)", tuple,
Guido van Rossum3d602e31996-07-21 02:33:56 +0000812 "Illegal ast tuple; cannot start with terminal symbol.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000813 PyErr_SetObject(parser_error, tuple);
814 }
815 else if (ISNONTERMINAL(num)) {
816 /*
817 * Not efficient, but that can be handled later.
818 */
819 int line_num = 0;
820
821 res = PyNode_New(num);
822 if (res != build_node_children(tuple, res, &line_num)) {
823 PyNode_Free(res);
824 res = 0;
825 }
826 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000827 else
828 /* The tuple is illegal -- if the number is neither TERMINAL nor
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000829 * NONTERMINAL, we can't use it.
830 */
831 PyErr_SetObject(parser_error,
832 Py_BuildValue("(os)", tuple,
833 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000834
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000835 return (res);
836
837} /* build_node_tree() */
838
839
Guido van Rossum360a9341996-08-21 19:04:10 +0000840#ifdef HAVE_OLD_CPP
Guido van Rossum2a288461996-08-21 21:55:43 +0000841#define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000842#else
Guido van Rossum2a288461996-08-21 21:55:43 +0000843#define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000844#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000845
846
847/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000848 * Validation routines used within the validation section:
849 */
Guido van Rossum2a288461996-08-21 21:55:43 +0000850staticforward int validate_terminal Py_PROTO((node *terminal,
851 int type, char *string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000852
853#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
854#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
855#define validate_colon(ch) validate_terminal(ch, COLON, ":")
856#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
857#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
858#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000859#define validate_indent(ch) validate_terminal(ch, INDENT, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000860#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000861#define validate_newline(ch) validate_terminal(ch, NEWLINE, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000862#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
863#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
864#define validate_star(ch) validate_terminal(ch, STAR, "*")
865#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000866#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
Guido van Rossum47478871996-08-21 14:32:37 +0000867#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000868#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000869
Guido van Rossum3d602e31996-07-21 02:33:56 +0000870VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000871VALIDATER(class); VALIDATER(node);
872VALIDATER(parameters); VALIDATER(suite);
873VALIDATER(testlist); VALIDATER(varargslist);
874VALIDATER(fpdef); VALIDATER(fplist);
875VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000876VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000877VALIDATER(print_stmt); VALIDATER(del_stmt);
878VALIDATER(return_stmt);
879VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000880VALIDATER(global_stmt);
Guido van Rossum925e5471997-04-02 05:32:13 +0000881VALIDATER(assert_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000882VALIDATER(exec_stmt); VALIDATER(compound_stmt);
883VALIDATER(while); VALIDATER(for);
884VALIDATER(try); VALIDATER(except_clause);
885VALIDATER(test); VALIDATER(and_test);
886VALIDATER(not_test); VALIDATER(comparison);
887VALIDATER(comp_op); VALIDATER(expr);
888VALIDATER(xor_expr); VALIDATER(and_expr);
889VALIDATER(shift_expr); VALIDATER(arith_expr);
890VALIDATER(term); VALIDATER(factor);
891VALIDATER(atom); VALIDATER(lambdef);
892VALIDATER(trailer); VALIDATER(subscript);
Guido van Rossum47478871996-08-21 14:32:37 +0000893VALIDATER(subscriptlist); VALIDATER(sliceop);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000894VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000895VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000896
897
898#define is_even(n) (((n) & 1) == 0)
899#define is_odd(n) (((n) & 1) == 1)
900
901
902static int
903validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000904 node *n;
905 int t;
Guido van Rossum47478871996-08-21 14:32:37 +0000906{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000907 int res = (TYPE(n) == t);
908
909 if (!res) {
910 char buffer[128];
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000911 sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000912 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000913 }
914 return (res);
915
916} /* validate_ntype() */
917
918
919static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000920validate_numnodes(n, num, name)
921 node *n;
922 int num;
923 const char *const name;
Guido van Rossum47478871996-08-21 14:32:37 +0000924{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000925 if (NCH(n) != num) {
926 char buff[60];
927 sprintf(buff, "Illegal number of children for %s node.", name);
928 err_string(buff);
929 }
930 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000931
Guido van Rossum3d602e31996-07-21 02:33:56 +0000932} /* validate_numnodes() */
933
934
935static int
936validate_terminal(terminal, type, string)
937 node *terminal;
938 int type;
939 char *string;
Guido van Rossum47478871996-08-21 14:32:37 +0000940{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000941 int res = (validate_ntype(terminal, type)
942 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
943
944 if (!res && !PyErr_Occurred()) {
945 char buffer[60];
946 sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
947 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000948 }
949 return (res);
950
951} /* validate_terminal() */
952
953
Guido van Rossum47478871996-08-21 14:32:37 +0000954/* X (',' X) [',']
955 */
956static int
957validate_repeating_list(tree, ntype, vfunc, name)
958 node *tree;
959 int ntype;
960 int (*vfunc)();
961 const char *const name;
962{
963 int nch = NCH(tree);
964 int res = (nch && validate_ntype(tree, ntype)
965 && vfunc(CHILD(tree, 0)));
966
967 if (!res && !PyErr_Occurred())
968 validate_numnodes(tree, 1, name);
969 else {
970 if (is_even(nch))
971 res = validate_comma(CHILD(tree, --nch));
972 if (res && nch > 1) {
973 int pos = 1;
974 for ( ; res && pos < nch; pos += 2)
975 res = (validate_comma(CHILD(tree, pos))
976 && vfunc(CHILD(tree, pos + 1)));
977 }
978 }
979 return (res);
980
981} /* validate_repeating_list() */
982
983
Guido van Rossum3d602e31996-07-21 02:33:56 +0000984/* VALIDATE(class)
985 *
986 * classdef:
987 * 'class' NAME ['(' testlist ')'] ':' suite
988 */
Guido van Rossum47478871996-08-21 14:32:37 +0000989static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000990validate_class(tree)
991 node *tree;
992{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000993 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000994 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000995
Guido van Rossum3d602e31996-07-21 02:33:56 +0000996 if (res) {
997 res = (validate_name(CHILD(tree, 0), "class")
998 && validate_ntype(CHILD(tree, 1), NAME)
999 && validate_colon(CHILD(tree, nch - 2))
1000 && validate_suite(CHILD(tree, nch - 1)));
1001 }
1002 else
1003 validate_numnodes(tree, 4, "class");
1004 if (res && (nch == 7)) {
1005 res = (validate_lparen(CHILD(tree, 2))
1006 && validate_testlist(CHILD(tree, 3))
1007 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001008 }
1009 return (res);
1010
1011} /* validate_class() */
1012
1013
Guido van Rossum3d602e31996-07-21 02:33:56 +00001014/* if_stmt:
1015 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1016 */
Guido van Rossum47478871996-08-21 14:32:37 +00001017static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001018validate_if(tree)
1019 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001020{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001021 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001022 int res = (validate_ntype(tree, if_stmt)
1023 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001024 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +00001025 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001026 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001027 && validate_suite(CHILD(tree, 3)));
1028
1029 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001030 /* ... 'else' ':' suite */
1031 res = (validate_name(CHILD(tree, nch - 3), "else")
1032 && validate_colon(CHILD(tree, nch - 2))
1033 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001034 nch -= 3;
1035 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001036 else if (!res && !PyErr_Occurred())
1037 validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001038 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001039 /* Will catch the case for nch < 4 */
1040 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001041 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001042 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001043 int j = 4;
1044 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001045 res = (validate_name(CHILD(tree, j), "elif")
1046 && validate_colon(CHILD(tree, j + 2))
1047 && validate_test(CHILD(tree, j + 1))
1048 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001049 j += 4;
1050 }
1051 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001052 return (res);
1053
1054} /* validate_if() */
1055
1056
Guido van Rossum3d602e31996-07-21 02:33:56 +00001057/* parameters:
1058 * '(' [varargslist] ')'
1059 *
1060 */
Guido van Rossum47478871996-08-21 14:32:37 +00001061static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001062validate_parameters(tree)
1063 node *tree;
1064{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001065 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001066 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001067
Guido van Rossum3d602e31996-07-21 02:33:56 +00001068 if (res) {
1069 res = (validate_lparen(CHILD(tree, 0))
1070 && validate_rparen(CHILD(tree, nch - 1)));
1071 if (res && (nch == 3))
1072 res = validate_varargslist(CHILD(tree, 1));
1073 }
1074 else
1075 validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001076
1077 return (res);
1078
1079} /* validate_parameters() */
1080
1081
Guido van Rossum3d602e31996-07-21 02:33:56 +00001082/* VALIDATE(suite)
1083 *
1084 * suite:
1085 * simple_stmt
1086 * | NEWLINE INDENT stmt+ DEDENT
1087 */
Guido van Rossum47478871996-08-21 14:32:37 +00001088static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001089validate_suite(tree)
1090 node *tree;
1091{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001092 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001093 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001094
Guido van Rossum3d602e31996-07-21 02:33:56 +00001095 if (res && (nch == 1))
1096 res = validate_simple_stmt(CHILD(tree, 0));
1097 else if (res) {
1098 /* NEWLINE INDENT stmt+ DEDENT */
1099 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001100 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001101 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001102 && validate_dedent(CHILD(tree, nch - 1)));
1103
Guido van Rossum3d602e31996-07-21 02:33:56 +00001104 if (res && (nch > 4)) {
1105 int i = 3;
1106 --nch; /* forget the DEDENT */
1107 for ( ; res && (i < nch); ++i)
1108 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001109 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001110 else if (nch < 4)
1111 validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001112 }
1113 return (res);
1114
1115} /* validate_suite() */
1116
1117
Guido van Rossum47478871996-08-21 14:32:37 +00001118static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001119validate_testlist(tree)
1120 node *tree;
1121{
Guido van Rossum47478871996-08-21 14:32:37 +00001122 return (validate_repeating_list(tree, testlist,
1123 validate_test, "testlist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001124
1125} /* validate_testlist() */
1126
1127
Guido van Rossum3d602e31996-07-21 02:33:56 +00001128/* VALIDATE(varargslist)
1129 *
1130 * varargslist:
1131 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1132 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1133 *
1134 * (fpdef ['=' test] ',')*
1135 * ('*' NAME [',' ('**'|'*' '*') NAME]
1136 * | ('**'|'*' '*') NAME)
1137 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1138 *
1139 */
Guido van Rossum47478871996-08-21 14:32:37 +00001140static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001141validate_varargslist(tree)
1142 node *tree;
1143{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001144 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001145 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001146
Guido van Rossum3d602e31996-07-21 02:33:56 +00001147 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1148 /* (fpdef ['=' test] ',')*
1149 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1150 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001151 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001152 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001153
Guido van Rossum3d602e31996-07-21 02:33:56 +00001154 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1155 res = validate_fpdef(CHILD(tree, pos));
1156 if (res) {
1157 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1158 res = validate_test(CHILD(tree, pos + 2));
1159 pos += 2;
1160 }
1161 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001162 pos += 2;
1163 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001164 }
1165 if (res) {
1166 remaining = nch - pos;
1167 res = ((remaining == 2) || (remaining == 3)
1168 || (remaining == 5) || (remaining == 6));
1169 if (!res)
1170 validate_numnodes(tree, 2, "varargslist");
1171 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1172 return ((remaining == 2)
1173 && validate_ntype(CHILD(tree, pos+1), NAME));
1174 else {
1175 res = validate_star(CHILD(tree, pos++));
1176 --remaining;
1177 }
1178 }
1179 if (res) {
1180 if (remaining == 2) {
1181 res = (validate_star(CHILD(tree, pos))
1182 && validate_ntype(CHILD(tree, pos + 1), NAME));
1183 }
1184 else {
1185 res = validate_ntype(CHILD(tree, pos++), NAME);
1186 if (res && (remaining >= 4)) {
1187 res = validate_comma(CHILD(tree, pos));
1188 if (--remaining == 3)
Fred Drakee1607a81996-09-11 21:58:26 +00001189 res = (validate_star(CHILD(tree, pos + 1))
1190 && validate_star(CHILD(tree, pos + 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001191 else
1192 validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1193 }
1194 }
1195 }
1196 if (!res && !PyErr_Occurred())
1197 err_string("Incorrect validation of variable arguments list.");
1198 }
1199 else if (res) {
1200 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1201 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1202 --nch;
1203
1204 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1205 res = (is_odd(nch)
1206 && validate_fpdef(CHILD(tree, 0)));
1207
1208 if (res && (nch > 1)) {
1209 int pos = 1;
1210 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1211 res = validate_test(CHILD(tree, 2));
1212 pos += 2;
1213 }
1214 /* ... (',' fpdef ['=' test])* */
1215 for ( ; res && (pos < nch); pos += 2) {
1216 /* ',' fpdef */
1217 res = (validate_comma(CHILD(tree, pos))
1218 && validate_fpdef(CHILD(tree, pos + 1)));
1219 if (res
1220 && ((nch - pos) > 2)
1221 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1222 /* ['=' test] */
1223 res = validate_test(CHILD(tree, pos + 3));
1224 pos += 2;
1225 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001226 }
1227 }
1228 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001229 else
1230 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001231
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001232 return (res);
1233
1234} /* validate_varargslist() */
1235
1236
Guido van Rossum3d602e31996-07-21 02:33:56 +00001237/* VALIDATE(fpdef)
1238 *
1239 * fpdef:
1240 * NAME
1241 * | '(' fplist ')'
1242 */
Guido van Rossum47478871996-08-21 14:32:37 +00001243static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001244validate_fpdef(tree)
1245 node *tree;
1246{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001247 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001248 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001249
Guido van Rossum3d602e31996-07-21 02:33:56 +00001250 if (res) {
1251 if (nch == 1)
1252 res = validate_ntype(CHILD(tree, 0), NAME);
1253 else if (nch == 3)
1254 res = (validate_lparen(CHILD(tree, 0))
1255 && validate_fplist(CHILD(tree, 1))
1256 && validate_rparen(CHILD(tree, 2)));
1257 else
1258 validate_numnodes(tree, 1, "fpdef");
1259 }
1260 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001261
1262} /* validate_fpdef() */
1263
1264
Guido van Rossum47478871996-08-21 14:32:37 +00001265static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001266validate_fplist(tree)
1267 node *tree;
1268{
Guido van Rossum47478871996-08-21 14:32:37 +00001269 return (validate_repeating_list(tree, fplist,
1270 validate_fpdef, "fplist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001271
1272} /* validate_fplist() */
1273
1274
Guido van Rossum3d602e31996-07-21 02:33:56 +00001275/* simple_stmt | compound_stmt
1276 *
1277 */
Guido van Rossum47478871996-08-21 14:32:37 +00001278static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001279validate_stmt(tree)
1280 node *tree;
1281{
1282 int res = (validate_ntype(tree, stmt)
1283 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001284
Guido van Rossum3d602e31996-07-21 02:33:56 +00001285 if (res) {
1286 tree = CHILD(tree, 0);
1287
1288 if (TYPE(tree) == simple_stmt)
1289 res = validate_simple_stmt(tree);
1290 else
1291 res = validate_compound_stmt(tree);
1292 }
1293 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001294
1295} /* validate_stmt() */
1296
1297
Guido van Rossum3d602e31996-07-21 02:33:56 +00001298/* small_stmt (';' small_stmt)* [';'] NEWLINE
1299 *
1300 */
Guido van Rossum47478871996-08-21 14:32:37 +00001301static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001302validate_simple_stmt(tree)
1303 node *tree;
1304{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001305 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001306 int res = (validate_ntype(tree, simple_stmt)
1307 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001308 && validate_small_stmt(CHILD(tree, 0))
1309 && validate_newline(CHILD(tree, nch - 1)));
1310
Guido van Rossum3d602e31996-07-21 02:33:56 +00001311 if (nch < 2)
1312 res = validate_numnodes(tree, 2, "simple_stmt");
1313 --nch; /* forget the NEWLINE */
1314 if (res && is_even(nch))
1315 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001316 if (res && (nch > 2)) {
1317 int i;
1318
Guido van Rossum3d602e31996-07-21 02:33:56 +00001319 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001320 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001321 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001322 }
1323 return (res);
1324
1325} /* validate_simple_stmt() */
1326
1327
Guido van Rossum47478871996-08-21 14:32:37 +00001328static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001329validate_small_stmt(tree)
1330 node *tree;
1331{
1332 int nch = NCH(tree);
1333 int res = (validate_numnodes(tree, 1, "small_stmt")
1334 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1335 || (TYPE(CHILD(tree, 0)) == print_stmt)
1336 || (TYPE(CHILD(tree, 0)) == del_stmt)
1337 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1338 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1339 || (TYPE(CHILD(tree, 0)) == import_stmt)
1340 || (TYPE(CHILD(tree, 0)) == global_stmt)
Guido van Rossum925e5471997-04-02 05:32:13 +00001341 || (TYPE(CHILD(tree, 0)) == assert_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001342 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1343
1344 if (res)
1345 res = validate_node(CHILD(tree, 0));
1346 else if (nch == 1) {
1347 char buffer[60];
1348 sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1349 TYPE(CHILD(tree, 0)));
1350 err_string(buffer);
1351 }
1352 return (res);
1353
1354} /* validate_small_stmt */
1355
1356
1357/* compound_stmt:
1358 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1359 */
Guido van Rossum47478871996-08-21 14:32:37 +00001360static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001361validate_compound_stmt(tree)
1362 node *tree;
1363{
1364 int res = (validate_ntype(tree, compound_stmt)
1365 && validate_numnodes(tree, 1, "compound_stmt"));
1366
1367 if (!res)
1368 return (0);
1369
1370 tree = CHILD(tree, 0);
1371 res = ((TYPE(tree) == if_stmt)
1372 || (TYPE(tree) == while_stmt)
1373 || (TYPE(tree) == for_stmt)
1374 || (TYPE(tree) == try_stmt)
1375 || (TYPE(tree) == funcdef)
1376 || (TYPE(tree) == classdef));
1377 if (res)
1378 res = validate_node(tree);
1379 else {
1380 char buffer[60];
1381 sprintf(buffer, "Illegal compound statement type: %d.", TYPE(tree));
1382 err_string(buffer);
1383 }
1384 return (res);
1385
1386} /* validate_compound_stmt() */
1387
1388
Guido van Rossum47478871996-08-21 14:32:37 +00001389static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001390validate_expr_stmt(tree)
1391 node *tree;
1392{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001393 int j;
1394 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001395 int res = (validate_ntype(tree, expr_stmt)
1396 && is_odd(nch)
1397 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001398
Guido van Rossum3d602e31996-07-21 02:33:56 +00001399 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001400 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001401 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001402
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001403 return (res);
1404
1405} /* validate_expr_stmt() */
1406
1407
Guido van Rossum3d602e31996-07-21 02:33:56 +00001408/* print_stmt:
1409 *
1410 * 'print' (test ',')* [test]
1411 *
1412 */
Guido van Rossum47478871996-08-21 14:32:37 +00001413static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001414validate_print_stmt(tree)
1415 node *tree;
1416{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001417 int j;
1418 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001419 int res = (validate_ntype(tree, print_stmt)
1420 && (nch != 0)
1421 && validate_name(CHILD(tree, 0), "print"));
1422
1423 if (res && is_even(nch)) {
1424 res = validate_test(CHILD(tree, nch - 1));
1425 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001426 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001427 else if (!res && !PyErr_Occurred())
1428 validate_numnodes(tree, 1, "print_stmt");
1429 for (j = 1; res && (j < nch); j += 2)
1430 res = (validate_test(CHILD(tree, j))
1431 && validate_ntype(CHILD(tree, j + 1), COMMA));
1432
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001433 return (res);
1434
1435} /* validate_print_stmt() */
1436
1437
Guido van Rossum47478871996-08-21 14:32:37 +00001438static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001439validate_del_stmt(tree)
1440 node *tree;
1441{
1442 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001443 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001444 && validate_exprlist(CHILD(tree, 1)));
1445
1446} /* validate_del_stmt() */
1447
1448
Guido van Rossum47478871996-08-21 14:32:37 +00001449static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001450validate_return_stmt(tree)
1451 node *tree;
1452{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001453 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001454 int res = (validate_ntype(tree, return_stmt)
1455 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001456 && validate_name(CHILD(tree, 0), "return"));
1457
Guido van Rossum3d602e31996-07-21 02:33:56 +00001458 if (res && (nch == 2))
1459 res = validate_testlist(CHILD(tree, 1));
1460
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001461 return (res);
1462
1463} /* validate_return_stmt() */
1464
1465
Guido van Rossum47478871996-08-21 14:32:37 +00001466static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001467validate_raise_stmt(tree)
1468 node *tree;
1469{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001470 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001471 int res = (validate_ntype(tree, raise_stmt)
1472 && ((nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001473
Guido van Rossum3d602e31996-07-21 02:33:56 +00001474 if (res) {
1475 res = (validate_name(CHILD(tree, 0), "raise")
1476 && validate_test(CHILD(tree, 1)));
1477 if (res && nch > 2) {
1478 res = (validate_comma(CHILD(tree, 2))
1479 && validate_test(CHILD(tree, 3)));
1480 if (res && (nch > 4))
1481 res = (validate_comma(CHILD(tree, 4))
1482 && validate_test(CHILD(tree, 5)));
1483 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001484 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001485 else
1486 validate_numnodes(tree, 2, "raise");
1487 if (res && (nch == 4))
1488 res = (validate_comma(CHILD(tree, 2))
1489 && validate_test(CHILD(tree, 3)));
1490
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001491 return (res);
1492
1493} /* validate_raise_stmt() */
1494
1495
Guido van Rossum3d602e31996-07-21 02:33:56 +00001496/* import_stmt:
1497 *
1498 * 'import' dotted_name (',' dotted_name)*
1499 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1500 */
Guido van Rossum47478871996-08-21 14:32:37 +00001501static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001502validate_import_stmt(tree)
1503 node *tree;
1504{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001505 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001506 int res = (validate_ntype(tree, import_stmt)
1507 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001508 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001509 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001510
1511 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001512 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001513
Guido van Rossum3d602e31996-07-21 02:33:56 +00001514 for (j = 2; res && (j < nch); j += 2)
1515 res = (validate_comma(CHILD(tree, j))
1516 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001517 }
1518 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001519 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001520 && validate_name(CHILD(tree, 2), "import"));
1521 if (nch == 4) {
1522 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001523 || (TYPE(CHILD(tree, 3)) == STAR));
1524 if (!res)
1525 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001526 }
1527 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001528 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001529 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001530 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001531 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001532 res = (validate_comma(CHILD(tree, j))
1533 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001534 }
1535 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001536 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001537 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001538
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001539 return (res);
1540
1541} /* validate_import_stmt() */
1542
1543
Guido van Rossum47478871996-08-21 14:32:37 +00001544static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001545validate_global_stmt(tree)
1546 node *tree;
1547{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001548 int j;
1549 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001550 int res = (validate_ntype(tree, global_stmt)
1551 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001552
Guido van Rossum3d602e31996-07-21 02:33:56 +00001553 if (res)
1554 res = (validate_name(CHILD(tree, 0), "global")
1555 && validate_ntype(CHILD(tree, 1), NAME));
1556 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001557 res = (validate_comma(CHILD(tree, j))
1558 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001559
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001560 return (res);
1561
1562} /* validate_global_stmt() */
1563
1564
Guido van Rossum3d602e31996-07-21 02:33:56 +00001565/* exec_stmt:
1566 *
1567 * 'exec' expr ['in' test [',' test]]
1568 */
Guido van Rossum47478871996-08-21 14:32:37 +00001569static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001570validate_exec_stmt(tree)
1571 node *tree;
1572{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001573 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001574 int res = (validate_ntype(tree, exec_stmt)
1575 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001576 && validate_name(CHILD(tree, 0), "exec")
1577 && validate_expr(CHILD(tree, 1)));
1578
Guido van Rossum3d602e31996-07-21 02:33:56 +00001579 if (!res && !PyErr_Occurred())
1580 err_string("Illegal exec statement.");
1581 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001582 res = (validate_name(CHILD(tree, 2), "in")
1583 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001584 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001585 res = (validate_comma(CHILD(tree, 4))
1586 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001587
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001588 return (res);
1589
1590} /* validate_exec_stmt() */
1591
1592
Guido van Rossum925e5471997-04-02 05:32:13 +00001593/* assert_stmt:
1594 *
1595 * 'assert' test [',' test]
1596 */
1597static int
1598validate_assert_stmt(tree)
1599 node *tree;
1600{
1601 int nch = NCH(tree);
1602 int res = (validate_ntype(tree, assert_stmt)
1603 && ((nch == 2) || (nch == 4))
1604 && (validate_name(CHILD(tree, 0), "__assert__") ||
1605 validate_name(CHILD(tree, 0), "assert"))
1606 && validate_test(CHILD(tree, 1)));
1607
1608 if (!res && !PyErr_Occurred())
1609 err_string("Illegal assert statement.");
1610 if (res && (nch > 2))
1611 res = (validate_comma(CHILD(tree, 2))
1612 && validate_test(CHILD(tree, 3)));
1613
1614 return (res);
1615
1616} /* validate_assert_stmt() */
1617
1618
Guido van Rossum47478871996-08-21 14:32:37 +00001619static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001620validate_while(tree)
1621 node *tree;
1622{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001623 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001624 int res = (validate_ntype(tree, while_stmt)
1625 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001626 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001627 && validate_test(CHILD(tree, 1))
1628 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001629 && validate_suite(CHILD(tree, 3)));
1630
Guido van Rossum3d602e31996-07-21 02:33:56 +00001631 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001632 res = (validate_name(CHILD(tree, 4), "else")
1633 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001634 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001635
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001636 return (res);
1637
1638} /* validate_while() */
1639
1640
Guido van Rossum47478871996-08-21 14:32:37 +00001641static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001642validate_for(tree)
1643 node *tree;
1644{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001645 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001646 int res = (validate_ntype(tree, for_stmt)
1647 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001648 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001649 && validate_exprlist(CHILD(tree, 1))
1650 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001651 && validate_testlist(CHILD(tree, 3))
1652 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001653 && validate_suite(CHILD(tree, 5)));
1654
Guido van Rossum3d602e31996-07-21 02:33:56 +00001655 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001656 res = (validate_name(CHILD(tree, 6), "else")
1657 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001658 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001659
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001660 return (res);
1661
1662} /* validate_for() */
1663
1664
Guido van Rossum3d602e31996-07-21 02:33:56 +00001665/* try_stmt:
1666 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1667 * | 'try' ':' suite 'finally' ':' suite
1668 *
1669 */
Guido van Rossum47478871996-08-21 14:32:37 +00001670static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001671validate_try(tree)
1672 node *tree;
1673{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001674 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001675 int pos = 3;
1676 int res = (validate_ntype(tree, try_stmt)
1677 && (nch >= 6) && ((nch % 3) == 0));
1678
1679 if (res)
1680 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001681 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001682 && validate_suite(CHILD(tree, 2))
1683 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001684 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001685 else {
1686 const char* name = "execpt";
1687 char buffer[60];
1688 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1689 name = STR(CHILD(tree, nch - 3));
1690 sprintf(buffer, "Illegal number of children for try/%s node.", name);
1691 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001692 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001693 /* Skip past except_clause sections: */
1694 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1695 res = (validate_except_clause(CHILD(tree, pos))
1696 && validate_colon(CHILD(tree, pos + 1))
1697 && validate_suite(CHILD(tree, pos + 2)));
1698 pos += 3;
1699 }
1700 if (res && (pos < nch)) {
1701 res = validate_ntype(CHILD(tree, pos), NAME);
1702 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1703 res = (validate_numnodes(tree, 6, "try/finally")
1704 && validate_colon(CHILD(tree, 4))
1705 && validate_suite(CHILD(tree, 5)));
1706 else if (res)
1707 if (nch == (pos + 3)) {
1708 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1709 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1710 if (!res)
1711 err_string("Illegal trailing triple in try statement.");
1712 }
1713 else if (nch == (pos + 6))
1714 res = (validate_name(CHILD(tree, pos), "except")
1715 && validate_colon(CHILD(tree, pos + 1))
1716 && validate_suite(CHILD(tree, pos + 2))
1717 && validate_name(CHILD(tree, pos + 3), "else"));
1718 else
1719 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001720 }
1721 return (res);
1722
1723} /* validate_try() */
1724
1725
Guido van Rossum47478871996-08-21 14:32:37 +00001726static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001727validate_except_clause(tree)
1728 node *tree;
1729{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001730 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001731 int res = (validate_ntype(tree, except_clause)
1732 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001733 && validate_name(CHILD(tree, 0), "except"));
1734
Guido van Rossum3d602e31996-07-21 02:33:56 +00001735 if (res && (nch > 1))
1736 res = validate_test(CHILD(tree, 1));
1737 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001738 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001739 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001740
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001741 return (res);
1742
1743} /* validate_except_clause() */
1744
1745
Guido van Rossum47478871996-08-21 14:32:37 +00001746static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001747validate_test(tree)
1748 node *tree;
1749{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001750 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001751 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001752
Guido van Rossum3d602e31996-07-21 02:33:56 +00001753 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001754 res = ((nch == 1)
1755 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001756 else if (res) {
1757 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001758 res = validate_and_test(CHILD(tree, 0));
1759 for (pos = 1; res && (pos < nch); pos += 2)
1760 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001761 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001762 }
1763 return (res);
1764
1765} /* validate_test() */
1766
1767
Guido van Rossum47478871996-08-21 14:32:37 +00001768static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001769validate_and_test(tree)
1770 node *tree;
1771{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001772 int pos;
1773 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001774 int res = (validate_ntype(tree, and_test)
1775 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001776 && validate_not_test(CHILD(tree, 0)));
1777
Guido van Rossum3d602e31996-07-21 02:33:56 +00001778 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001779 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001780 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001781
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001782 return (res);
1783
1784} /* validate_and_test() */
1785
1786
Guido van Rossum47478871996-08-21 14:32:37 +00001787static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001788validate_not_test(tree)
1789 node *tree;
1790{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001791 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001792 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001793
Guido van Rossum3d602e31996-07-21 02:33:56 +00001794 if (res) {
1795 if (nch == 2)
1796 res = (validate_name(CHILD(tree, 0), "not")
1797 && validate_not_test(CHILD(tree, 1)));
1798 else if (nch == 1)
1799 res = validate_comparison(CHILD(tree, 0));
1800 }
1801 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001802
1803} /* validate_not_test() */
1804
1805
Guido van Rossum47478871996-08-21 14:32:37 +00001806static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001807validate_comparison(tree)
1808 node *tree;
1809{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001810 int pos;
1811 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001812 int res = (validate_ntype(tree, comparison)
1813 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001814 && validate_expr(CHILD(tree, 0)));
1815
Guido van Rossum3d602e31996-07-21 02:33:56 +00001816 for (pos = 1; res && (pos < nch); pos += 2)
1817 res = (validate_comp_op(CHILD(tree, pos))
1818 && validate_expr(CHILD(tree, pos + 1)));
1819
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001820 return (res);
1821
1822} /* validate_comparison() */
1823
1824
Guido van Rossum47478871996-08-21 14:32:37 +00001825static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001826validate_comp_op(tree)
1827 node *tree;
1828{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001829 int res = 0;
1830 int nch = NCH(tree);
1831
Guido van Rossum3d602e31996-07-21 02:33:56 +00001832 if (!validate_ntype(tree, comp_op))
1833 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001834 if (nch == 1) {
1835 /*
1836 * Only child will be a terminal with a well-defined symbolic name
1837 * or a NAME with a string of either 'is' or 'in'
1838 */
1839 tree = CHILD(tree, 0);
1840 switch (TYPE(tree)) {
1841 case LESS:
1842 case GREATER:
1843 case EQEQUAL:
1844 case EQUAL:
1845 case LESSEQUAL:
1846 case GREATEREQUAL:
1847 case NOTEQUAL:
1848 res = 1;
1849 break;
1850 case NAME:
1851 res = ((strcmp(STR(tree), "in") == 0)
1852 || (strcmp(STR(tree), "is") == 0));
1853 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001854 char buff[128];
1855 sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1856 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001857 }
1858 break;
1859 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001860 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001861 break;
1862 }
1863 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001864 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001865 res = (validate_ntype(CHILD(tree, 0), NAME)
1866 && validate_ntype(CHILD(tree, 1), NAME)
1867 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1868 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1869 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1870 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001871 if (!res && !PyErr_Occurred())
1872 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001873 }
1874 return (res);
1875
1876} /* validate_comp_op() */
1877
1878
Guido van Rossum47478871996-08-21 14:32:37 +00001879static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001880validate_expr(tree)
1881 node *tree;
1882{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001883 int j;
1884 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001885 int res = (validate_ntype(tree, expr)
1886 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001887 && validate_xor_expr(CHILD(tree, 0)));
1888
Guido van Rossum3d602e31996-07-21 02:33:56 +00001889 for (j = 2; res && (j < nch); j += 2)
1890 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001891 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001892
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001893 return (res);
1894
1895} /* validate_expr() */
1896
1897
Guido van Rossum47478871996-08-21 14:32:37 +00001898static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001899validate_xor_expr(tree)
1900 node *tree;
1901{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001902 int j;
1903 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001904 int res = (validate_ntype(tree, xor_expr)
1905 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001906 && validate_and_expr(CHILD(tree, 0)));
1907
Guido van Rossum3d602e31996-07-21 02:33:56 +00001908 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001909 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001910 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001911
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001912 return (res);
1913
1914} /* validate_xor_expr() */
1915
1916
Guido van Rossum47478871996-08-21 14:32:37 +00001917static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001918validate_and_expr(tree)
1919 node *tree;
1920{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001921 int pos;
1922 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001923 int res = (validate_ntype(tree, and_expr)
1924 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001925 && validate_shift_expr(CHILD(tree, 0)));
1926
Guido van Rossum3d602e31996-07-21 02:33:56 +00001927 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001928 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001929 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001930
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001931 return (res);
1932
1933} /* validate_and_expr() */
1934
1935
1936static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001937validate_chain_two_ops(tree, termvalid, op1, op2)
1938 node *tree;
1939 int (*termvalid)();
1940 int op1;
1941 int op2;
1942 {
1943 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001944 int nch = NCH(tree);
1945 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001946 && (*termvalid)(CHILD(tree, 0)));
1947
Guido van Rossum3d602e31996-07-21 02:33:56 +00001948 for ( ; res && (pos < nch); pos += 2) {
1949 if (TYPE(CHILD(tree, pos)) != op1)
1950 res = validate_ntype(CHILD(tree, pos), op2);
1951 if (res)
1952 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001953 }
1954 return (res);
1955
1956} /* validate_chain_two_ops() */
1957
1958
Guido van Rossum47478871996-08-21 14:32:37 +00001959static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001960validate_shift_expr(tree)
1961 node *tree;
1962{
1963 return (validate_ntype(tree, shift_expr)
1964 && validate_chain_two_ops(tree, validate_arith_expr,
1965 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001966
1967} /* validate_shift_expr() */
1968
1969
Guido van Rossum47478871996-08-21 14:32:37 +00001970static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001971validate_arith_expr(tree)
1972 node *tree;
1973{
1974 return (validate_ntype(tree, arith_expr)
1975 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001976
1977} /* validate_arith_expr() */
1978
1979
Guido van Rossum47478871996-08-21 14:32:37 +00001980static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001981validate_term(tree)
1982 node *tree;
1983{
1984 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001985 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001986 int res = (validate_ntype(tree, term)
1987 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001988 && validate_factor(CHILD(tree, 0)));
1989
Guido van Rossum3d602e31996-07-21 02:33:56 +00001990 for ( ; res && (pos < nch); pos += 2)
1991 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001992 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001993 || (TYPE(CHILD(tree, pos)) == PERCENT))
1994 && validate_factor(CHILD(tree, pos + 1)));
1995
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001996 return (res);
1997
1998} /* validate_term() */
1999
2000
Guido van Rossum3d602e31996-07-21 02:33:56 +00002001/* factor:
2002 *
2003 * factor: ('+'|'-'|'~') factor | power
2004 */
Guido van Rossum47478871996-08-21 14:32:37 +00002005static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002006validate_factor(tree)
2007 node *tree;
2008{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002009 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002010 int res = (validate_ntype(tree, factor)
2011 && (((nch == 2)
2012 && ((TYPE(CHILD(tree, 0)) == PLUS)
2013 || (TYPE(CHILD(tree, 0)) == MINUS)
2014 || (TYPE(CHILD(tree, 0)) == TILDE))
2015 && validate_factor(CHILD(tree, 1)))
2016 || ((nch == 1)
2017 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002018 return (res);
2019
2020} /* validate_factor() */
2021
2022
Guido van Rossum3d602e31996-07-21 02:33:56 +00002023/* power:
2024 *
2025 * power: atom trailer* ('**' factor)*
2026 */
Guido van Rossum47478871996-08-21 14:32:37 +00002027static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002028validate_power(tree)
2029 node *tree;
2030{
2031 int pos = 1;
2032 int nch = NCH(tree);
2033 int res = (validate_ntype(tree, power) && (nch >= 1)
2034 && validate_atom(CHILD(tree, 0)));
2035
2036 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2037 res = validate_trailer(CHILD(tree, pos++));
2038 if (res && (pos < nch)) {
2039 if (!is_even(nch - pos)) {
2040 err_string("Illegal number of nodes for 'power'.");
2041 return (0);
2042 }
2043 for ( ; res && (pos < (nch - 1)); pos += 2)
2044 res = (validate_doublestar(CHILD(tree, pos))
2045 && validate_factor(CHILD(tree, pos + 1)));
2046 }
2047 return (res);
2048
2049} /* validate_power() */
2050
2051
Guido van Rossum47478871996-08-21 14:32:37 +00002052static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002053validate_atom(tree)
2054 node *tree;
2055{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002056 int pos;
2057 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002058 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002059
2060 if (res) {
2061 switch (TYPE(CHILD(tree, 0))) {
2062 case LPAR:
2063 res = ((nch <= 3)
2064 && (validate_rparen(CHILD(tree, nch - 1))));
2065
Guido van Rossum3d602e31996-07-21 02:33:56 +00002066 if (res && (nch == 3))
2067 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002068 break;
2069 case LSQB:
2070 res = ((nch <= 3)
2071 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2072
Guido van Rossum3d602e31996-07-21 02:33:56 +00002073 if (res && (nch == 3))
2074 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002075 break;
2076 case LBRACE:
2077 res = ((nch <= 3)
2078 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2079
Guido van Rossum3d602e31996-07-21 02:33:56 +00002080 if (res && (nch == 3))
2081 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002082 break;
2083 case BACKQUOTE:
2084 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002085 && validate_testlist(CHILD(tree, 1))
2086 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2087 break;
2088 case NAME:
2089 case NUMBER:
2090 res = (nch == 1);
2091 break;
2092 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002093 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002094 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002095 break;
2096 default:
2097 res = 0;
2098 break;
2099 }
2100 }
2101 return (res);
2102
2103} /* validate_atom() */
2104
2105
Guido van Rossum3d602e31996-07-21 02:33:56 +00002106/* funcdef:
2107 * 'def' NAME parameters ':' suite
2108 *
2109 */
Guido van Rossum47478871996-08-21 14:32:37 +00002110static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002111validate_funcdef(tree)
2112 node *tree;
2113{
2114 return (validate_ntype(tree, funcdef)
2115 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002116 && validate_name(CHILD(tree, 0), "def")
2117 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002118 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002119 && validate_parameters(CHILD(tree, 2))
2120 && validate_suite(CHILD(tree, 4)));
2121
2122} /* validate_funcdef() */
2123
2124
Guido van Rossum47478871996-08-21 14:32:37 +00002125static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002126validate_lambdef(tree)
2127 node *tree;
2128{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002129 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002130 int res = (validate_ntype(tree, lambdef)
2131 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002132 && validate_name(CHILD(tree, 0), "lambda")
2133 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002134 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002135
Guido van Rossum3d602e31996-07-21 02:33:56 +00002136 if (res && (nch == 4))
2137 res = validate_varargslist(CHILD(tree, 1));
2138 else if (!res && !PyErr_Occurred())
2139 validate_numnodes(tree, 3, "lambdef");
2140
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002141 return (res);
2142
2143} /* validate_lambdef() */
2144
2145
Guido van Rossum3d602e31996-07-21 02:33:56 +00002146/* arglist:
2147 *
2148 * argument (',' argument)* [',']
2149 */
Guido van Rossum47478871996-08-21 14:32:37 +00002150static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002151validate_arglist(tree)
2152 node *tree;
2153{
Guido van Rossum47478871996-08-21 14:32:37 +00002154 return (validate_repeating_list(tree, arglist,
2155 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002156
2157} /* validate_arglist() */
2158
2159
2160
2161/* argument:
2162 *
2163 * [test '='] test
2164 */
Guido van Rossum47478871996-08-21 14:32:37 +00002165static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002166validate_argument(tree)
2167 node *tree;
2168{
2169 int nch = NCH(tree);
2170 int res = (validate_ntype(tree, argument)
2171 && ((nch == 1) || (nch == 3))
2172 && validate_test(CHILD(tree, 0)));
2173
2174 if (res && (nch == 3))
2175 res = (validate_equal(CHILD(tree, 1))
2176 && validate_test(CHILD(tree, 2)));
2177
2178 return (res);
2179
2180} /* validate_argument() */
2181
2182
2183
2184/* trailer:
2185 *
Guido van Rossum47478871996-08-21 14:32:37 +00002186 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002187 */
Guido van Rossum47478871996-08-21 14:32:37 +00002188static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002189validate_trailer(tree)
2190 node *tree;
2191{
2192 int nch = NCH(tree);
2193 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002194
2195 if (res) {
2196 switch (TYPE(CHILD(tree, 0))) {
2197 case LPAR:
2198 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002199 if (res && (nch == 3))
2200 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002201 break;
2202 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002203 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002204 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002205 && validate_ntype(CHILD(tree, 2), RSQB));
2206 break;
2207 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002208 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002209 && validate_ntype(CHILD(tree, 1), NAME));
2210 break;
2211 default:
2212 res = 0;
2213 break;
2214 }
2215 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002216 else
2217 validate_numnodes(tree, 2, "trailer");
2218
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002219 return (res);
2220
2221} /* validate_trailer() */
2222
2223
Guido van Rossum47478871996-08-21 14:32:37 +00002224/* subscriptlist:
2225 *
2226 * subscript (',' subscript)* [',']
2227 */
2228static int
2229validate_subscriptlist(tree)
2230 node *tree;
2231{
2232 return (validate_repeating_list(tree, subscriptlist,
2233 validate_subscript, "subscriptlist"));
2234
2235} /* validate_subscriptlist() */
2236
2237
Guido van Rossum3d602e31996-07-21 02:33:56 +00002238/* subscript:
2239 *
Guido van Rossum47478871996-08-21 14:32:37 +00002240 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002241 */
Guido van Rossum47478871996-08-21 14:32:37 +00002242static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002243validate_subscript(tree)
2244 node *tree;
2245{
Guido van Rossum47478871996-08-21 14:32:37 +00002246 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002247 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002248 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002249
Guido van Rossum47478871996-08-21 14:32:37 +00002250 if (!res) {
2251 if (!PyErr_Occurred())
2252 err_string("invalid number of arguments for subscript node");
2253 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002254 }
Guido van Rossum47478871996-08-21 14:32:37 +00002255 if (TYPE(CHILD(tree, 0)) == DOT)
2256 /* take care of ('.' '.' '.') possibility */
2257 return (validate_numnodes(tree, 3, "subscript")
2258 && validate_dot(CHILD(tree, 0))
2259 && validate_dot(CHILD(tree, 1))
2260 && validate_dot(CHILD(tree, 2)));
2261 if (nch == 1) {
2262 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002263 res = validate_test(CHILD(tree, 0));
2264 else
Guido van Rossum47478871996-08-21 14:32:37 +00002265 res = validate_colon(CHILD(tree, 0));
2266 return (res);
2267 }
2268 /* Must be [test] ':' [test] [sliceop],
2269 * but at least one of the optional components will
2270 * be present, but we don't know which yet.
2271 */
2272 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2273 res = validate_test(CHILD(tree, 0));
2274 offset = 1;
2275 }
2276 if (res)
2277 res = validate_colon(CHILD(tree, offset));
2278 if (res) {
2279 int rem = nch - ++offset;
2280 if (rem) {
2281 if (TYPE(CHILD(tree, offset)) == test) {
2282 res = validate_test(CHILD(tree, offset));
2283 ++offset;
2284 --rem;
2285 }
2286 if (res && rem)
2287 res = validate_sliceop(CHILD(tree, offset));
2288 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002289 }
2290 return (res);
2291
2292} /* validate_subscript() */
2293
2294
Guido van Rossum47478871996-08-21 14:32:37 +00002295static int
2296validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002297 node *tree;
2298{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002299 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002300 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2301 && validate_ntype(tree, sliceop);
2302 if (!res && !PyErr_Occurred()) {
2303 validate_numnodes(tree, 1, "sliceop");
2304 res = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002305 }
Guido van Rossum47478871996-08-21 14:32:37 +00002306 if (res)
2307 res = validate_colon(CHILD(tree, 0));
2308 if (res && (nch == 2))
2309 res = validate_test(CHILD(tree, 1));
2310
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002311 return (res);
2312
Guido van Rossum47478871996-08-21 14:32:37 +00002313} /* validate_sliceop() */
2314
2315
2316static int
2317validate_exprlist(tree)
2318 node *tree;
2319{
2320 return (validate_repeating_list(tree, exprlist,
2321 validate_expr, "exprlist"));
2322
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002323} /* validate_exprlist() */
2324
2325
Guido van Rossum47478871996-08-21 14:32:37 +00002326static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002327validate_dictmaker(tree)
2328 node *tree;
2329{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002330 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002331 int res = (validate_ntype(tree, dictmaker)
2332 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002333 && validate_test(CHILD(tree, 0))
2334 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002335 && validate_test(CHILD(tree, 2)));
2336
Guido van Rossum3d602e31996-07-21 02:33:56 +00002337 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002338 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002339 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002340 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002341
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002342 if (res && (nch > 3)) {
2343 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002344 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002345 while (res && (pos < nch)) {
2346 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002347 && validate_test(CHILD(tree, pos + 1))
2348 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002349 && validate_test(CHILD(tree, pos + 3)));
2350 pos += 4;
2351 }
2352 }
2353 return (res);
2354
2355} /* validate_dictmaker() */
2356
2357
Guido van Rossum47478871996-08-21 14:32:37 +00002358static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002359validate_eval_input(tree)
2360 node *tree;
2361{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002362 int pos;
2363 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002364 int res = (validate_ntype(tree, eval_input)
2365 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002366 && validate_testlist(CHILD(tree, 0))
2367 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2368
Guido van Rossum3d602e31996-07-21 02:33:56 +00002369 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002370 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002371
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002372 return (res);
2373
2374} /* validate_eval_input() */
2375
2376
Guido van Rossum47478871996-08-21 14:32:37 +00002377static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002378validate_node(tree)
2379 node *tree;
2380{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002381 int nch = 0; /* num. children on current node */
2382 int res = 1; /* result value */
2383 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002384
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002385 while (res & (tree != 0)) {
2386 nch = NCH(tree);
2387 next = 0;
2388 switch (TYPE(tree)) {
2389 /*
2390 * Definition nodes.
2391 */
2392 case funcdef:
2393 res = validate_funcdef(tree);
2394 break;
2395 case classdef:
2396 res = validate_class(tree);
2397 break;
2398 /*
2399 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002400 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002401 */
2402 case stmt:
2403 res = validate_stmt(tree);
2404 break;
2405 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002406 /*
2407 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum925e5471997-04-02 05:32:13 +00002408 * | import_stmt | global_stmt | exec_stmt | assert_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002409 */
2410 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002411 break;
2412 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002413 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002414 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2415 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2416 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002417 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2418 if (res)
2419 next = CHILD(tree, 0);
2420 else if (nch == 1)
2421 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002422 break;
2423 /*
2424 * Compound statements.
2425 */
2426 case simple_stmt:
2427 res = validate_simple_stmt(tree);
2428 break;
2429 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002430 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002431 break;
2432 /*
2433 * Fundemental statements.
2434 */
2435 case expr_stmt:
2436 res = validate_expr_stmt(tree);
2437 break;
2438 case print_stmt:
2439 res = validate_print_stmt(tree);
2440 break;
2441 case del_stmt:
2442 res = validate_del_stmt(tree);
2443 break;
2444 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002445 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002446 && validate_name(CHILD(tree, 0), "pass"));
2447 break;
2448 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002449 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002450 && validate_name(CHILD(tree, 0), "break"));
2451 break;
2452 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002453 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002454 && validate_name(CHILD(tree, 0), "continue"));
2455 break;
2456 case return_stmt:
2457 res = validate_return_stmt(tree);
2458 break;
2459 case raise_stmt:
2460 res = validate_raise_stmt(tree);
2461 break;
2462 case import_stmt:
2463 res = validate_import_stmt(tree);
2464 break;
2465 case global_stmt:
2466 res = validate_global_stmt(tree);
2467 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002468 case exec_stmt:
2469 res = validate_exec_stmt(tree);
2470 break;
Guido van Rossum925e5471997-04-02 05:32:13 +00002471 case assert_stmt:
2472 res = validate_assert_stmt(tree);
2473 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002474 case if_stmt:
2475 res = validate_if(tree);
2476 break;
2477 case while_stmt:
2478 res = validate_while(tree);
2479 break;
2480 case for_stmt:
2481 res = validate_for(tree);
2482 break;
2483 case try_stmt:
2484 res = validate_try(tree);
2485 break;
2486 case suite:
2487 res = validate_suite(tree);
2488 break;
2489 /*
2490 * Expression nodes.
2491 */
2492 case testlist:
2493 res = validate_testlist(tree);
2494 break;
2495 case test:
2496 res = validate_test(tree);
2497 break;
2498 case and_test:
2499 res = validate_and_test(tree);
2500 break;
2501 case not_test:
2502 res = validate_not_test(tree);
2503 break;
2504 case comparison:
2505 res = validate_comparison(tree);
2506 break;
2507 case exprlist:
2508 res = validate_exprlist(tree);
2509 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002510 case comp_op:
2511 res = validate_comp_op(tree);
2512 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002513 case expr:
2514 res = validate_expr(tree);
2515 break;
2516 case xor_expr:
2517 res = validate_xor_expr(tree);
2518 break;
2519 case and_expr:
2520 res = validate_and_expr(tree);
2521 break;
2522 case shift_expr:
2523 res = validate_shift_expr(tree);
2524 break;
2525 case arith_expr:
2526 res = validate_arith_expr(tree);
2527 break;
2528 case term:
2529 res = validate_term(tree);
2530 break;
2531 case factor:
2532 res = validate_factor(tree);
2533 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002534 case power:
2535 res = validate_power(tree);
2536 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002537 case atom:
2538 res = validate_atom(tree);
2539 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002540
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002541 default:
2542 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002543 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002544 res = 0;
2545 break;
2546 }
2547 tree = next;
2548 }
2549 return (res);
2550
2551} /* validate_node() */
2552
2553
Guido van Rossum47478871996-08-21 14:32:37 +00002554static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002555validate_expr_tree(tree)
2556 node *tree;
2557{
2558 int res = validate_eval_input(tree);
2559
2560 if (!res && !PyErr_Occurred())
2561 err_string("Could not validate expression tuple.");
2562
2563 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002564
2565} /* validate_expr_tree() */
2566
2567
Guido van Rossum3d602e31996-07-21 02:33:56 +00002568/* file_input:
2569 * (NEWLINE | stmt)* ENDMARKER
2570 */
Guido van Rossum47478871996-08-21 14:32:37 +00002571static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002572validate_file_input(tree)
2573 node *tree;
2574{
2575 int j = 0;
2576 int nch = NCH(tree) - 1;
2577 int res = ((nch >= 0)
2578 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002579
Guido van Rossum3d602e31996-07-21 02:33:56 +00002580 for ( ; res && (j < nch); ++j) {
2581 if (TYPE(CHILD(tree, j)) == stmt)
2582 res = validate_stmt(CHILD(tree, j));
2583 else
2584 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002585 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002586 /* This stays in to prevent any internal failues from getting to the
2587 * user. Hopefully, this won't be needed. If a user reports getting
2588 * this, we have some debugging to do.
2589 */
2590 if (!res && !PyErr_Occurred())
2591 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2592
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002593 return (res);
2594
Guido van Rossum2a288461996-08-21 21:55:43 +00002595} /* validate_file_input() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002596
2597
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002598/* Functions exported by this module. Most of this should probably
2599 * be converted into an AST object with methods, but that is better
2600 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002601 * We'd really have to write a wrapper around it all anyway to allow
2602 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002603 */
2604static PyMethodDef parser_functions[] = {
Guido van Rossum3d602e31996-07-21 02:33:56 +00002605 {"ast2tuple", parser_ast2tuple, 1,
2606 "Creates a tuple-tree representation of an AST."},
Guido van Rossum47478871996-08-21 14:32:37 +00002607 {"ast2list", parser_ast2list, 1,
2608 "Creates a list-tree representation of an AST."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002609 {"compileast", parser_compileast, 1,
2610 "Compiles an AST object into a code object."},
2611 {"expr", parser_expr, 1,
2612 "Creates an AST object from an expression."},
2613 {"isexpr", parser_isexpr, 1,
2614 "Determines if an AST object was created from an expression."},
2615 {"issuite", parser_issuite, 1,
2616 "Determines if an AST object was created from a suite."},
2617 {"suite", parser_suite, 1,
2618 "Creates an AST object from a suite."},
Guido van Rossum47478871996-08-21 14:32:37 +00002619 {"sequence2ast", parser_tuple2ast, 1,
2620 "Creates an AST object from a tree representation."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002621 {"tuple2ast", parser_tuple2ast, 1,
Guido van Rossum47478871996-08-21 14:32:37 +00002622 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002623
2624 {0, 0, 0}
2625 };
2626
2627
Guido van Rossum52f2c051993-11-10 12:53:24 +00002628void
Guido van Rossum3d602e31996-07-21 02:33:56 +00002629initparser()
2630 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002631 PyObject* module;
2632 PyObject* dict;
2633
2634 PyAST_Type.ob_type = &PyType_Type;
2635 module = Py_InitModule("parser", parser_functions);
2636 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002637
Fred Drake0225a381997-10-07 19:32:00 +00002638 parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002639
2640 if ((parser_error == 0)
2641 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2642 /*
2643 * This is serious.
2644 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002645 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002646 }
2647 /*
2648 * Nice to have, but don't cry if we fail.
2649 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002650 Py_INCREF(&PyAST_Type);
2651 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2652
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002653 PyDict_SetItemString(dict, "__copyright__",
2654 PyString_FromString(parser_copyright_string));
2655 PyDict_SetItemString(dict, "__doc__",
2656 PyString_FromString(parser_doc_string));
2657 PyDict_SetItemString(dict, "__version__",
2658 PyString_FromString(parser_version_string));
2659
2660} /* initparser() */
2661
2662
2663/*
Guido van Rossum3d602e31996-07-21 02:33:56 +00002664 * end of parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002665 */