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