blob: 94e22ec544a31a3bc68665e0102a05006c890302 [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 Rossum3d602e31996-07-21 02:33:56 +0000823#define VALIDATER(n) static int validate_##n()
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000824
825
826/*
827 * Validation for the code above:
828 */
829VALIDATER(expr_tree);
830VALIDATER(suite_tree);
831
832
833/*
834 * Validation routines used within the validation section:
835 */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000836staticforward int validate_terminal();
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000837
838#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
839#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
840#define validate_colon(ch) validate_terminal(ch, COLON, ":")
841#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
842#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
843#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000844#define validate_indent(ch) validate_terminal(ch, INDENT, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000845#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000846#define validate_newline(ch) validate_terminal(ch, NEWLINE, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000847#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
848#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
849#define validate_star(ch) validate_terminal(ch, STAR, "*")
850#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000851#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
Guido van Rossum47478871996-08-21 14:32:37 +0000852#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000853#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000854
Guido van Rossum3d602e31996-07-21 02:33:56 +0000855VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000856VALIDATER(class); VALIDATER(node);
857VALIDATER(parameters); VALIDATER(suite);
858VALIDATER(testlist); VALIDATER(varargslist);
859VALIDATER(fpdef); VALIDATER(fplist);
860VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000861VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000862VALIDATER(print_stmt); VALIDATER(del_stmt);
863VALIDATER(return_stmt);
864VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000865VALIDATER(global_stmt); VALIDATER(file_input);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000866VALIDATER(exec_stmt); VALIDATER(compound_stmt);
867VALIDATER(while); VALIDATER(for);
868VALIDATER(try); VALIDATER(except_clause);
869VALIDATER(test); VALIDATER(and_test);
870VALIDATER(not_test); VALIDATER(comparison);
871VALIDATER(comp_op); VALIDATER(expr);
872VALIDATER(xor_expr); VALIDATER(and_expr);
873VALIDATER(shift_expr); VALIDATER(arith_expr);
874VALIDATER(term); VALIDATER(factor);
875VALIDATER(atom); VALIDATER(lambdef);
876VALIDATER(trailer); VALIDATER(subscript);
Guido van Rossum47478871996-08-21 14:32:37 +0000877VALIDATER(subscriptlist); VALIDATER(sliceop);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000878VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000879VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000880
881
882#define is_even(n) (((n) & 1) == 0)
883#define is_odd(n) (((n) & 1) == 1)
884
885
886static int
887validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000888 node *n;
889 int t;
Guido van Rossum47478871996-08-21 14:32:37 +0000890{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000891 int res = (TYPE(n) == t);
892
893 if (!res) {
894 char buffer[128];
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000895 sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000896 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000897 }
898 return (res);
899
900} /* validate_ntype() */
901
902
903static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000904validate_numnodes(n, num, name)
905 node *n;
906 int num;
907 const char *const name;
Guido van Rossum47478871996-08-21 14:32:37 +0000908{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000909 if (NCH(n) != num) {
910 char buff[60];
911 sprintf(buff, "Illegal number of children for %s node.", name);
912 err_string(buff);
913 }
914 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000915
Guido van Rossum3d602e31996-07-21 02:33:56 +0000916} /* validate_numnodes() */
917
918
919static int
920validate_terminal(terminal, type, string)
921 node *terminal;
922 int type;
923 char *string;
Guido van Rossum47478871996-08-21 14:32:37 +0000924{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000925 int res = (validate_ntype(terminal, type)
926 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
927
928 if (!res && !PyErr_Occurred()) {
929 char buffer[60];
930 sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
931 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000932 }
933 return (res);
934
935} /* validate_terminal() */
936
937
Guido van Rossum47478871996-08-21 14:32:37 +0000938/* X (',' X) [',']
939 */
940static int
941validate_repeating_list(tree, ntype, vfunc, name)
942 node *tree;
943 int ntype;
944 int (*vfunc)();
945 const char *const name;
946{
947 int nch = NCH(tree);
948 int res = (nch && validate_ntype(tree, ntype)
949 && vfunc(CHILD(tree, 0)));
950
951 if (!res && !PyErr_Occurred())
952 validate_numnodes(tree, 1, name);
953 else {
954 if (is_even(nch))
955 res = validate_comma(CHILD(tree, --nch));
956 if (res && nch > 1) {
957 int pos = 1;
958 for ( ; res && pos < nch; pos += 2)
959 res = (validate_comma(CHILD(tree, pos))
960 && vfunc(CHILD(tree, pos + 1)));
961 }
962 }
963 return (res);
964
965} /* validate_repeating_list() */
966
967
Guido van Rossum3d602e31996-07-21 02:33:56 +0000968/* VALIDATE(class)
969 *
970 * classdef:
971 * 'class' NAME ['(' testlist ')'] ':' suite
972 */
Guido van Rossum47478871996-08-21 14:32:37 +0000973static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000974validate_class(tree)
975 node *tree;
976{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000977 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000978 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000979
Guido van Rossum3d602e31996-07-21 02:33:56 +0000980 if (res) {
981 res = (validate_name(CHILD(tree, 0), "class")
982 && validate_ntype(CHILD(tree, 1), NAME)
983 && validate_colon(CHILD(tree, nch - 2))
984 && validate_suite(CHILD(tree, nch - 1)));
985 }
986 else
987 validate_numnodes(tree, 4, "class");
988 if (res && (nch == 7)) {
989 res = (validate_lparen(CHILD(tree, 2))
990 && validate_testlist(CHILD(tree, 3))
991 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000992 }
993 return (res);
994
995} /* validate_class() */
996
997
Guido van Rossum3d602e31996-07-21 02:33:56 +0000998/* if_stmt:
999 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1000 */
Guido van Rossum47478871996-08-21 14:32:37 +00001001static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001002validate_if(tree)
1003 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001004{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001005 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001006 int res = (validate_ntype(tree, if_stmt)
1007 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001008 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +00001009 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001010 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001011 && validate_suite(CHILD(tree, 3)));
1012
1013 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001014 /* ... 'else' ':' suite */
1015 res = (validate_name(CHILD(tree, nch - 3), "else")
1016 && validate_colon(CHILD(tree, nch - 2))
1017 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001018 nch -= 3;
1019 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001020 else if (!res && !PyErr_Occurred())
1021 validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001022 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001023 /* Will catch the case for nch < 4 */
1024 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001025 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001026 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001027 int j = 4;
1028 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001029 res = (validate_name(CHILD(tree, j), "elif")
1030 && validate_colon(CHILD(tree, j + 2))
1031 && validate_test(CHILD(tree, j + 1))
1032 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001033 j += 4;
1034 }
1035 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001036 return (res);
1037
1038} /* validate_if() */
1039
1040
Guido van Rossum3d602e31996-07-21 02:33:56 +00001041/* parameters:
1042 * '(' [varargslist] ')'
1043 *
1044 */
Guido van Rossum47478871996-08-21 14:32:37 +00001045static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001046validate_parameters(tree)
1047 node *tree;
1048{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001049 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001050 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001051
Guido van Rossum3d602e31996-07-21 02:33:56 +00001052 if (res) {
1053 res = (validate_lparen(CHILD(tree, 0))
1054 && validate_rparen(CHILD(tree, nch - 1)));
1055 if (res && (nch == 3))
1056 res = validate_varargslist(CHILD(tree, 1));
1057 }
1058 else
1059 validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001060
1061 return (res);
1062
1063} /* validate_parameters() */
1064
1065
Guido van Rossum3d602e31996-07-21 02:33:56 +00001066/* VALIDATE(suite)
1067 *
1068 * suite:
1069 * simple_stmt
1070 * | NEWLINE INDENT stmt+ DEDENT
1071 */
Guido van Rossum47478871996-08-21 14:32:37 +00001072static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001073validate_suite(tree)
1074 node *tree;
1075{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001076 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001077 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001078
Guido van Rossum3d602e31996-07-21 02:33:56 +00001079 if (res && (nch == 1))
1080 res = validate_simple_stmt(CHILD(tree, 0));
1081 else if (res) {
1082 /* NEWLINE INDENT stmt+ DEDENT */
1083 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001084 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001085 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001086 && validate_dedent(CHILD(tree, nch - 1)));
1087
Guido van Rossum3d602e31996-07-21 02:33:56 +00001088 if (res && (nch > 4)) {
1089 int i = 3;
1090 --nch; /* forget the DEDENT */
1091 for ( ; res && (i < nch); ++i)
1092 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001093 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001094 else if (nch < 4)
1095 validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001096 }
1097 return (res);
1098
1099} /* validate_suite() */
1100
1101
Guido van Rossum47478871996-08-21 14:32:37 +00001102static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001103validate_testlist(tree)
1104 node *tree;
1105{
Guido van Rossum47478871996-08-21 14:32:37 +00001106 return (validate_repeating_list(tree, testlist,
1107 validate_test, "testlist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001108
1109} /* validate_testlist() */
1110
1111
Guido van Rossum3d602e31996-07-21 02:33:56 +00001112/* VALIDATE(varargslist)
1113 *
1114 * varargslist:
1115 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1116 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1117 *
1118 * (fpdef ['=' test] ',')*
1119 * ('*' NAME [',' ('**'|'*' '*') NAME]
1120 * | ('**'|'*' '*') NAME)
1121 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1122 *
1123 */
Guido van Rossum47478871996-08-21 14:32:37 +00001124static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001125validate_varargslist(tree)
1126 node *tree;
1127{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001128 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001129 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001130
Guido van Rossum3d602e31996-07-21 02:33:56 +00001131 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1132 /* (fpdef ['=' test] ',')*
1133 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1134 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001135 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001136 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001137
Guido van Rossum3d602e31996-07-21 02:33:56 +00001138 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1139 res = validate_fpdef(CHILD(tree, pos));
1140 if (res) {
1141 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1142 res = validate_test(CHILD(tree, pos + 2));
1143 pos += 2;
1144 }
1145 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001146 pos += 2;
1147 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001148 }
1149 if (res) {
1150 remaining = nch - pos;
1151 res = ((remaining == 2) || (remaining == 3)
1152 || (remaining == 5) || (remaining == 6));
1153 if (!res)
1154 validate_numnodes(tree, 2, "varargslist");
1155 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1156 return ((remaining == 2)
1157 && validate_ntype(CHILD(tree, pos+1), NAME));
1158 else {
1159 res = validate_star(CHILD(tree, pos++));
1160 --remaining;
1161 }
1162 }
1163 if (res) {
1164 if (remaining == 2) {
1165 res = (validate_star(CHILD(tree, pos))
1166 && validate_ntype(CHILD(tree, pos + 1), NAME));
1167 }
1168 else {
1169 res = validate_ntype(CHILD(tree, pos++), NAME);
1170 if (res && (remaining >= 4)) {
1171 res = validate_comma(CHILD(tree, pos));
1172 if (--remaining == 3)
1173 res == (validate_star(CHILD(tree, pos + 1))
1174 && validate_star(CHILD(tree, pos + 2)));
1175 else
1176 validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1177 }
1178 }
1179 }
1180 if (!res && !PyErr_Occurred())
1181 err_string("Incorrect validation of variable arguments list.");
1182 }
1183 else if (res) {
1184 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1185 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1186 --nch;
1187
1188 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1189 res = (is_odd(nch)
1190 && validate_fpdef(CHILD(tree, 0)));
1191
1192 if (res && (nch > 1)) {
1193 int pos = 1;
1194 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1195 res = validate_test(CHILD(tree, 2));
1196 pos += 2;
1197 }
1198 /* ... (',' fpdef ['=' test])* */
1199 for ( ; res && (pos < nch); pos += 2) {
1200 /* ',' fpdef */
1201 res = (validate_comma(CHILD(tree, pos))
1202 && validate_fpdef(CHILD(tree, pos + 1)));
1203 if (res
1204 && ((nch - pos) > 2)
1205 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1206 /* ['=' test] */
1207 res = validate_test(CHILD(tree, pos + 3));
1208 pos += 2;
1209 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001210 }
1211 }
1212 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001213 else
1214 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001215
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001216 return (res);
1217
1218} /* validate_varargslist() */
1219
1220
Guido van Rossum3d602e31996-07-21 02:33:56 +00001221/* VALIDATE(fpdef)
1222 *
1223 * fpdef:
1224 * NAME
1225 * | '(' fplist ')'
1226 */
Guido van Rossum47478871996-08-21 14:32:37 +00001227static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001228validate_fpdef(tree)
1229 node *tree;
1230{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001231 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001232 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001233
Guido van Rossum3d602e31996-07-21 02:33:56 +00001234 if (res) {
1235 if (nch == 1)
1236 res = validate_ntype(CHILD(tree, 0), NAME);
1237 else if (nch == 3)
1238 res = (validate_lparen(CHILD(tree, 0))
1239 && validate_fplist(CHILD(tree, 1))
1240 && validate_rparen(CHILD(tree, 2)));
1241 else
1242 validate_numnodes(tree, 1, "fpdef");
1243 }
1244 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001245
1246} /* validate_fpdef() */
1247
1248
Guido van Rossum47478871996-08-21 14:32:37 +00001249static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001250validate_fplist(tree)
1251 node *tree;
1252{
Guido van Rossum47478871996-08-21 14:32:37 +00001253 return (validate_repeating_list(tree, fplist,
1254 validate_fpdef, "fplist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001255
1256} /* validate_fplist() */
1257
1258
Guido van Rossum3d602e31996-07-21 02:33:56 +00001259/* simple_stmt | compound_stmt
1260 *
1261 */
Guido van Rossum47478871996-08-21 14:32:37 +00001262static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001263validate_stmt(tree)
1264 node *tree;
1265{
1266 int res = (validate_ntype(tree, stmt)
1267 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001268
Guido van Rossum3d602e31996-07-21 02:33:56 +00001269 if (res) {
1270 tree = CHILD(tree, 0);
1271
1272 if (TYPE(tree) == simple_stmt)
1273 res = validate_simple_stmt(tree);
1274 else
1275 res = validate_compound_stmt(tree);
1276 }
1277 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001278
1279} /* validate_stmt() */
1280
1281
Guido van Rossum3d602e31996-07-21 02:33:56 +00001282/* small_stmt (';' small_stmt)* [';'] NEWLINE
1283 *
1284 */
Guido van Rossum47478871996-08-21 14:32:37 +00001285static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001286validate_simple_stmt(tree)
1287 node *tree;
1288{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001289 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001290 int res = (validate_ntype(tree, simple_stmt)
1291 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001292 && validate_small_stmt(CHILD(tree, 0))
1293 && validate_newline(CHILD(tree, nch - 1)));
1294
Guido van Rossum3d602e31996-07-21 02:33:56 +00001295 if (nch < 2)
1296 res = validate_numnodes(tree, 2, "simple_stmt");
1297 --nch; /* forget the NEWLINE */
1298 if (res && is_even(nch))
1299 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001300 if (res && (nch > 2)) {
1301 int i;
1302
Guido van Rossum3d602e31996-07-21 02:33:56 +00001303 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001304 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001305 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001306 }
1307 return (res);
1308
1309} /* validate_simple_stmt() */
1310
1311
Guido van Rossum47478871996-08-21 14:32:37 +00001312static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001313validate_small_stmt(tree)
1314 node *tree;
1315{
1316 int nch = NCH(tree);
1317 int res = (validate_numnodes(tree, 1, "small_stmt")
1318 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1319 || (TYPE(CHILD(tree, 0)) == print_stmt)
1320 || (TYPE(CHILD(tree, 0)) == del_stmt)
1321 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1322 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1323 || (TYPE(CHILD(tree, 0)) == import_stmt)
1324 || (TYPE(CHILD(tree, 0)) == global_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001325 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1326
1327 if (res)
1328 res = validate_node(CHILD(tree, 0));
1329 else if (nch == 1) {
1330 char buffer[60];
1331 sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1332 TYPE(CHILD(tree, 0)));
1333 err_string(buffer);
1334 }
1335 return (res);
1336
1337} /* validate_small_stmt */
1338
1339
1340/* compound_stmt:
1341 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1342 */
Guido van Rossum47478871996-08-21 14:32:37 +00001343static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001344validate_compound_stmt(tree)
1345 node *tree;
1346{
1347 int res = (validate_ntype(tree, compound_stmt)
1348 && validate_numnodes(tree, 1, "compound_stmt"));
1349
1350 if (!res)
1351 return (0);
1352
1353 tree = CHILD(tree, 0);
1354 res = ((TYPE(tree) == if_stmt)
1355 || (TYPE(tree) == while_stmt)
1356 || (TYPE(tree) == for_stmt)
1357 || (TYPE(tree) == try_stmt)
1358 || (TYPE(tree) == funcdef)
1359 || (TYPE(tree) == classdef));
1360 if (res)
1361 res = validate_node(tree);
1362 else {
1363 char buffer[60];
1364 sprintf(buffer, "Illegal compound statement type: %d.", TYPE(tree));
1365 err_string(buffer);
1366 }
1367 return (res);
1368
1369} /* validate_compound_stmt() */
1370
1371
Guido van Rossum47478871996-08-21 14:32:37 +00001372static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001373validate_expr_stmt(tree)
1374 node *tree;
1375{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001376 int j;
1377 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001378 int res = (validate_ntype(tree, expr_stmt)
1379 && is_odd(nch)
1380 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001381
Guido van Rossum3d602e31996-07-21 02:33:56 +00001382 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001383 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001384 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001385
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001386 return (res);
1387
1388} /* validate_expr_stmt() */
1389
1390
Guido van Rossum3d602e31996-07-21 02:33:56 +00001391/* print_stmt:
1392 *
1393 * 'print' (test ',')* [test]
1394 *
1395 */
Guido van Rossum47478871996-08-21 14:32:37 +00001396static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001397validate_print_stmt(tree)
1398 node *tree;
1399{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001400 int j;
1401 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001402 int res = (validate_ntype(tree, print_stmt)
1403 && (nch != 0)
1404 && validate_name(CHILD(tree, 0), "print"));
1405
1406 if (res && is_even(nch)) {
1407 res = validate_test(CHILD(tree, nch - 1));
1408 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001409 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001410 else if (!res && !PyErr_Occurred())
1411 validate_numnodes(tree, 1, "print_stmt");
1412 for (j = 1; res && (j < nch); j += 2)
1413 res = (validate_test(CHILD(tree, j))
1414 && validate_ntype(CHILD(tree, j + 1), COMMA));
1415
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001416 return (res);
1417
1418} /* validate_print_stmt() */
1419
1420
Guido van Rossum47478871996-08-21 14:32:37 +00001421static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001422validate_del_stmt(tree)
1423 node *tree;
1424{
1425 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001426 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001427 && validate_exprlist(CHILD(tree, 1)));
1428
1429} /* validate_del_stmt() */
1430
1431
Guido van Rossum47478871996-08-21 14:32:37 +00001432static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001433validate_return_stmt(tree)
1434 node *tree;
1435{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001436 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001437 int res = (validate_ntype(tree, return_stmt)
1438 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001439 && validate_name(CHILD(tree, 0), "return"));
1440
Guido van Rossum3d602e31996-07-21 02:33:56 +00001441 if (res && (nch == 2))
1442 res = validate_testlist(CHILD(tree, 1));
1443
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001444 return (res);
1445
1446} /* validate_return_stmt() */
1447
1448
Guido van Rossum47478871996-08-21 14:32:37 +00001449static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001450validate_raise_stmt(tree)
1451 node *tree;
1452{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001453 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001454 int res = (validate_ntype(tree, raise_stmt)
1455 && ((nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001456
Guido van Rossum3d602e31996-07-21 02:33:56 +00001457 if (res) {
1458 res = (validate_name(CHILD(tree, 0), "raise")
1459 && validate_test(CHILD(tree, 1)));
1460 if (res && nch > 2) {
1461 res = (validate_comma(CHILD(tree, 2))
1462 && validate_test(CHILD(tree, 3)));
1463 if (res && (nch > 4))
1464 res = (validate_comma(CHILD(tree, 4))
1465 && validate_test(CHILD(tree, 5)));
1466 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001467 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001468 else
1469 validate_numnodes(tree, 2, "raise");
1470 if (res && (nch == 4))
1471 res = (validate_comma(CHILD(tree, 2))
1472 && validate_test(CHILD(tree, 3)));
1473
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001474 return (res);
1475
1476} /* validate_raise_stmt() */
1477
1478
Guido van Rossum3d602e31996-07-21 02:33:56 +00001479/* import_stmt:
1480 *
1481 * 'import' dotted_name (',' dotted_name)*
1482 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1483 */
Guido van Rossum47478871996-08-21 14:32:37 +00001484static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001485validate_import_stmt(tree)
1486 node *tree;
1487{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001488 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001489 int res = (validate_ntype(tree, import_stmt)
1490 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001491 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001492 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001493
1494 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001495 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001496
Guido van Rossum3d602e31996-07-21 02:33:56 +00001497 for (j = 2; res && (j < nch); j += 2)
1498 res = (validate_comma(CHILD(tree, j))
1499 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001500 }
1501 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001502 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001503 && validate_name(CHILD(tree, 2), "import"));
1504 if (nch == 4) {
1505 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001506 || (TYPE(CHILD(tree, 3)) == STAR));
1507 if (!res)
1508 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001509 }
1510 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001511 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001512 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001513 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001514 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001515 res = (validate_comma(CHILD(tree, j))
1516 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001517 }
1518 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001519 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001520 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001521
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001522 return (res);
1523
1524} /* validate_import_stmt() */
1525
1526
Guido van Rossum47478871996-08-21 14:32:37 +00001527static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001528validate_global_stmt(tree)
1529 node *tree;
1530{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001531 int j;
1532 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001533 int res = (validate_ntype(tree, global_stmt)
1534 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001535
Guido van Rossum3d602e31996-07-21 02:33:56 +00001536 if (res)
1537 res = (validate_name(CHILD(tree, 0), "global")
1538 && validate_ntype(CHILD(tree, 1), NAME));
1539 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001540 res = (validate_comma(CHILD(tree, j))
1541 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001542
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001543 return (res);
1544
1545} /* validate_global_stmt() */
1546
1547
Guido van Rossum3d602e31996-07-21 02:33:56 +00001548/* exec_stmt:
1549 *
1550 * 'exec' expr ['in' test [',' test]]
1551 */
Guido van Rossum47478871996-08-21 14:32:37 +00001552static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001553validate_exec_stmt(tree)
1554 node *tree;
1555{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001556 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001557 int res = (validate_ntype(tree, exec_stmt)
1558 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001559 && validate_name(CHILD(tree, 0), "exec")
1560 && validate_expr(CHILD(tree, 1)));
1561
Guido van Rossum3d602e31996-07-21 02:33:56 +00001562 if (!res && !PyErr_Occurred())
1563 err_string("Illegal exec statement.");
1564 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001565 res = (validate_name(CHILD(tree, 2), "in")
1566 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001567 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001568 res = (validate_comma(CHILD(tree, 4))
1569 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001570
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001571 return (res);
1572
1573} /* validate_exec_stmt() */
1574
1575
Guido van Rossum47478871996-08-21 14:32:37 +00001576static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001577validate_while(tree)
1578 node *tree;
1579{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001580 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001581 int res = (validate_ntype(tree, while_stmt)
1582 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001583 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001584 && validate_test(CHILD(tree, 1))
1585 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001586 && validate_suite(CHILD(tree, 3)));
1587
Guido van Rossum3d602e31996-07-21 02:33:56 +00001588 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001589 res = (validate_name(CHILD(tree, 4), "else")
1590 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001591 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001592
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001593 return (res);
1594
1595} /* validate_while() */
1596
1597
Guido van Rossum47478871996-08-21 14:32:37 +00001598static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001599validate_for(tree)
1600 node *tree;
1601{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001602 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001603 int res = (validate_ntype(tree, for_stmt)
1604 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001605 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001606 && validate_exprlist(CHILD(tree, 1))
1607 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001608 && validate_testlist(CHILD(tree, 3))
1609 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001610 && validate_suite(CHILD(tree, 5)));
1611
Guido van Rossum3d602e31996-07-21 02:33:56 +00001612 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001613 res = (validate_name(CHILD(tree, 6), "else")
1614 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001615 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001616
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001617 return (res);
1618
1619} /* validate_for() */
1620
1621
Guido van Rossum3d602e31996-07-21 02:33:56 +00001622/* try_stmt:
1623 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1624 * | 'try' ':' suite 'finally' ':' suite
1625 *
1626 */
Guido van Rossum47478871996-08-21 14:32:37 +00001627static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001628validate_try(tree)
1629 node *tree;
1630{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001631 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001632 int pos = 3;
1633 int res = (validate_ntype(tree, try_stmt)
1634 && (nch >= 6) && ((nch % 3) == 0));
1635
1636 if (res)
1637 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001638 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001639 && validate_suite(CHILD(tree, 2))
1640 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001641 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001642 else {
1643 const char* name = "execpt";
1644 char buffer[60];
1645 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1646 name = STR(CHILD(tree, nch - 3));
1647 sprintf(buffer, "Illegal number of children for try/%s node.", name);
1648 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001649 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001650 /* Skip past except_clause sections: */
1651 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1652 res = (validate_except_clause(CHILD(tree, pos))
1653 && validate_colon(CHILD(tree, pos + 1))
1654 && validate_suite(CHILD(tree, pos + 2)));
1655 pos += 3;
1656 }
1657 if (res && (pos < nch)) {
1658 res = validate_ntype(CHILD(tree, pos), NAME);
1659 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1660 res = (validate_numnodes(tree, 6, "try/finally")
1661 && validate_colon(CHILD(tree, 4))
1662 && validate_suite(CHILD(tree, 5)));
1663 else if (res)
1664 if (nch == (pos + 3)) {
1665 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1666 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1667 if (!res)
1668 err_string("Illegal trailing triple in try statement.");
1669 }
1670 else if (nch == (pos + 6))
1671 res = (validate_name(CHILD(tree, pos), "except")
1672 && validate_colon(CHILD(tree, pos + 1))
1673 && validate_suite(CHILD(tree, pos + 2))
1674 && validate_name(CHILD(tree, pos + 3), "else"));
1675 else
1676 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001677 }
1678 return (res);
1679
1680} /* validate_try() */
1681
1682
Guido van Rossum47478871996-08-21 14:32:37 +00001683static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001684validate_except_clause(tree)
1685 node *tree;
1686{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001687 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001688 int res = (validate_ntype(tree, except_clause)
1689 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001690 && validate_name(CHILD(tree, 0), "except"));
1691
Guido van Rossum3d602e31996-07-21 02:33:56 +00001692 if (res && (nch > 1))
1693 res = validate_test(CHILD(tree, 1));
1694 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001695 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001696 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001697
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001698 return (res);
1699
1700} /* validate_except_clause() */
1701
1702
Guido van Rossum47478871996-08-21 14:32:37 +00001703static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001704validate_test(tree)
1705 node *tree;
1706{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001707 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001708 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001709
Guido van Rossum3d602e31996-07-21 02:33:56 +00001710 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001711 res = ((nch == 1)
1712 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001713 else if (res) {
1714 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001715 res = validate_and_test(CHILD(tree, 0));
1716 for (pos = 1; res && (pos < nch); pos += 2)
1717 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001718 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001719 }
1720 return (res);
1721
1722} /* validate_test() */
1723
1724
Guido van Rossum47478871996-08-21 14:32:37 +00001725static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001726validate_and_test(tree)
1727 node *tree;
1728{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001729 int pos;
1730 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001731 int res = (validate_ntype(tree, and_test)
1732 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001733 && validate_not_test(CHILD(tree, 0)));
1734
Guido van Rossum3d602e31996-07-21 02:33:56 +00001735 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001736 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001737 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001738
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001739 return (res);
1740
1741} /* validate_and_test() */
1742
1743
Guido van Rossum47478871996-08-21 14:32:37 +00001744static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001745validate_not_test(tree)
1746 node *tree;
1747{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001748 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001749 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001750
Guido van Rossum3d602e31996-07-21 02:33:56 +00001751 if (res) {
1752 if (nch == 2)
1753 res = (validate_name(CHILD(tree, 0), "not")
1754 && validate_not_test(CHILD(tree, 1)));
1755 else if (nch == 1)
1756 res = validate_comparison(CHILD(tree, 0));
1757 }
1758 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001759
1760} /* validate_not_test() */
1761
1762
Guido van Rossum47478871996-08-21 14:32:37 +00001763static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001764validate_comparison(tree)
1765 node *tree;
1766{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001767 int pos;
1768 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001769 int res = (validate_ntype(tree, comparison)
1770 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001771 && validate_expr(CHILD(tree, 0)));
1772
Guido van Rossum3d602e31996-07-21 02:33:56 +00001773 for (pos = 1; res && (pos < nch); pos += 2)
1774 res = (validate_comp_op(CHILD(tree, pos))
1775 && validate_expr(CHILD(tree, pos + 1)));
1776
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001777 return (res);
1778
1779} /* validate_comparison() */
1780
1781
Guido van Rossum47478871996-08-21 14:32:37 +00001782static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001783validate_comp_op(tree)
1784 node *tree;
1785{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001786 int res = 0;
1787 int nch = NCH(tree);
1788
Guido van Rossum3d602e31996-07-21 02:33:56 +00001789 if (!validate_ntype(tree, comp_op))
1790 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001791 if (nch == 1) {
1792 /*
1793 * Only child will be a terminal with a well-defined symbolic name
1794 * or a NAME with a string of either 'is' or 'in'
1795 */
1796 tree = CHILD(tree, 0);
1797 switch (TYPE(tree)) {
1798 case LESS:
1799 case GREATER:
1800 case EQEQUAL:
1801 case EQUAL:
1802 case LESSEQUAL:
1803 case GREATEREQUAL:
1804 case NOTEQUAL:
1805 res = 1;
1806 break;
1807 case NAME:
1808 res = ((strcmp(STR(tree), "in") == 0)
1809 || (strcmp(STR(tree), "is") == 0));
1810 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001811 char buff[128];
1812 sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1813 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001814 }
1815 break;
1816 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001817 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001818 break;
1819 }
1820 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001821 else if (res = validate_numnodes(tree, 2, "comp_op")) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001822 res = (validate_ntype(CHILD(tree, 0), NAME)
1823 && validate_ntype(CHILD(tree, 1), NAME)
1824 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1825 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1826 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1827 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001828 if (!res && !PyErr_Occurred())
1829 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001830 }
1831 return (res);
1832
1833} /* validate_comp_op() */
1834
1835
Guido van Rossum47478871996-08-21 14:32:37 +00001836static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001837validate_expr(tree)
1838 node *tree;
1839{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001840 int j;
1841 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001842 int res = (validate_ntype(tree, expr)
1843 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001844 && validate_xor_expr(CHILD(tree, 0)));
1845
Guido van Rossum3d602e31996-07-21 02:33:56 +00001846 for (j = 2; res && (j < nch); j += 2)
1847 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001848 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001849
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001850 return (res);
1851
1852} /* validate_expr() */
1853
1854
Guido van Rossum47478871996-08-21 14:32:37 +00001855static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001856validate_xor_expr(tree)
1857 node *tree;
1858{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001859 int j;
1860 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001861 int res = (validate_ntype(tree, xor_expr)
1862 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001863 && validate_and_expr(CHILD(tree, 0)));
1864
Guido van Rossum3d602e31996-07-21 02:33:56 +00001865 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001866 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001867 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001868
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001869 return (res);
1870
1871} /* validate_xor_expr() */
1872
1873
Guido van Rossum47478871996-08-21 14:32:37 +00001874static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001875validate_and_expr(tree)
1876 node *tree;
1877{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001878 int pos;
1879 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001880 int res = (validate_ntype(tree, and_expr)
1881 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001882 && validate_shift_expr(CHILD(tree, 0)));
1883
Guido van Rossum3d602e31996-07-21 02:33:56 +00001884 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001885 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001886 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001887
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001888 return (res);
1889
1890} /* validate_and_expr() */
1891
1892
1893static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001894validate_chain_two_ops(tree, termvalid, op1, op2)
1895 node *tree;
1896 int (*termvalid)();
1897 int op1;
1898 int op2;
1899 {
1900 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001901 int nch = NCH(tree);
1902 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001903 && (*termvalid)(CHILD(tree, 0)));
1904
Guido van Rossum3d602e31996-07-21 02:33:56 +00001905 for ( ; res && (pos < nch); pos += 2) {
1906 if (TYPE(CHILD(tree, pos)) != op1)
1907 res = validate_ntype(CHILD(tree, pos), op2);
1908 if (res)
1909 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001910 }
1911 return (res);
1912
1913} /* validate_chain_two_ops() */
1914
1915
Guido van Rossum47478871996-08-21 14:32:37 +00001916static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001917validate_shift_expr(tree)
1918 node *tree;
1919{
1920 return (validate_ntype(tree, shift_expr)
1921 && validate_chain_two_ops(tree, validate_arith_expr,
1922 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001923
1924} /* validate_shift_expr() */
1925
1926
Guido van Rossum47478871996-08-21 14:32:37 +00001927static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001928validate_arith_expr(tree)
1929 node *tree;
1930{
1931 return (validate_ntype(tree, arith_expr)
1932 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001933
1934} /* validate_arith_expr() */
1935
1936
Guido van Rossum47478871996-08-21 14:32:37 +00001937static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001938validate_term(tree)
1939 node *tree;
1940{
1941 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001942 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001943 int res = (validate_ntype(tree, term)
1944 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001945 && validate_factor(CHILD(tree, 0)));
1946
Guido van Rossum3d602e31996-07-21 02:33:56 +00001947 for ( ; res && (pos < nch); pos += 2)
1948 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001949 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001950 || (TYPE(CHILD(tree, pos)) == PERCENT))
1951 && validate_factor(CHILD(tree, pos + 1)));
1952
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001953 return (res);
1954
1955} /* validate_term() */
1956
1957
Guido van Rossum3d602e31996-07-21 02:33:56 +00001958/* factor:
1959 *
1960 * factor: ('+'|'-'|'~') factor | power
1961 */
Guido van Rossum47478871996-08-21 14:32:37 +00001962static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001963validate_factor(tree)
1964 node *tree;
1965{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001966 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001967 int res = (validate_ntype(tree, factor)
1968 && (((nch == 2)
1969 && ((TYPE(CHILD(tree, 0)) == PLUS)
1970 || (TYPE(CHILD(tree, 0)) == MINUS)
1971 || (TYPE(CHILD(tree, 0)) == TILDE))
1972 && validate_factor(CHILD(tree, 1)))
1973 || ((nch == 1)
1974 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001975 return (res);
1976
1977} /* validate_factor() */
1978
1979
Guido van Rossum3d602e31996-07-21 02:33:56 +00001980/* power:
1981 *
1982 * power: atom trailer* ('**' factor)*
1983 */
Guido van Rossum47478871996-08-21 14:32:37 +00001984static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001985validate_power(tree)
1986 node *tree;
1987{
1988 int pos = 1;
1989 int nch = NCH(tree);
1990 int res = (validate_ntype(tree, power) && (nch >= 1)
1991 && validate_atom(CHILD(tree, 0)));
1992
1993 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
1994 res = validate_trailer(CHILD(tree, pos++));
1995 if (res && (pos < nch)) {
1996 if (!is_even(nch - pos)) {
1997 err_string("Illegal number of nodes for 'power'.");
1998 return (0);
1999 }
2000 for ( ; res && (pos < (nch - 1)); pos += 2)
2001 res = (validate_doublestar(CHILD(tree, pos))
2002 && validate_factor(CHILD(tree, pos + 1)));
2003 }
2004 return (res);
2005
2006} /* validate_power() */
2007
2008
Guido van Rossum47478871996-08-21 14:32:37 +00002009static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002010validate_atom(tree)
2011 node *tree;
2012{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002013 int pos;
2014 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002015 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002016
2017 if (res) {
2018 switch (TYPE(CHILD(tree, 0))) {
2019 case LPAR:
2020 res = ((nch <= 3)
2021 && (validate_rparen(CHILD(tree, nch - 1))));
2022
Guido van Rossum3d602e31996-07-21 02:33:56 +00002023 if (res && (nch == 3))
2024 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002025 break;
2026 case LSQB:
2027 res = ((nch <= 3)
2028 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2029
Guido van Rossum3d602e31996-07-21 02:33:56 +00002030 if (res && (nch == 3))
2031 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002032 break;
2033 case LBRACE:
2034 res = ((nch <= 3)
2035 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2036
Guido van Rossum3d602e31996-07-21 02:33:56 +00002037 if (res && (nch == 3))
2038 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002039 break;
2040 case BACKQUOTE:
2041 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002042 && validate_testlist(CHILD(tree, 1))
2043 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2044 break;
2045 case NAME:
2046 case NUMBER:
2047 res = (nch == 1);
2048 break;
2049 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002050 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002051 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002052 break;
2053 default:
2054 res = 0;
2055 break;
2056 }
2057 }
2058 return (res);
2059
2060} /* validate_atom() */
2061
2062
Guido van Rossum3d602e31996-07-21 02:33:56 +00002063/* funcdef:
2064 * 'def' NAME parameters ':' suite
2065 *
2066 */
Guido van Rossum47478871996-08-21 14:32:37 +00002067static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002068validate_funcdef(tree)
2069 node *tree;
2070{
2071 return (validate_ntype(tree, funcdef)
2072 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002073 && validate_name(CHILD(tree, 0), "def")
2074 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002075 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002076 && validate_parameters(CHILD(tree, 2))
2077 && validate_suite(CHILD(tree, 4)));
2078
2079} /* validate_funcdef() */
2080
2081
Guido van Rossum47478871996-08-21 14:32:37 +00002082static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002083validate_lambdef(tree)
2084 node *tree;
2085{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002086 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002087 int res = (validate_ntype(tree, lambdef)
2088 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002089 && validate_name(CHILD(tree, 0), "lambda")
2090 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002091 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002092
Guido van Rossum3d602e31996-07-21 02:33:56 +00002093 if (res && (nch == 4))
2094 res = validate_varargslist(CHILD(tree, 1));
2095 else if (!res && !PyErr_Occurred())
2096 validate_numnodes(tree, 3, "lambdef");
2097
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002098 return (res);
2099
2100} /* validate_lambdef() */
2101
2102
Guido van Rossum3d602e31996-07-21 02:33:56 +00002103/* arglist:
2104 *
2105 * argument (',' argument)* [',']
2106 */
Guido van Rossum47478871996-08-21 14:32:37 +00002107static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002108validate_arglist(tree)
2109 node *tree;
2110{
Guido van Rossum47478871996-08-21 14:32:37 +00002111 return (validate_repeating_list(tree, arglist,
2112 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002113
2114} /* validate_arglist() */
2115
2116
2117
2118/* argument:
2119 *
2120 * [test '='] test
2121 */
Guido van Rossum47478871996-08-21 14:32:37 +00002122static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002123validate_argument(tree)
2124 node *tree;
2125{
2126 int nch = NCH(tree);
2127 int res = (validate_ntype(tree, argument)
2128 && ((nch == 1) || (nch == 3))
2129 && validate_test(CHILD(tree, 0)));
2130
2131 if (res && (nch == 3))
2132 res = (validate_equal(CHILD(tree, 1))
2133 && validate_test(CHILD(tree, 2)));
2134
2135 return (res);
2136
2137} /* validate_argument() */
2138
2139
2140
2141/* trailer:
2142 *
Guido van Rossum47478871996-08-21 14:32:37 +00002143 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002144 */
Guido van Rossum47478871996-08-21 14:32:37 +00002145static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002146validate_trailer(tree)
2147 node *tree;
2148{
2149 int nch = NCH(tree);
2150 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002151
2152 if (res) {
2153 switch (TYPE(CHILD(tree, 0))) {
2154 case LPAR:
2155 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002156 if (res && (nch == 3))
2157 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002158 break;
2159 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002160 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002161 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002162 && validate_ntype(CHILD(tree, 2), RSQB));
2163 break;
2164 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002165 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002166 && validate_ntype(CHILD(tree, 1), NAME));
2167 break;
2168 default:
2169 res = 0;
2170 break;
2171 }
2172 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002173 else
2174 validate_numnodes(tree, 2, "trailer");
2175
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002176 return (res);
2177
2178} /* validate_trailer() */
2179
2180
Guido van Rossum47478871996-08-21 14:32:37 +00002181/* subscriptlist:
2182 *
2183 * subscript (',' subscript)* [',']
2184 */
2185static int
2186validate_subscriptlist(tree)
2187 node *tree;
2188{
2189 return (validate_repeating_list(tree, subscriptlist,
2190 validate_subscript, "subscriptlist"));
2191
2192} /* validate_subscriptlist() */
2193
2194
Guido van Rossum3d602e31996-07-21 02:33:56 +00002195/* subscript:
2196 *
Guido van Rossum47478871996-08-21 14:32:37 +00002197 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002198 */
Guido van Rossum47478871996-08-21 14:32:37 +00002199static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002200validate_subscript(tree)
2201 node *tree;
2202{
Guido van Rossum47478871996-08-21 14:32:37 +00002203 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002204 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002205 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002206
Guido van Rossum47478871996-08-21 14:32:37 +00002207 if (!res) {
2208 if (!PyErr_Occurred())
2209 err_string("invalid number of arguments for subscript node");
2210 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002211 }
Guido van Rossum47478871996-08-21 14:32:37 +00002212 if (TYPE(CHILD(tree, 0)) == DOT)
2213 /* take care of ('.' '.' '.') possibility */
2214 return (validate_numnodes(tree, 3, "subscript")
2215 && validate_dot(CHILD(tree, 0))
2216 && validate_dot(CHILD(tree, 1))
2217 && validate_dot(CHILD(tree, 2)));
2218 if (nch == 1) {
2219 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002220 res = validate_test(CHILD(tree, 0));
2221 else
Guido van Rossum47478871996-08-21 14:32:37 +00002222 res = validate_colon(CHILD(tree, 0));
2223 return (res);
2224 }
2225 /* Must be [test] ':' [test] [sliceop],
2226 * but at least one of the optional components will
2227 * be present, but we don't know which yet.
2228 */
2229 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2230 res = validate_test(CHILD(tree, 0));
2231 offset = 1;
2232 }
2233 if (res)
2234 res = validate_colon(CHILD(tree, offset));
2235 if (res) {
2236 int rem = nch - ++offset;
2237 if (rem) {
2238 if (TYPE(CHILD(tree, offset)) == test) {
2239 res = validate_test(CHILD(tree, offset));
2240 ++offset;
2241 --rem;
2242 }
2243 if (res && rem)
2244 res = validate_sliceop(CHILD(tree, offset));
2245 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002246 }
2247 return (res);
2248
2249} /* validate_subscript() */
2250
2251
Guido van Rossum47478871996-08-21 14:32:37 +00002252static int
2253validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002254 node *tree;
2255{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002256 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002257 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2258 && validate_ntype(tree, sliceop);
2259 if (!res && !PyErr_Occurred()) {
2260 validate_numnodes(tree, 1, "sliceop");
2261 res = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002262 }
Guido van Rossum47478871996-08-21 14:32:37 +00002263 if (res)
2264 res = validate_colon(CHILD(tree, 0));
2265 if (res && (nch == 2))
2266 res = validate_test(CHILD(tree, 1));
2267
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002268 return (res);
2269
Guido van Rossum47478871996-08-21 14:32:37 +00002270} /* validate_sliceop() */
2271
2272
2273static int
2274validate_exprlist(tree)
2275 node *tree;
2276{
2277 return (validate_repeating_list(tree, exprlist,
2278 validate_expr, "exprlist"));
2279
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002280} /* validate_exprlist() */
2281
2282
Guido van Rossum47478871996-08-21 14:32:37 +00002283static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002284validate_dictmaker(tree)
2285 node *tree;
2286{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002287 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002288 int res = (validate_ntype(tree, dictmaker)
2289 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002290 && validate_test(CHILD(tree, 0))
2291 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002292 && validate_test(CHILD(tree, 2)));
2293
Guido van Rossum3d602e31996-07-21 02:33:56 +00002294 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002295 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002296 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002297 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002298
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002299 if (res && (nch > 3)) {
2300 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002301 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002302 while (res && (pos < nch)) {
2303 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002304 && validate_test(CHILD(tree, pos + 1))
2305 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002306 && validate_test(CHILD(tree, pos + 3)));
2307 pos += 4;
2308 }
2309 }
2310 return (res);
2311
2312} /* validate_dictmaker() */
2313
2314
Guido van Rossum47478871996-08-21 14:32:37 +00002315static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002316validate_eval_input(tree)
2317 node *tree;
2318{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002319 int pos;
2320 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002321 int res = (validate_ntype(tree, eval_input)
2322 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002323 && validate_testlist(CHILD(tree, 0))
2324 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2325
Guido van Rossum3d602e31996-07-21 02:33:56 +00002326 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002327 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002328
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002329 return (res);
2330
2331} /* validate_eval_input() */
2332
2333
Guido van Rossum47478871996-08-21 14:32:37 +00002334static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002335validate_node(tree)
2336 node *tree;
2337{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002338 int nch = 0; /* num. children on current node */
2339 int res = 1; /* result value */
2340 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002341
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002342 while (res & (tree != 0)) {
2343 nch = NCH(tree);
2344 next = 0;
2345 switch (TYPE(tree)) {
2346 /*
2347 * Definition nodes.
2348 */
2349 case funcdef:
2350 res = validate_funcdef(tree);
2351 break;
2352 case classdef:
2353 res = validate_class(tree);
2354 break;
2355 /*
2356 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002357 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002358 */
2359 case stmt:
2360 res = validate_stmt(tree);
2361 break;
2362 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002363 /*
2364 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum47478871996-08-21 14:32:37 +00002365 * | import_stmt | global_stmt | exec_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002366 */
2367 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002368 break;
2369 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002370 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002371 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2372 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2373 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002374 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2375 if (res)
2376 next = CHILD(tree, 0);
2377 else if (nch == 1)
2378 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002379 break;
2380 /*
2381 * Compound statements.
2382 */
2383 case simple_stmt:
2384 res = validate_simple_stmt(tree);
2385 break;
2386 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002387 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002388 break;
2389 /*
2390 * Fundemental statements.
2391 */
2392 case expr_stmt:
2393 res = validate_expr_stmt(tree);
2394 break;
2395 case print_stmt:
2396 res = validate_print_stmt(tree);
2397 break;
2398 case del_stmt:
2399 res = validate_del_stmt(tree);
2400 break;
2401 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002402 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002403 && validate_name(CHILD(tree, 0), "pass"));
2404 break;
2405 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002406 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002407 && validate_name(CHILD(tree, 0), "break"));
2408 break;
2409 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002410 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002411 && validate_name(CHILD(tree, 0), "continue"));
2412 break;
2413 case return_stmt:
2414 res = validate_return_stmt(tree);
2415 break;
2416 case raise_stmt:
2417 res = validate_raise_stmt(tree);
2418 break;
2419 case import_stmt:
2420 res = validate_import_stmt(tree);
2421 break;
2422 case global_stmt:
2423 res = validate_global_stmt(tree);
2424 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002425 case exec_stmt:
2426 res = validate_exec_stmt(tree);
2427 break;
2428 case if_stmt:
2429 res = validate_if(tree);
2430 break;
2431 case while_stmt:
2432 res = validate_while(tree);
2433 break;
2434 case for_stmt:
2435 res = validate_for(tree);
2436 break;
2437 case try_stmt:
2438 res = validate_try(tree);
2439 break;
2440 case suite:
2441 res = validate_suite(tree);
2442 break;
2443 /*
2444 * Expression nodes.
2445 */
2446 case testlist:
2447 res = validate_testlist(tree);
2448 break;
2449 case test:
2450 res = validate_test(tree);
2451 break;
2452 case and_test:
2453 res = validate_and_test(tree);
2454 break;
2455 case not_test:
2456 res = validate_not_test(tree);
2457 break;
2458 case comparison:
2459 res = validate_comparison(tree);
2460 break;
2461 case exprlist:
2462 res = validate_exprlist(tree);
2463 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002464 case comp_op:
2465 res = validate_comp_op(tree);
2466 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002467 case expr:
2468 res = validate_expr(tree);
2469 break;
2470 case xor_expr:
2471 res = validate_xor_expr(tree);
2472 break;
2473 case and_expr:
2474 res = validate_and_expr(tree);
2475 break;
2476 case shift_expr:
2477 res = validate_shift_expr(tree);
2478 break;
2479 case arith_expr:
2480 res = validate_arith_expr(tree);
2481 break;
2482 case term:
2483 res = validate_term(tree);
2484 break;
2485 case factor:
2486 res = validate_factor(tree);
2487 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002488 case power:
2489 res = validate_power(tree);
2490 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002491 case atom:
2492 res = validate_atom(tree);
2493 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002494
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002495 default:
2496 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002497 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002498 res = 0;
2499 break;
2500 }
2501 tree = next;
2502 }
2503 return (res);
2504
2505} /* validate_node() */
2506
2507
Guido van Rossum47478871996-08-21 14:32:37 +00002508static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002509validate_expr_tree(tree)
2510 node *tree;
2511{
2512 int res = validate_eval_input(tree);
2513
2514 if (!res && !PyErr_Occurred())
2515 err_string("Could not validate expression tuple.");
2516
2517 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002518
2519} /* validate_expr_tree() */
2520
2521
Guido van Rossum3d602e31996-07-21 02:33:56 +00002522/* file_input:
2523 * (NEWLINE | stmt)* ENDMARKER
2524 */
Guido van Rossum47478871996-08-21 14:32:37 +00002525static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002526validate_file_input(tree)
2527 node *tree;
2528{
2529 int j = 0;
2530 int nch = NCH(tree) - 1;
2531 int res = ((nch >= 0)
2532 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002533
Guido van Rossum3d602e31996-07-21 02:33:56 +00002534 for ( ; res && (j < nch); ++j) {
2535 if (TYPE(CHILD(tree, j)) == stmt)
2536 res = validate_stmt(CHILD(tree, j));
2537 else
2538 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002539 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002540 /* This stays in to prevent any internal failues from getting to the
2541 * user. Hopefully, this won't be needed. If a user reports getting
2542 * this, we have some debugging to do.
2543 */
2544 if (!res && !PyErr_Occurred())
2545 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2546
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002547 return (res);
2548
2549} /* validate_suite_tree() */
2550
2551
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002552/* Functions exported by this module. Most of this should probably
2553 * be converted into an AST object with methods, but that is better
2554 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002555 * We'd really have to write a wrapper around it all anyway to allow
2556 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002557 */
2558static PyMethodDef parser_functions[] = {
Guido van Rossum3d602e31996-07-21 02:33:56 +00002559 {"ast2tuple", parser_ast2tuple, 1,
2560 "Creates a tuple-tree representation of an AST."},
Guido van Rossum47478871996-08-21 14:32:37 +00002561 {"ast2list", parser_ast2list, 1,
2562 "Creates a list-tree representation of an AST."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002563 {"compileast", parser_compileast, 1,
2564 "Compiles an AST object into a code object."},
2565 {"expr", parser_expr, 1,
2566 "Creates an AST object from an expression."},
2567 {"isexpr", parser_isexpr, 1,
2568 "Determines if an AST object was created from an expression."},
2569 {"issuite", parser_issuite, 1,
2570 "Determines if an AST object was created from a suite."},
2571 {"suite", parser_suite, 1,
2572 "Creates an AST object from a suite."},
Guido van Rossum47478871996-08-21 14:32:37 +00002573 {"sequence2ast", parser_tuple2ast, 1,
2574 "Creates an AST object from a tree representation."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002575 {"tuple2ast", parser_tuple2ast, 1,
Guido van Rossum47478871996-08-21 14:32:37 +00002576 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002577
2578 {0, 0, 0}
2579 };
2580
2581
Guido van Rossum52f2c051993-11-10 12:53:24 +00002582void
Guido van Rossum3d602e31996-07-21 02:33:56 +00002583initparser()
2584 {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002585 PyObject* module = Py_InitModule("parser", parser_functions);
2586 PyObject* dict = PyModule_GetDict(module);
2587
2588 parser_error = PyString_FromString("parser.ParserError");
2589
2590 if ((parser_error == 0)
2591 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2592 /*
2593 * This is serious.
2594 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002595 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002596 }
2597 /*
2598 * Nice to have, but don't cry if we fail.
2599 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002600 Py_INCREF(&PyAST_Type);
2601 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2602
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002603 PyDict_SetItemString(dict, "__copyright__",
2604 PyString_FromString(parser_copyright_string));
2605 PyDict_SetItemString(dict, "__doc__",
2606 PyString_FromString(parser_doc_string));
2607 PyDict_SetItemString(dict, "__version__",
2608 PyString_FromString(parser_version_string));
2609
2610} /* initparser() */
2611
2612
2613/*
Guido van Rossum3d602e31996-07-21 02:33:56 +00002614 * end of parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002615 */