blob: 50c1defc4f80dbb904f3fb6a06d171c9b25b7527 [file] [log] [blame]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001/* parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002 *
Guido van Rossum47478871996-08-21 14:32:37 +00003 * Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic
4 * Institute and State University, Blacksburg, Virginia, USA.
5 * Portions copyright 1991-1995 by Stichting Mathematisch Centrum,
6 * Amsterdam, The Netherlands. Copying is permitted under the terms
7 * associated with the main Python distribution, with the additional
8 * restriction that this additional notice be included and maintained
9 * on all distributed copies.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000010 *
Guido van Rossum47478871996-08-21 14:32:37 +000011 * This module serves to replace the original parser module written
12 * by Guido. The functionality is not matched precisely, but the
13 * original may be implemented on top of this. This is desirable
14 * since the source of the text to be parsed is now divorced from
15 * this interface.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000016 *
Guido van Rossum47478871996-08-21 14:32:37 +000017 * Unlike the prior interface, the ability to give a parse tree
18 * produced by Python code as a tuple to the compiler is enabled by
19 * this module. See the documentation for more details.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000020 */
21
22#include "Python.h" /* general Python API */
23#include "graminit.h" /* symbols defined in the grammar */
24#include "node.h" /* internal parser structure */
25#include "token.h" /* token definitions */
26 /* ISTERMINAL() / ISNONTERMINAL() */
Guido van Rossum3d602e31996-07-21 02:33:56 +000027#include "compile.h" /* PyNode_Compile() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000028
29/*
30 * All the "fudge" declarations are here:
Guido van Rossum3d602e31996-07-21 02:33:56 +000031 *
32 * This isn't part of the Python runtime, but it's in the library somewhere.
Guido van Rossum2a288461996-08-21 21:55:43 +000033 * Where it is varies a bit, so just declare it. Don't use any prototype;
34 * different systems declare it a little differently, and we don't need the
35 * extra warnings.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000036 */
Guido van Rossum3d602e31996-07-21 02:33:56 +000037extern char* strdup();
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000038
39
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000040/* String constants used to initialize module attributes.
41 *
42 */
43static char*
44parser_copyright_string
Guido van Rossum2a288461996-08-21 21:55:43 +000045= "Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
46University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
47Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\
48Centrum, Amsterdam, The Netherlands.";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000049
50
51static char*
52parser_doc_string
53= "This is an interface to Python's internal parser.";
54
55static char*
Guido van Rossum47478871996-08-21 14:32:37 +000056parser_version_string = "0.4";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000057
58
Guido van Rossum2a288461996-08-21 21:55:43 +000059typedef PyObject* (*SeqMaker) Py_PROTO((int length));
60typedef void (*SeqInserter) Py_PROTO((PyObject* sequence,
61 int index,
62 PyObject* element));
Guido van Rossum47478871996-08-21 14:32:37 +000063
Guido van Rossum3d602e31996-07-21 02:33:56 +000064/* The function below is copyrigthed by Stichting Mathematisch Centrum. The
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000065 * original copyright statement is included below, and continues to apply
66 * in full to the function immediately following. All other material is
67 * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
68 * Institute and State University. Changes were made to comply with the
Guido van Rossum2a288461996-08-21 21:55:43 +000069 * new naming conventions. Added arguments to provide support for creating
70 * lists as well as tuples, and optionally including the line numbers.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000071 */
72
Guido van Rossum52f2c051993-11-10 12:53:24 +000073/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +000074Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
75The Netherlands.
Guido van Rossum52f2c051993-11-10 12:53:24 +000076
77 All Rights Reserved
78
Guido van Rossum3d602e31996-07-21 02:33:56 +000079Permission to use, copy, modify, and distribute this software and its
80documentation for any purpose and without fee is hereby granted,
Guido van Rossum52f2c051993-11-10 12:53:24 +000081provided that the above copyright notice appear in all copies and that
Guido van Rossum3d602e31996-07-21 02:33:56 +000082both that copyright notice and this permission notice appear in
Guido van Rossum52f2c051993-11-10 12:53:24 +000083supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000084Centrum or CWI or Corporation for National Research Initiatives or
85CNRI not be used in advertising or publicity pertaining to
86distribution of the software without specific, written prior
87permission.
Guido van Rossum52f2c051993-11-10 12:53:24 +000088
Guido van Rossumd266eb41996-10-25 14:44:06 +000089While CWI is the initial source for this software, a modified version
90is made available by the Corporation for National Research Initiatives
91(CNRI) at the Internet address ftp://ftp.python.org.
92
93STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
94REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
95MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
96CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
97DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
98PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
99TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
100PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum52f2c051993-11-10 12:53:24 +0000101
102******************************************************************/
103
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000104static PyObject*
Guido van Rossum47478871996-08-21 14:32:37 +0000105node2tuple(n, mkseq, addelem, lineno)
106 node *n; /* node to convert */
107 SeqMaker mkseq; /* create sequence */
108 SeqInserter addelem; /* func. to add elem. in seq. */
109 int lineno; /* include line numbers? */
110{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000111 if (n == NULL) {
112 Py_INCREF(Py_None);
113 return Py_None;
114 }
115 if (ISNONTERMINAL(TYPE(n))) {
116 int i;
117 PyObject *v, *w;
Guido van Rossum47478871996-08-21 14:32:37 +0000118 v = mkseq(1 + NCH(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000119 if (v == NULL)
120 return v;
121 w = PyInt_FromLong(TYPE(n));
122 if (w == NULL) {
123 Py_DECREF(v);
124 return NULL;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000125 }
Guido van Rossum47478871996-08-21 14:32:37 +0000126 addelem(v, 0, w);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000127 for (i = 0; i < NCH(n); i++) {
Guido van Rossum47478871996-08-21 14:32:37 +0000128 w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000129 if (w == NULL) {
130 Py_DECREF(v);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000131 return NULL;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000132 }
Guido van Rossum47478871996-08-21 14:32:37 +0000133 addelem(v, i+1, w);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000134 }
Guido van Rossum47478871996-08-21 14:32:37 +0000135 return (v);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000136 }
137 else if (ISTERMINAL(TYPE(n))) {
Guido van Rossum47478871996-08-21 14:32:37 +0000138 PyObject *result = mkseq(2 + lineno);
139 if (result != NULL) {
140 addelem(result, 0, PyInt_FromLong(TYPE(n)));
141 addelem(result, 1, PyString_FromString(STR(n)));
142 if (lineno == 1)
143 addelem(result, 2, PyInt_FromLong(n->n_lineno));
144 }
145 return (result);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000146 }
147 else {
148 PyErr_SetString(PyExc_SystemError,
149 "unrecognized parse tree node type");
150 return NULL;
151 }
Guido van Rossum47478871996-08-21 14:32:37 +0000152} /* node2tuple() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000153/*
154 * End of material copyrighted by Stichting Mathematisch Centrum.
155 */
Guido van Rossum52f2c051993-11-10 12:53:24 +0000156
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000157
158
159/* There are two types of intermediate objects we're interested in:
160 * 'eval' and 'exec' types. These constants can be used in the ast_type
161 * field of the object type to identify which any given object represents.
162 * These should probably go in an external header to allow other extensions
163 * to use them, but then, we really should be using C++ too. ;-)
164 *
Guido van Rossum3d602e31996-07-21 02:33:56 +0000165 * The PyAST_FRAGMENT type is not currently supported. Maybe not useful?
166 * Haven't decided yet.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000167 */
168
169#define PyAST_EXPR 1
170#define PyAST_SUITE 2
171#define PyAST_FRAGMENT 3
172
173
174/* These are the internal objects and definitions required to implement the
175 * AST type. Most of the internal names are more reminiscent of the 'old'
176 * naming style, but the code uses the new naming convention.
177 */
178
179static PyObject*
180parser_error = 0;
181
182
183typedef struct _PyAST_Object {
184
185 PyObject_HEAD /* standard object header */
186 node* ast_node; /* the node* returned by the parser */
187 int ast_type; /* EXPR or SUITE ? */
188
189} PyAST_Object;
190
191
Guido van Rossum2a288461996-08-21 21:55:43 +0000192staticforward void parser_free Py_PROTO((PyAST_Object *ast));
193staticforward int parser_compare Py_PROTO((PyAST_Object *left,
194 PyAST_Object *right));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000195
196
197/* static */
198PyTypeObject PyAST_Type = {
199
Guido van Rossumf2b2dac1997-01-23 23:29:44 +0000200 PyObject_HEAD_INIT(NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000201 0,
202 "ast", /* tp_name */
203 sizeof(PyAST_Object), /* tp_basicsize */
204 0, /* tp_itemsize */
205 (destructor)parser_free, /* tp_dealloc */
206 0, /* tp_print */
207 0, /* tp_getattr */
208 0, /* tp_setattr */
209 (cmpfunc)parser_compare, /* tp_compare */
210 0, /* tp_repr */
211 0, /* tp_as_number */
212 0, /* tp_as_sequence */
213 0, /* tp_as_mapping */
214 0, /* tp_hash */
215 0, /* tp_call */
Fred Drake69b9ae41997-05-23 04:04:17 +0000216 0, /* tp_str */
217 0, /* tp_getattro */
218 0, /* tp_setattro */
219
220 /* Functions to access object as input/output buffer */
221 0, /* tp_as_buffer */
222
223 /* Space for future expansion */
224 0, /* tp_xxx4 */
225
226 /* __doc__ */
227 "Intermediate representation of a Python parse tree."
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000228
229}; /* PyAST_Type */
230
231
232static int
233parser_compare_nodes(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000234 node *left;
235 node *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000236{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000237 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000238
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000239 if (TYPE(left) < TYPE(right))
240 return (-1);
241
242 if (TYPE(right) < TYPE(left))
243 return (1);
244
245 if (ISTERMINAL(TYPE(left)))
246 return (strcmp(STR(left), STR(right)));
247
248 if (NCH(left) < NCH(right))
249 return (-1);
250
251 if (NCH(right) < NCH(left))
252 return (1);
253
254 for (j = 0; j < NCH(left); ++j) {
255 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
256
257 if (v)
258 return (v);
259 }
260 return (0);
261
262} /* parser_compare_nodes() */
263
264
265/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
266 *
267 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
268 * This really just wraps a call to parser_compare_nodes() with some easy
269 * checks and protection code.
270 *
271 */
272static int
273parser_compare(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000274 PyAST_Object *left;
275 PyAST_Object *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000276{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000277 if (left == right)
278 return (0);
279
280 if ((left == 0) || (right == 0))
281 return (-1);
282
283 return (parser_compare_nodes(left->ast_node, right->ast_node));
284
285} /* parser_compare() */
286
287
288/* parser_newastobject(node* ast)
289 *
290 * Allocates a new Python object representing an AST. This is simply the
291 * 'wrapper' object that holds a node* and allows it to be passed around in
292 * Python code.
293 *
294 */
295static PyObject*
296parser_newastobject(ast, type)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000297 node *ast;
298 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000299{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000300 PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
301
302 if (o != 0) {
303 o->ast_node = ast;
304 o->ast_type = type;
305 }
306 return ((PyObject*)o);
307
308} /* parser_newastobject() */
309
310
311/* void parser_free(PyAST_Object* ast)
312 *
313 * This is called by a del statement that reduces the reference count to 0.
314 *
315 */
316static void
317parser_free(ast)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000318 PyAST_Object *ast;
Guido van Rossum47478871996-08-21 14:32:37 +0000319{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000320 PyNode_Free(ast->ast_node);
321 PyMem_DEL(ast);
322
323} /* parser_free() */
324
325
326/* parser_ast2tuple(PyObject* self, PyObject* args)
327 *
328 * This provides conversion from a node* to a tuple object that can be
329 * returned to the Python-level caller. The AST object is not modified.
330 *
331 */
332static PyObject*
333parser_ast2tuple(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000334 PyObject *self;
335 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000336{
337 PyObject *ast;
338 PyObject *line_option = 0;
339 PyObject *res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000340
Guido van Rossum47478871996-08-21 14:32:37 +0000341 if (PyArg_ParseTuple(args, "O!|O:ast2tuple", &PyAST_Type, &ast,
342 &line_option)) {
343 int lineno = 0;
344 if (line_option != 0) {
345 lineno = PyObject_IsTrue(line_option);
346 lineno = lineno ? 1 : 0;
347 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000348 /*
349 * Convert AST into a tuple representation. Use Guido's function,
350 * since it's known to work already.
351 */
Guido van Rossum47478871996-08-21 14:32:37 +0000352 res = node2tuple(((PyAST_Object*)ast)->ast_node,
353 PyTuple_New, PyTuple_SetItem, lineno);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000354 }
355 return (res);
356
357} /* parser_ast2tuple() */
358
359
Guido van Rossum47478871996-08-21 14:32:37 +0000360/* parser_ast2tuple(PyObject* self, PyObject* args)
361 *
362 * This provides conversion from a node* to a tuple object that can be
363 * returned to the Python-level caller. The AST object is not modified.
364 *
365 */
366static PyObject*
367parser_ast2list(self, args)
368 PyObject *self;
369 PyObject *args;
370{
371 PyObject *ast;
372 PyObject *line_option = 0;
373 PyObject *res = 0;
374
375 if (PyArg_ParseTuple(args, "O!|O:ast2list", &PyAST_Type, &ast,
376 &line_option)) {
377 int lineno = 0;
378 if (line_option != 0) {
379 lineno = PyObject_IsTrue(line_option);
380 lineno = lineno ? 1 : 0;
381 }
382 /*
383 * Convert AST into a tuple representation. Use Guido's function,
384 * since it's known to work already.
385 */
386 res = node2tuple(((PyAST_Object*)ast)->ast_node,
387 PyList_New, PyList_SetItem, lineno);
388 }
389 return (res);
390
391} /* parser_ast2list() */
392
393
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000394/* parser_compileast(PyObject* self, PyObject* args)
395 *
396 * This function creates code objects from the parse tree represented by
397 * the passed-in data object. An optional file name is passed in as well.
398 *
399 */
400static PyObject*
401parser_compileast(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 char* str = "<ast>";
408
409 if (PyArg_ParseTuple(args, "O!|s", &PyAST_Type, &ast, &str))
Guido van Rossum3d602e31996-07-21 02:33:56 +0000410 res = (PyObject*) PyNode_Compile(ast->ast_node, str);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000411
412 return (res);
413
414} /* parser_compileast() */
415
416
417/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
418 * PyObject* parser_issuite(PyObject* self, PyObject* args)
419 *
420 * Checks the passed-in AST object to determine if it is an expression or
421 * a statement suite, respectively. The return is a Python truth value.
422 *
423 */
424static PyObject*
425parser_isexpr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000426 PyObject *self;
427 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000428{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000429 PyAST_Object* ast;
430 PyObject* res = 0;
431
432 if (PyArg_ParseTuple(args, "O!:isexpr", &PyAST_Type, &ast)) {
433 /*
434 * Check to see if the AST represents an expression or not.
435 */
436 res = (ast->ast_type == PyAST_EXPR) ? Py_True : Py_False;
437 Py_INCREF(res);
438 }
439 return (res);
440
441} /* parser_isexpr() */
442
443
444static PyObject*
445parser_issuite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000446 PyObject *self;
447 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000448{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000449 PyAST_Object* ast;
450 PyObject* res = 0;
451
Guido van Rossum3d602e31996-07-21 02:33:56 +0000452 if (PyArg_ParseTuple(args, "O!:issuite", &PyAST_Type, &ast)) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000453 /*
454 * Check to see if the AST represents an expression or not.
455 */
456 res = (ast->ast_type == PyAST_EXPR) ? Py_False : Py_True;
457 Py_INCREF(res);
458 }
459 return (res);
460
461} /* parser_issuite() */
462
463
Guido van Rossum3d602e31996-07-21 02:33:56 +0000464/* err_string(char* message)
465 *
466 * Sets the error string for an exception of type ParserError.
467 *
468 */
469static void
470err_string(message)
471 char *message;
Guido van Rossum47478871996-08-21 14:32:37 +0000472{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000473 PyErr_SetString(parser_error, message);
474
475} /* err_string() */
476
477
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000478/* PyObject* parser_do_parse(PyObject* args, int type)
479 *
480 * Internal function to actually execute the parse and return the result if
481 * successful, or set an exception if not.
482 *
483 */
484static PyObject*
485parser_do_parse(args, type)
486 PyObject *args;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000487 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000488{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000489 char* string = 0;
490 PyObject* res = 0;
491
492 if (PyArg_ParseTuple(args, "s", &string)) {
493 node* n = PyParser_SimpleParseString(string,
494 (type == PyAST_EXPR)
495 ? eval_input : file_input);
496
497 if (n != 0)
498 res = parser_newastobject(n, type);
499 else
Guido van Rossum3d602e31996-07-21 02:33:56 +0000500 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000501 }
502 return (res);
503
504} /* parser_do_parse() */
505
506
507/* PyObject* parser_expr(PyObject* self, PyObject* args)
508 * PyObject* parser_suite(PyObject* self, PyObject* args)
509 *
510 * External interfaces to the parser itself. Which is called determines if
511 * the parser attempts to recognize an expression ('eval' form) or statement
512 * suite ('exec' form). The real work is done by parser_do_parse() above.
513 *
514 */
515static PyObject*
516parser_expr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000517 PyObject *self;
518 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000519{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000520 return (parser_do_parse(args, PyAST_EXPR));
521
522} /* parser_expr() */
523
524
525static PyObject*
526parser_suite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000527 PyObject *self;
528 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000529{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000530 return (parser_do_parse(args, PyAST_SUITE));
531
532} /* parser_suite() */
533
534
535
536/* This is the messy part of the code. Conversion from a tuple to an AST
537 * object requires that the input tuple be valid without having to rely on
538 * catching an exception from the compiler. This is done to allow the
539 * compiler itself to remain fast, since most of its input will come from
540 * the parser directly, and therefore be known to be syntactically correct.
541 * This validation is done to ensure that we don't core dump the compile
542 * phase, returning an exception instead.
543 *
544 * Two aspects can be broken out in this code: creating a node tree from
545 * the tuple passed in, and verifying that it is indeed valid. It may be
546 * advantageous to expand the number of AST types to include funcdefs and
547 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
548 * here. They are not necessary, and not quite as useful in a raw form.
549 * For now, let's get expressions and suites working reliably.
550 */
551
552
Guido van Rossum2a288461996-08-21 21:55:43 +0000553staticforward node* build_node_tree Py_PROTO((PyObject *tuple));
554staticforward int validate_expr_tree Py_PROTO((node *tree));
555staticforward int validate_file_input Py_PROTO((node *tree));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000556
557
558/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
559 *
560 * This is the public function, called from the Python code. It receives a
561 * single tuple object from the caller, and creates an AST object if the
562 * tuple can be validated. It does this by checking the first code of the
563 * tuple, and, if acceptable, builds the internal representation. If this
564 * step succeeds, the internal representation is validated as fully as
565 * possible with the various validate_*() routines defined below.
566 *
567 * This function must be changed if support is to be added for PyAST_FRAGMENT
568 * AST objects.
569 *
570 */
571static PyObject*
572parser_tuple2ast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000573 PyObject *self;
574 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000575{
576 PyObject *ast = 0;
577 PyObject *tuple = 0;
578 PyObject *temp = 0;
579 int ok;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000580 int start_sym = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000581
Guido van Rossum47478871996-08-21 14:32:37 +0000582 if (!PyArg_ParseTuple(args, "O:tuple2ast", &tuple))
583 return (0);
584 if (!PySequence_Check(tuple)) {
585 PyErr_SetString(PyExc_ValueError,
586 "tuple2ast() requires a single sequence argument");
587 return (0);
588 }
589 /*
590 * This mess of tests is written this way so we can use the abstract
591 * object interface (AOI). Unfortunately, the AOI increments reference
592 * counts, which requires that we store a pointer to retrieved object
593 * so we can DECREF it after the check. But we really should accept
594 * lists as well as tuples at the very least.
595 */
596 ok = PyObject_Length(tuple) >= 2;
597 if (ok) {
598 temp = PySequence_GetItem(tuple, 0);
599 ok = (temp != NULL) && PyInt_Check(temp);
600 if (ok)
601 /* this is used after the initial checks: */
602 start_sym = PyInt_AsLong(temp);
603 Py_XDECREF(temp);
604 }
605 if (ok) {
606 temp = PySequence_GetItem(tuple, 1);
607 ok = (temp != NULL) && PySequence_Check(temp);
608 Py_XDECREF(temp);
609 }
610 if (ok) {
611 temp = PySequence_GetItem(tuple, 1);
612 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
613 if (ok) {
614 PyObject *temp2 = PySequence_GetItem(temp, 0);
615 if (temp2 != NULL) {
616 ok = PyInt_Check(temp2);
617 Py_DECREF(temp2);
618 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000619 }
Guido van Rossum47478871996-08-21 14:32:37 +0000620 Py_XDECREF(temp);
621 }
622 /* If we've failed at some point, get out of here. */
623 if (!ok) {
624 err_string("malformed sequence for tuple2ast()");
625 return (0);
626 }
627 /*
628 * This might be a valid parse tree, but let's do a quick check
629 * before we jump the gun.
630 */
631 if (start_sym == eval_input) {
632 /* Might be an eval form. */
633 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000634
Guido van Rossum47478871996-08-21 14:32:37 +0000635 if ((expression != 0) && validate_expr_tree(expression))
636 ast = parser_newastobject(expression, PyAST_EXPR);
637 }
638 else if (start_sym == file_input) {
639 /* This looks like an exec form so far. */
640 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000641
Guido van Rossum47478871996-08-21 14:32:37 +0000642 if ((suite_tree != 0) && validate_file_input(suite_tree))
643 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000644 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000645 else
Guido van Rossum47478871996-08-21 14:32:37 +0000646 /* This is a fragment, and is not yet supported. Maybe they
647 * will be if I find a use for them.
648 */
649 err_string("Fragmentary parse trees not supported.");
650
651 /* Make sure we throw an exception on all errors. We should never
652 * get this, but we'd do well to be sure something is done.
653 */
654 if ((ast == 0) && !PyErr_Occurred())
655 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000656
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000657 return (ast);
658
659} /* parser_tuple2ast() */
660
661
662/* int check_terminal_tuple()
663 *
Guido van Rossum47478871996-08-21 14:32:37 +0000664 * Check a tuple to determine that it is indeed a valid terminal
665 * node. The node is known to be required as a terminal, so we throw
666 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000667 *
Guido van Rossum47478871996-08-21 14:32:37 +0000668 * The format of an acceptable terminal tuple is "(is[i])": the fact
669 * that elem is a tuple and the integer is a valid terminal symbol
670 * has been established before this function is called. We must
671 * check the length of the tuple and the type of the second element
672 * and optional third element. We do *NOT* check the actual text of
673 * the string element, which we could do in many cases. This is done
674 * by the validate_*() functions which operate on the internal
675 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000676 */
677static int
Guido van Rossum47478871996-08-21 14:32:37 +0000678check_terminal_tuple(elem)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000679 PyObject *elem;
Guido van Rossum47478871996-08-21 14:32:37 +0000680{
681 int len = PyObject_Length(elem);
682 int res = 1;
683 char* str = "Illegal terminal symbol; bad node length.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000684
Guido van Rossum47478871996-08-21 14:32:37 +0000685 if ((len == 2) || (len == 3)) {
686 PyObject *temp = PySequence_GetItem(elem, 1);
687 res = PyString_Check(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000688 str = "Illegal terminal symbol; expected a string.";
Guido van Rossum47478871996-08-21 14:32:37 +0000689 if (res && (len == 3)) {
690 PyObject* third = PySequence_GetItem(elem, 2);
691 res = PyInt_Check(third);
692 str = "Invalid third element of terminal node.";
693 Py_XDECREF(third);
694 }
695 Py_XDECREF(temp);
696 }
697 else {
698 res = 0;
699 }
700 if (!res) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000701 elem = Py_BuildValue("(os)", elem, str);
702 PyErr_SetObject(parser_error, elem);
703 }
704 return (res);
705
706} /* check_terminal_tuple() */
707
708
709/* node* build_node_children()
710 *
711 * Iterate across the children of the current non-terminal node and build
712 * their structures. If successful, return the root of this portion of
713 * the tree, otherwise, 0. Any required exception will be specified already,
714 * and no memory will have been deallocated.
715 *
716 */
717static node*
718build_node_children(tuple, root, line_num)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000719 PyObject *tuple;
720 node *root;
721 int *line_num;
Guido van Rossum47478871996-08-21 14:32:37 +0000722{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000723 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000724 int i;
725
726 for (i = 1; i < len; ++i) {
727 /* elem must always be a tuple, however simple */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000728 PyObject* elem = PySequence_GetItem(tuple, i);
Guido van Rossum47478871996-08-21 14:32:37 +0000729 int ok = elem != NULL;
730 long type = 0;
731 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000732
Guido van Rossum47478871996-08-21 14:32:37 +0000733 if (ok)
734 ok = PySequence_Check(elem);
735 if (ok) {
736 PyObject *temp = PySequence_GetItem(elem, 0);
737 if (temp == NULL)
738 ok = 0;
739 else {
740 ok = PyInt_Check(temp);
741 if (ok)
742 type = PyInt_AsLong(temp);
743 Py_DECREF(temp);
744 }
745 }
746 if (!ok) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000747 PyErr_SetObject(parser_error,
748 Py_BuildValue("(os)", elem,
749 "Illegal node construct."));
Guido van Rossum47478871996-08-21 14:32:37 +0000750 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000751 return (0);
752 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000753 if (ISTERMINAL(type)) {
Guido van Rossum47478871996-08-21 14:32:37 +0000754 if (check_terminal_tuple(elem)) {
755 PyObject *temp = PySequence_GetItem(elem, 1);
756
757 strn = strdup(PyString_AsString(temp));
758 Py_XDECREF(temp);
759
760 if (PyObject_Length(elem) == 3) {
761 PyObject* temp = PySequence_GetItem(elem, 2);
762 *line_num = PyInt_AsLong(temp);
763 Py_DECREF(temp);
764 }
765 }
766 else {
767 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000768 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000769 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000770 }
771 else if (!ISNONTERMINAL(type)) {
772 /*
773 * It has to be one or the other; this is an error.
774 * Throw an exception.
775 */
776 PyErr_SetObject(parser_error,
777 Py_BuildValue("(os)", elem,
778 "Unknown node type."));
Guido van Rossum47478871996-08-21 14:32:37 +0000779 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000780 return (0);
781 }
782 PyNode_AddChild(root, type, strn, *line_num);
783
784 if (ISNONTERMINAL(type)) {
785 node* new_child = CHILD(root, i - 1);
786
Guido van Rossum47478871996-08-21 14:32:37 +0000787 if (new_child != build_node_children(elem, new_child, line_num)) {
788 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000789 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000790 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000791 }
Guido van Rossum47478871996-08-21 14:32:37 +0000792 else if (type == NEWLINE) { /* It's true: we increment the */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000793 ++(*line_num); /* line number *after* the newline! */
Guido van Rossum47478871996-08-21 14:32:37 +0000794 }
795 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000796 }
797 return (root);
798
799} /* build_node_children() */
800
801
802static node*
803build_node_tree(tuple)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000804 PyObject *tuple;
Guido van Rossum47478871996-08-21 14:32:37 +0000805{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000806 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000807 PyObject *temp = PySequence_GetItem(tuple, 0);
808 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000809
Guido van Rossum47478871996-08-21 14:32:37 +0000810 if (temp != NULL)
811 num = PyInt_AsLong(temp);
812 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000813 if (ISTERMINAL(num)) {
814 /*
815 * The tuple is simple, but it doesn't start with a start symbol.
816 * Throw an exception now and be done with it.
817 */
818 tuple = Py_BuildValue("(os)", tuple,
Guido van Rossum3d602e31996-07-21 02:33:56 +0000819 "Illegal ast tuple; cannot start with terminal symbol.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000820 PyErr_SetObject(parser_error, tuple);
821 }
822 else if (ISNONTERMINAL(num)) {
823 /*
824 * Not efficient, but that can be handled later.
825 */
826 int line_num = 0;
827
828 res = PyNode_New(num);
829 if (res != build_node_children(tuple, res, &line_num)) {
830 PyNode_Free(res);
831 res = 0;
832 }
833 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000834 else
835 /* The tuple is illegal -- if the number is neither TERMINAL nor
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000836 * NONTERMINAL, we can't use it.
837 */
838 PyErr_SetObject(parser_error,
839 Py_BuildValue("(os)", tuple,
840 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000841
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000842 return (res);
843
844} /* build_node_tree() */
845
846
Guido van Rossum360a9341996-08-21 19:04:10 +0000847#ifdef HAVE_OLD_CPP
Guido van Rossum2a288461996-08-21 21:55:43 +0000848#define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000849#else
Guido van Rossum2a288461996-08-21 21:55:43 +0000850#define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000851#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000852
853
854/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000855 * Validation routines used within the validation section:
856 */
Guido van Rossum2a288461996-08-21 21:55:43 +0000857staticforward int validate_terminal Py_PROTO((node *terminal,
858 int type, char *string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000859
860#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
861#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
862#define validate_colon(ch) validate_terminal(ch, COLON, ":")
863#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
864#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
865#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000866#define validate_indent(ch) validate_terminal(ch, INDENT, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000867#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000868#define validate_newline(ch) validate_terminal(ch, NEWLINE, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000869#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
870#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
871#define validate_star(ch) validate_terminal(ch, STAR, "*")
872#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000873#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
Guido van Rossum47478871996-08-21 14:32:37 +0000874#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000875#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000876
Guido van Rossum3d602e31996-07-21 02:33:56 +0000877VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000878VALIDATER(class); VALIDATER(node);
879VALIDATER(parameters); VALIDATER(suite);
880VALIDATER(testlist); VALIDATER(varargslist);
881VALIDATER(fpdef); VALIDATER(fplist);
882VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000883VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000884VALIDATER(print_stmt); VALIDATER(del_stmt);
885VALIDATER(return_stmt);
886VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000887VALIDATER(global_stmt);
Guido van Rossum925e5471997-04-02 05:32:13 +0000888VALIDATER(assert_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000889VALIDATER(exec_stmt); VALIDATER(compound_stmt);
890VALIDATER(while); VALIDATER(for);
891VALIDATER(try); VALIDATER(except_clause);
892VALIDATER(test); VALIDATER(and_test);
893VALIDATER(not_test); VALIDATER(comparison);
894VALIDATER(comp_op); VALIDATER(expr);
895VALIDATER(xor_expr); VALIDATER(and_expr);
896VALIDATER(shift_expr); VALIDATER(arith_expr);
897VALIDATER(term); VALIDATER(factor);
898VALIDATER(atom); VALIDATER(lambdef);
899VALIDATER(trailer); VALIDATER(subscript);
Guido van Rossum47478871996-08-21 14:32:37 +0000900VALIDATER(subscriptlist); VALIDATER(sliceop);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000901VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000902VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000903
904
905#define is_even(n) (((n) & 1) == 0)
906#define is_odd(n) (((n) & 1) == 1)
907
908
909static int
910validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000911 node *n;
912 int t;
Guido van Rossum47478871996-08-21 14:32:37 +0000913{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000914 int res = (TYPE(n) == t);
915
916 if (!res) {
917 char buffer[128];
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000918 sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000919 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000920 }
921 return (res);
922
923} /* validate_ntype() */
924
925
926static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000927validate_numnodes(n, num, name)
928 node *n;
929 int num;
930 const char *const name;
Guido van Rossum47478871996-08-21 14:32:37 +0000931{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000932 if (NCH(n) != num) {
933 char buff[60];
934 sprintf(buff, "Illegal number of children for %s node.", name);
935 err_string(buff);
936 }
937 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000938
Guido van Rossum3d602e31996-07-21 02:33:56 +0000939} /* validate_numnodes() */
940
941
942static int
943validate_terminal(terminal, type, string)
944 node *terminal;
945 int type;
946 char *string;
Guido van Rossum47478871996-08-21 14:32:37 +0000947{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000948 int res = (validate_ntype(terminal, type)
949 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
950
951 if (!res && !PyErr_Occurred()) {
952 char buffer[60];
953 sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
954 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000955 }
956 return (res);
957
958} /* validate_terminal() */
959
960
Guido van Rossum47478871996-08-21 14:32:37 +0000961/* X (',' X) [',']
962 */
963static int
964validate_repeating_list(tree, ntype, vfunc, name)
965 node *tree;
966 int ntype;
967 int (*vfunc)();
968 const char *const name;
969{
970 int nch = NCH(tree);
971 int res = (nch && validate_ntype(tree, ntype)
972 && vfunc(CHILD(tree, 0)));
973
974 if (!res && !PyErr_Occurred())
975 validate_numnodes(tree, 1, name);
976 else {
977 if (is_even(nch))
978 res = validate_comma(CHILD(tree, --nch));
979 if (res && nch > 1) {
980 int pos = 1;
981 for ( ; res && pos < nch; pos += 2)
982 res = (validate_comma(CHILD(tree, pos))
983 && vfunc(CHILD(tree, pos + 1)));
984 }
985 }
986 return (res);
987
988} /* validate_repeating_list() */
989
990
Guido van Rossum3d602e31996-07-21 02:33:56 +0000991/* VALIDATE(class)
992 *
993 * classdef:
994 * 'class' NAME ['(' testlist ')'] ':' suite
995 */
Guido van Rossum47478871996-08-21 14:32:37 +0000996static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000997validate_class(tree)
998 node *tree;
999{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001000 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001001 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001002
Guido van Rossum3d602e31996-07-21 02:33:56 +00001003 if (res) {
1004 res = (validate_name(CHILD(tree, 0), "class")
1005 && validate_ntype(CHILD(tree, 1), NAME)
1006 && validate_colon(CHILD(tree, nch - 2))
1007 && validate_suite(CHILD(tree, nch - 1)));
1008 }
1009 else
1010 validate_numnodes(tree, 4, "class");
1011 if (res && (nch == 7)) {
1012 res = (validate_lparen(CHILD(tree, 2))
1013 && validate_testlist(CHILD(tree, 3))
1014 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001015 }
1016 return (res);
1017
1018} /* validate_class() */
1019
1020
Guido van Rossum3d602e31996-07-21 02:33:56 +00001021/* if_stmt:
1022 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1023 */
Guido van Rossum47478871996-08-21 14:32:37 +00001024static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001025validate_if(tree)
1026 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001027{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001028 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001029 int res = (validate_ntype(tree, if_stmt)
1030 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001031 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +00001032 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001033 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001034 && validate_suite(CHILD(tree, 3)));
1035
1036 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001037 /* ... 'else' ':' suite */
1038 res = (validate_name(CHILD(tree, nch - 3), "else")
1039 && validate_colon(CHILD(tree, nch - 2))
1040 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001041 nch -= 3;
1042 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001043 else if (!res && !PyErr_Occurred())
1044 validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001045 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001046 /* Will catch the case for nch < 4 */
1047 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001048 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001049 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001050 int j = 4;
1051 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001052 res = (validate_name(CHILD(tree, j), "elif")
1053 && validate_colon(CHILD(tree, j + 2))
1054 && validate_test(CHILD(tree, j + 1))
1055 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001056 j += 4;
1057 }
1058 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001059 return (res);
1060
1061} /* validate_if() */
1062
1063
Guido van Rossum3d602e31996-07-21 02:33:56 +00001064/* parameters:
1065 * '(' [varargslist] ')'
1066 *
1067 */
Guido van Rossum47478871996-08-21 14:32:37 +00001068static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001069validate_parameters(tree)
1070 node *tree;
1071{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001072 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001073 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001074
Guido van Rossum3d602e31996-07-21 02:33:56 +00001075 if (res) {
1076 res = (validate_lparen(CHILD(tree, 0))
1077 && validate_rparen(CHILD(tree, nch - 1)));
1078 if (res && (nch == 3))
1079 res = validate_varargslist(CHILD(tree, 1));
1080 }
1081 else
1082 validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001083
1084 return (res);
1085
1086} /* validate_parameters() */
1087
1088
Guido van Rossum3d602e31996-07-21 02:33:56 +00001089/* VALIDATE(suite)
1090 *
1091 * suite:
1092 * simple_stmt
1093 * | NEWLINE INDENT stmt+ DEDENT
1094 */
Guido van Rossum47478871996-08-21 14:32:37 +00001095static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001096validate_suite(tree)
1097 node *tree;
1098{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001099 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001100 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001101
Guido van Rossum3d602e31996-07-21 02:33:56 +00001102 if (res && (nch == 1))
1103 res = validate_simple_stmt(CHILD(tree, 0));
1104 else if (res) {
1105 /* NEWLINE INDENT stmt+ DEDENT */
1106 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001107 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001108 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001109 && validate_dedent(CHILD(tree, nch - 1)));
1110
Guido van Rossum3d602e31996-07-21 02:33:56 +00001111 if (res && (nch > 4)) {
1112 int i = 3;
1113 --nch; /* forget the DEDENT */
1114 for ( ; res && (i < nch); ++i)
1115 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001116 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001117 else if (nch < 4)
1118 validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001119 }
1120 return (res);
1121
1122} /* validate_suite() */
1123
1124
Guido van Rossum47478871996-08-21 14:32:37 +00001125static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001126validate_testlist(tree)
1127 node *tree;
1128{
Guido van Rossum47478871996-08-21 14:32:37 +00001129 return (validate_repeating_list(tree, testlist,
1130 validate_test, "testlist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001131
1132} /* validate_testlist() */
1133
1134
Guido van Rossum3d602e31996-07-21 02:33:56 +00001135/* VALIDATE(varargslist)
1136 *
1137 * varargslist:
1138 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1139 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1140 *
1141 * (fpdef ['=' test] ',')*
1142 * ('*' NAME [',' ('**'|'*' '*') NAME]
1143 * | ('**'|'*' '*') NAME)
1144 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1145 *
1146 */
Guido van Rossum47478871996-08-21 14:32:37 +00001147static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001148validate_varargslist(tree)
1149 node *tree;
1150{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001151 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001152 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001153
Guido van Rossum3d602e31996-07-21 02:33:56 +00001154 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1155 /* (fpdef ['=' test] ',')*
1156 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1157 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001158 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001159 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001160
Guido van Rossum3d602e31996-07-21 02:33:56 +00001161 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1162 res = validate_fpdef(CHILD(tree, pos));
1163 if (res) {
1164 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1165 res = validate_test(CHILD(tree, pos + 2));
1166 pos += 2;
1167 }
1168 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001169 pos += 2;
1170 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001171 }
1172 if (res) {
1173 remaining = nch - pos;
1174 res = ((remaining == 2) || (remaining == 3)
1175 || (remaining == 5) || (remaining == 6));
1176 if (!res)
1177 validate_numnodes(tree, 2, "varargslist");
1178 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1179 return ((remaining == 2)
1180 && validate_ntype(CHILD(tree, pos+1), NAME));
1181 else {
1182 res = validate_star(CHILD(tree, pos++));
1183 --remaining;
1184 }
1185 }
1186 if (res) {
1187 if (remaining == 2) {
1188 res = (validate_star(CHILD(tree, pos))
1189 && validate_ntype(CHILD(tree, pos + 1), NAME));
1190 }
1191 else {
1192 res = validate_ntype(CHILD(tree, pos++), NAME);
1193 if (res && (remaining >= 4)) {
1194 res = validate_comma(CHILD(tree, pos));
1195 if (--remaining == 3)
Fred Drakee1607a81996-09-11 21:58:26 +00001196 res = (validate_star(CHILD(tree, pos + 1))
1197 && validate_star(CHILD(tree, pos + 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001198 else
1199 validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1200 }
1201 }
1202 }
1203 if (!res && !PyErr_Occurred())
1204 err_string("Incorrect validation of variable arguments list.");
1205 }
1206 else if (res) {
1207 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1208 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1209 --nch;
1210
1211 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1212 res = (is_odd(nch)
1213 && validate_fpdef(CHILD(tree, 0)));
1214
1215 if (res && (nch > 1)) {
1216 int pos = 1;
1217 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1218 res = validate_test(CHILD(tree, 2));
1219 pos += 2;
1220 }
1221 /* ... (',' fpdef ['=' test])* */
1222 for ( ; res && (pos < nch); pos += 2) {
1223 /* ',' fpdef */
1224 res = (validate_comma(CHILD(tree, pos))
1225 && validate_fpdef(CHILD(tree, pos + 1)));
1226 if (res
1227 && ((nch - pos) > 2)
1228 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1229 /* ['=' test] */
1230 res = validate_test(CHILD(tree, pos + 3));
1231 pos += 2;
1232 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001233 }
1234 }
1235 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001236 else
1237 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001238
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001239 return (res);
1240
1241} /* validate_varargslist() */
1242
1243
Guido van Rossum3d602e31996-07-21 02:33:56 +00001244/* VALIDATE(fpdef)
1245 *
1246 * fpdef:
1247 * NAME
1248 * | '(' fplist ')'
1249 */
Guido van Rossum47478871996-08-21 14:32:37 +00001250static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001251validate_fpdef(tree)
1252 node *tree;
1253{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001254 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001255 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001256
Guido van Rossum3d602e31996-07-21 02:33:56 +00001257 if (res) {
1258 if (nch == 1)
1259 res = validate_ntype(CHILD(tree, 0), NAME);
1260 else if (nch == 3)
1261 res = (validate_lparen(CHILD(tree, 0))
1262 && validate_fplist(CHILD(tree, 1))
1263 && validate_rparen(CHILD(tree, 2)));
1264 else
1265 validate_numnodes(tree, 1, "fpdef");
1266 }
1267 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001268
1269} /* validate_fpdef() */
1270
1271
Guido van Rossum47478871996-08-21 14:32:37 +00001272static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001273validate_fplist(tree)
1274 node *tree;
1275{
Guido van Rossum47478871996-08-21 14:32:37 +00001276 return (validate_repeating_list(tree, fplist,
1277 validate_fpdef, "fplist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001278
1279} /* validate_fplist() */
1280
1281
Guido van Rossum3d602e31996-07-21 02:33:56 +00001282/* simple_stmt | compound_stmt
1283 *
1284 */
Guido van Rossum47478871996-08-21 14:32:37 +00001285static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001286validate_stmt(tree)
1287 node *tree;
1288{
1289 int res = (validate_ntype(tree, stmt)
1290 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001291
Guido van Rossum3d602e31996-07-21 02:33:56 +00001292 if (res) {
1293 tree = CHILD(tree, 0);
1294
1295 if (TYPE(tree) == simple_stmt)
1296 res = validate_simple_stmt(tree);
1297 else
1298 res = validate_compound_stmt(tree);
1299 }
1300 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001301
1302} /* validate_stmt() */
1303
1304
Guido van Rossum3d602e31996-07-21 02:33:56 +00001305/* small_stmt (';' small_stmt)* [';'] NEWLINE
1306 *
1307 */
Guido van Rossum47478871996-08-21 14:32:37 +00001308static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001309validate_simple_stmt(tree)
1310 node *tree;
1311{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001312 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001313 int res = (validate_ntype(tree, simple_stmt)
1314 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001315 && validate_small_stmt(CHILD(tree, 0))
1316 && validate_newline(CHILD(tree, nch - 1)));
1317
Guido van Rossum3d602e31996-07-21 02:33:56 +00001318 if (nch < 2)
1319 res = validate_numnodes(tree, 2, "simple_stmt");
1320 --nch; /* forget the NEWLINE */
1321 if (res && is_even(nch))
1322 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001323 if (res && (nch > 2)) {
1324 int i;
1325
Guido van Rossum3d602e31996-07-21 02:33:56 +00001326 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001327 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001328 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001329 }
1330 return (res);
1331
1332} /* validate_simple_stmt() */
1333
1334
Guido van Rossum47478871996-08-21 14:32:37 +00001335static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001336validate_small_stmt(tree)
1337 node *tree;
1338{
1339 int nch = NCH(tree);
1340 int res = (validate_numnodes(tree, 1, "small_stmt")
1341 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1342 || (TYPE(CHILD(tree, 0)) == print_stmt)
1343 || (TYPE(CHILD(tree, 0)) == del_stmt)
1344 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1345 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1346 || (TYPE(CHILD(tree, 0)) == import_stmt)
1347 || (TYPE(CHILD(tree, 0)) == global_stmt)
Guido van Rossum925e5471997-04-02 05:32:13 +00001348 || (TYPE(CHILD(tree, 0)) == assert_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001349 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1350
1351 if (res)
1352 res = validate_node(CHILD(tree, 0));
1353 else if (nch == 1) {
1354 char buffer[60];
1355 sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1356 TYPE(CHILD(tree, 0)));
1357 err_string(buffer);
1358 }
1359 return (res);
1360
1361} /* validate_small_stmt */
1362
1363
1364/* compound_stmt:
1365 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1366 */
Guido van Rossum47478871996-08-21 14:32:37 +00001367static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001368validate_compound_stmt(tree)
1369 node *tree;
1370{
1371 int res = (validate_ntype(tree, compound_stmt)
1372 && validate_numnodes(tree, 1, "compound_stmt"));
1373
1374 if (!res)
1375 return (0);
1376
1377 tree = CHILD(tree, 0);
1378 res = ((TYPE(tree) == if_stmt)
1379 || (TYPE(tree) == while_stmt)
1380 || (TYPE(tree) == for_stmt)
1381 || (TYPE(tree) == try_stmt)
1382 || (TYPE(tree) == funcdef)
1383 || (TYPE(tree) == classdef));
1384 if (res)
1385 res = validate_node(tree);
1386 else {
1387 char buffer[60];
1388 sprintf(buffer, "Illegal compound statement type: %d.", TYPE(tree));
1389 err_string(buffer);
1390 }
1391 return (res);
1392
1393} /* validate_compound_stmt() */
1394
1395
Guido van Rossum47478871996-08-21 14:32:37 +00001396static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001397validate_expr_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, expr_stmt)
1403 && is_odd(nch)
1404 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001405
Guido van Rossum3d602e31996-07-21 02:33:56 +00001406 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001407 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001408 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001409
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001410 return (res);
1411
1412} /* validate_expr_stmt() */
1413
1414
Guido van Rossum3d602e31996-07-21 02:33:56 +00001415/* print_stmt:
1416 *
1417 * 'print' (test ',')* [test]
1418 *
1419 */
Guido van Rossum47478871996-08-21 14:32:37 +00001420static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001421validate_print_stmt(tree)
1422 node *tree;
1423{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001424 int j;
1425 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001426 int res = (validate_ntype(tree, print_stmt)
1427 && (nch != 0)
1428 && validate_name(CHILD(tree, 0), "print"));
1429
1430 if (res && is_even(nch)) {
1431 res = validate_test(CHILD(tree, nch - 1));
1432 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001433 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001434 else if (!res && !PyErr_Occurred())
1435 validate_numnodes(tree, 1, "print_stmt");
1436 for (j = 1; res && (j < nch); j += 2)
1437 res = (validate_test(CHILD(tree, j))
1438 && validate_ntype(CHILD(tree, j + 1), COMMA));
1439
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001440 return (res);
1441
1442} /* validate_print_stmt() */
1443
1444
Guido van Rossum47478871996-08-21 14:32:37 +00001445static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001446validate_del_stmt(tree)
1447 node *tree;
1448{
1449 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001450 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001451 && validate_exprlist(CHILD(tree, 1)));
1452
1453} /* validate_del_stmt() */
1454
1455
Guido van Rossum47478871996-08-21 14:32:37 +00001456static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001457validate_return_stmt(tree)
1458 node *tree;
1459{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001460 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001461 int res = (validate_ntype(tree, return_stmt)
1462 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001463 && validate_name(CHILD(tree, 0), "return"));
1464
Guido van Rossum3d602e31996-07-21 02:33:56 +00001465 if (res && (nch == 2))
1466 res = validate_testlist(CHILD(tree, 1));
1467
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001468 return (res);
1469
1470} /* validate_return_stmt() */
1471
1472
Guido van Rossum47478871996-08-21 14:32:37 +00001473static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001474validate_raise_stmt(tree)
1475 node *tree;
1476{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001477 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001478 int res = (validate_ntype(tree, raise_stmt)
1479 && ((nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001480
Guido van Rossum3d602e31996-07-21 02:33:56 +00001481 if (res) {
1482 res = (validate_name(CHILD(tree, 0), "raise")
1483 && validate_test(CHILD(tree, 1)));
1484 if (res && nch > 2) {
1485 res = (validate_comma(CHILD(tree, 2))
1486 && validate_test(CHILD(tree, 3)));
1487 if (res && (nch > 4))
1488 res = (validate_comma(CHILD(tree, 4))
1489 && validate_test(CHILD(tree, 5)));
1490 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001491 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001492 else
1493 validate_numnodes(tree, 2, "raise");
1494 if (res && (nch == 4))
1495 res = (validate_comma(CHILD(tree, 2))
1496 && validate_test(CHILD(tree, 3)));
1497
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001498 return (res);
1499
1500} /* validate_raise_stmt() */
1501
1502
Guido van Rossum3d602e31996-07-21 02:33:56 +00001503/* import_stmt:
1504 *
1505 * 'import' dotted_name (',' dotted_name)*
1506 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1507 */
Guido van Rossum47478871996-08-21 14:32:37 +00001508static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001509validate_import_stmt(tree)
1510 node *tree;
1511{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001512 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001513 int res = (validate_ntype(tree, import_stmt)
1514 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001515 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001516 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001517
1518 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001519 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001520
Guido van Rossum3d602e31996-07-21 02:33:56 +00001521 for (j = 2; res && (j < nch); j += 2)
1522 res = (validate_comma(CHILD(tree, j))
1523 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001524 }
1525 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001526 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001527 && validate_name(CHILD(tree, 2), "import"));
1528 if (nch == 4) {
1529 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001530 || (TYPE(CHILD(tree, 3)) == STAR));
1531 if (!res)
1532 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001533 }
1534 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001535 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001536 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001537 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001538 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001539 res = (validate_comma(CHILD(tree, j))
1540 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001541 }
1542 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001543 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001544 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001545
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001546 return (res);
1547
1548} /* validate_import_stmt() */
1549
1550
Guido van Rossum47478871996-08-21 14:32:37 +00001551static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001552validate_global_stmt(tree)
1553 node *tree;
1554{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001555 int j;
1556 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001557 int res = (validate_ntype(tree, global_stmt)
1558 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001559
Guido van Rossum3d602e31996-07-21 02:33:56 +00001560 if (res)
1561 res = (validate_name(CHILD(tree, 0), "global")
1562 && validate_ntype(CHILD(tree, 1), NAME));
1563 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001564 res = (validate_comma(CHILD(tree, j))
1565 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001566
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001567 return (res);
1568
1569} /* validate_global_stmt() */
1570
1571
Guido van Rossum3d602e31996-07-21 02:33:56 +00001572/* exec_stmt:
1573 *
1574 * 'exec' expr ['in' test [',' test]]
1575 */
Guido van Rossum47478871996-08-21 14:32:37 +00001576static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001577validate_exec_stmt(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, exec_stmt)
1582 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001583 && validate_name(CHILD(tree, 0), "exec")
1584 && validate_expr(CHILD(tree, 1)));
1585
Guido van Rossum3d602e31996-07-21 02:33:56 +00001586 if (!res && !PyErr_Occurred())
1587 err_string("Illegal exec statement.");
1588 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001589 res = (validate_name(CHILD(tree, 2), "in")
1590 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001591 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001592 res = (validate_comma(CHILD(tree, 4))
1593 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001594
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001595 return (res);
1596
1597} /* validate_exec_stmt() */
1598
1599
Guido van Rossum925e5471997-04-02 05:32:13 +00001600/* assert_stmt:
1601 *
1602 * 'assert' test [',' test]
1603 */
1604static int
1605validate_assert_stmt(tree)
1606 node *tree;
1607{
1608 int nch = NCH(tree);
1609 int res = (validate_ntype(tree, assert_stmt)
1610 && ((nch == 2) || (nch == 4))
1611 && (validate_name(CHILD(tree, 0), "__assert__") ||
1612 validate_name(CHILD(tree, 0), "assert"))
1613 && validate_test(CHILD(tree, 1)));
1614
1615 if (!res && !PyErr_Occurred())
1616 err_string("Illegal assert statement.");
1617 if (res && (nch > 2))
1618 res = (validate_comma(CHILD(tree, 2))
1619 && validate_test(CHILD(tree, 3)));
1620
1621 return (res);
1622
1623} /* validate_assert_stmt() */
1624
1625
Guido van Rossum47478871996-08-21 14:32:37 +00001626static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001627validate_while(tree)
1628 node *tree;
1629{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001630 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001631 int res = (validate_ntype(tree, while_stmt)
1632 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001633 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001634 && validate_test(CHILD(tree, 1))
1635 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001636 && validate_suite(CHILD(tree, 3)));
1637
Guido van Rossum3d602e31996-07-21 02:33:56 +00001638 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001639 res = (validate_name(CHILD(tree, 4), "else")
1640 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001641 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001642
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001643 return (res);
1644
1645} /* validate_while() */
1646
1647
Guido van Rossum47478871996-08-21 14:32:37 +00001648static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001649validate_for(tree)
1650 node *tree;
1651{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001652 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001653 int res = (validate_ntype(tree, for_stmt)
1654 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001655 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001656 && validate_exprlist(CHILD(tree, 1))
1657 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001658 && validate_testlist(CHILD(tree, 3))
1659 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001660 && validate_suite(CHILD(tree, 5)));
1661
Guido van Rossum3d602e31996-07-21 02:33:56 +00001662 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001663 res = (validate_name(CHILD(tree, 6), "else")
1664 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001665 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001666
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001667 return (res);
1668
1669} /* validate_for() */
1670
1671
Guido van Rossum3d602e31996-07-21 02:33:56 +00001672/* try_stmt:
1673 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1674 * | 'try' ':' suite 'finally' ':' suite
1675 *
1676 */
Guido van Rossum47478871996-08-21 14:32:37 +00001677static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001678validate_try(tree)
1679 node *tree;
1680{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001681 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001682 int pos = 3;
1683 int res = (validate_ntype(tree, try_stmt)
1684 && (nch >= 6) && ((nch % 3) == 0));
1685
1686 if (res)
1687 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001688 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001689 && validate_suite(CHILD(tree, 2))
1690 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001691 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001692 else {
1693 const char* name = "execpt";
1694 char buffer[60];
1695 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1696 name = STR(CHILD(tree, nch - 3));
1697 sprintf(buffer, "Illegal number of children for try/%s node.", name);
1698 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001699 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001700 /* Skip past except_clause sections: */
1701 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1702 res = (validate_except_clause(CHILD(tree, pos))
1703 && validate_colon(CHILD(tree, pos + 1))
1704 && validate_suite(CHILD(tree, pos + 2)));
1705 pos += 3;
1706 }
1707 if (res && (pos < nch)) {
1708 res = validate_ntype(CHILD(tree, pos), NAME);
1709 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1710 res = (validate_numnodes(tree, 6, "try/finally")
1711 && validate_colon(CHILD(tree, 4))
1712 && validate_suite(CHILD(tree, 5)));
1713 else if (res)
1714 if (nch == (pos + 3)) {
1715 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1716 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1717 if (!res)
1718 err_string("Illegal trailing triple in try statement.");
1719 }
1720 else if (nch == (pos + 6))
1721 res = (validate_name(CHILD(tree, pos), "except")
1722 && validate_colon(CHILD(tree, pos + 1))
1723 && validate_suite(CHILD(tree, pos + 2))
1724 && validate_name(CHILD(tree, pos + 3), "else"));
1725 else
1726 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001727 }
1728 return (res);
1729
1730} /* validate_try() */
1731
1732
Guido van Rossum47478871996-08-21 14:32:37 +00001733static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001734validate_except_clause(tree)
1735 node *tree;
1736{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001737 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001738 int res = (validate_ntype(tree, except_clause)
1739 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001740 && validate_name(CHILD(tree, 0), "except"));
1741
Guido van Rossum3d602e31996-07-21 02:33:56 +00001742 if (res && (nch > 1))
1743 res = validate_test(CHILD(tree, 1));
1744 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001745 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001746 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001747
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001748 return (res);
1749
1750} /* validate_except_clause() */
1751
1752
Guido van Rossum47478871996-08-21 14:32:37 +00001753static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001754validate_test(tree)
1755 node *tree;
1756{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001757 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001758 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001759
Guido van Rossum3d602e31996-07-21 02:33:56 +00001760 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001761 res = ((nch == 1)
1762 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001763 else if (res) {
1764 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001765 res = validate_and_test(CHILD(tree, 0));
1766 for (pos = 1; res && (pos < nch); pos += 2)
1767 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001768 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001769 }
1770 return (res);
1771
1772} /* validate_test() */
1773
1774
Guido van Rossum47478871996-08-21 14:32:37 +00001775static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001776validate_and_test(tree)
1777 node *tree;
1778{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001779 int pos;
1780 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001781 int res = (validate_ntype(tree, and_test)
1782 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001783 && validate_not_test(CHILD(tree, 0)));
1784
Guido van Rossum3d602e31996-07-21 02:33:56 +00001785 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001786 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001787 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001788
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001789 return (res);
1790
1791} /* validate_and_test() */
1792
1793
Guido van Rossum47478871996-08-21 14:32:37 +00001794static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001795validate_not_test(tree)
1796 node *tree;
1797{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001798 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001799 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001800
Guido van Rossum3d602e31996-07-21 02:33:56 +00001801 if (res) {
1802 if (nch == 2)
1803 res = (validate_name(CHILD(tree, 0), "not")
1804 && validate_not_test(CHILD(tree, 1)));
1805 else if (nch == 1)
1806 res = validate_comparison(CHILD(tree, 0));
1807 }
1808 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001809
1810} /* validate_not_test() */
1811
1812
Guido van Rossum47478871996-08-21 14:32:37 +00001813static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001814validate_comparison(tree)
1815 node *tree;
1816{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001817 int pos;
1818 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001819 int res = (validate_ntype(tree, comparison)
1820 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001821 && validate_expr(CHILD(tree, 0)));
1822
Guido van Rossum3d602e31996-07-21 02:33:56 +00001823 for (pos = 1; res && (pos < nch); pos += 2)
1824 res = (validate_comp_op(CHILD(tree, pos))
1825 && validate_expr(CHILD(tree, pos + 1)));
1826
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001827 return (res);
1828
1829} /* validate_comparison() */
1830
1831
Guido van Rossum47478871996-08-21 14:32:37 +00001832static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001833validate_comp_op(tree)
1834 node *tree;
1835{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001836 int res = 0;
1837 int nch = NCH(tree);
1838
Guido van Rossum3d602e31996-07-21 02:33:56 +00001839 if (!validate_ntype(tree, comp_op))
1840 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001841 if (nch == 1) {
1842 /*
1843 * Only child will be a terminal with a well-defined symbolic name
1844 * or a NAME with a string of either 'is' or 'in'
1845 */
1846 tree = CHILD(tree, 0);
1847 switch (TYPE(tree)) {
1848 case LESS:
1849 case GREATER:
1850 case EQEQUAL:
1851 case EQUAL:
1852 case LESSEQUAL:
1853 case GREATEREQUAL:
1854 case NOTEQUAL:
1855 res = 1;
1856 break;
1857 case NAME:
1858 res = ((strcmp(STR(tree), "in") == 0)
1859 || (strcmp(STR(tree), "is") == 0));
1860 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001861 char buff[128];
1862 sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1863 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001864 }
1865 break;
1866 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001867 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001868 break;
1869 }
1870 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001871 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001872 res = (validate_ntype(CHILD(tree, 0), NAME)
1873 && validate_ntype(CHILD(tree, 1), NAME)
1874 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1875 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1876 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1877 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001878 if (!res && !PyErr_Occurred())
1879 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001880 }
1881 return (res);
1882
1883} /* validate_comp_op() */
1884
1885
Guido van Rossum47478871996-08-21 14:32:37 +00001886static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001887validate_expr(tree)
1888 node *tree;
1889{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001890 int j;
1891 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001892 int res = (validate_ntype(tree, expr)
1893 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001894 && validate_xor_expr(CHILD(tree, 0)));
1895
Guido van Rossum3d602e31996-07-21 02:33:56 +00001896 for (j = 2; res && (j < nch); j += 2)
1897 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001898 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001899
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001900 return (res);
1901
1902} /* validate_expr() */
1903
1904
Guido van Rossum47478871996-08-21 14:32:37 +00001905static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001906validate_xor_expr(tree)
1907 node *tree;
1908{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001909 int j;
1910 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001911 int res = (validate_ntype(tree, xor_expr)
1912 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001913 && validate_and_expr(CHILD(tree, 0)));
1914
Guido van Rossum3d602e31996-07-21 02:33:56 +00001915 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001916 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001917 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001918
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001919 return (res);
1920
1921} /* validate_xor_expr() */
1922
1923
Guido van Rossum47478871996-08-21 14:32:37 +00001924static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001925validate_and_expr(tree)
1926 node *tree;
1927{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001928 int pos;
1929 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001930 int res = (validate_ntype(tree, and_expr)
1931 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001932 && validate_shift_expr(CHILD(tree, 0)));
1933
Guido van Rossum3d602e31996-07-21 02:33:56 +00001934 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001935 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001936 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001937
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001938 return (res);
1939
1940} /* validate_and_expr() */
1941
1942
1943static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001944validate_chain_two_ops(tree, termvalid, op1, op2)
1945 node *tree;
1946 int (*termvalid)();
1947 int op1;
1948 int op2;
1949 {
1950 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001951 int nch = NCH(tree);
1952 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001953 && (*termvalid)(CHILD(tree, 0)));
1954
Guido van Rossum3d602e31996-07-21 02:33:56 +00001955 for ( ; res && (pos < nch); pos += 2) {
1956 if (TYPE(CHILD(tree, pos)) != op1)
1957 res = validate_ntype(CHILD(tree, pos), op2);
1958 if (res)
1959 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001960 }
1961 return (res);
1962
1963} /* validate_chain_two_ops() */
1964
1965
Guido van Rossum47478871996-08-21 14:32:37 +00001966static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001967validate_shift_expr(tree)
1968 node *tree;
1969{
1970 return (validate_ntype(tree, shift_expr)
1971 && validate_chain_two_ops(tree, validate_arith_expr,
1972 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001973
1974} /* validate_shift_expr() */
1975
1976
Guido van Rossum47478871996-08-21 14:32:37 +00001977static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001978validate_arith_expr(tree)
1979 node *tree;
1980{
1981 return (validate_ntype(tree, arith_expr)
1982 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001983
1984} /* validate_arith_expr() */
1985
1986
Guido van Rossum47478871996-08-21 14:32:37 +00001987static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001988validate_term(tree)
1989 node *tree;
1990{
1991 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001992 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001993 int res = (validate_ntype(tree, term)
1994 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001995 && validate_factor(CHILD(tree, 0)));
1996
Guido van Rossum3d602e31996-07-21 02:33:56 +00001997 for ( ; res && (pos < nch); pos += 2)
1998 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001999 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002000 || (TYPE(CHILD(tree, pos)) == PERCENT))
2001 && validate_factor(CHILD(tree, pos + 1)));
2002
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002003 return (res);
2004
2005} /* validate_term() */
2006
2007
Guido van Rossum3d602e31996-07-21 02:33:56 +00002008/* factor:
2009 *
2010 * factor: ('+'|'-'|'~') factor | power
2011 */
Guido van Rossum47478871996-08-21 14:32:37 +00002012static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002013validate_factor(tree)
2014 node *tree;
2015{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002016 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002017 int res = (validate_ntype(tree, factor)
2018 && (((nch == 2)
2019 && ((TYPE(CHILD(tree, 0)) == PLUS)
2020 || (TYPE(CHILD(tree, 0)) == MINUS)
2021 || (TYPE(CHILD(tree, 0)) == TILDE))
2022 && validate_factor(CHILD(tree, 1)))
2023 || ((nch == 1)
2024 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002025 return (res);
2026
2027} /* validate_factor() */
2028
2029
Guido van Rossum3d602e31996-07-21 02:33:56 +00002030/* power:
2031 *
2032 * power: atom trailer* ('**' factor)*
2033 */
Guido van Rossum47478871996-08-21 14:32:37 +00002034static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002035validate_power(tree)
2036 node *tree;
2037{
2038 int pos = 1;
2039 int nch = NCH(tree);
2040 int res = (validate_ntype(tree, power) && (nch >= 1)
2041 && validate_atom(CHILD(tree, 0)));
2042
2043 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2044 res = validate_trailer(CHILD(tree, pos++));
2045 if (res && (pos < nch)) {
2046 if (!is_even(nch - pos)) {
2047 err_string("Illegal number of nodes for 'power'.");
2048 return (0);
2049 }
2050 for ( ; res && (pos < (nch - 1)); pos += 2)
2051 res = (validate_doublestar(CHILD(tree, pos))
2052 && validate_factor(CHILD(tree, pos + 1)));
2053 }
2054 return (res);
2055
2056} /* validate_power() */
2057
2058
Guido van Rossum47478871996-08-21 14:32:37 +00002059static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002060validate_atom(tree)
2061 node *tree;
2062{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002063 int pos;
2064 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002065 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002066
2067 if (res) {
2068 switch (TYPE(CHILD(tree, 0))) {
2069 case LPAR:
2070 res = ((nch <= 3)
2071 && (validate_rparen(CHILD(tree, nch - 1))));
2072
Guido van Rossum3d602e31996-07-21 02:33:56 +00002073 if (res && (nch == 3))
2074 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002075 break;
2076 case LSQB:
2077 res = ((nch <= 3)
2078 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2079
Guido van Rossum3d602e31996-07-21 02:33:56 +00002080 if (res && (nch == 3))
2081 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002082 break;
2083 case LBRACE:
2084 res = ((nch <= 3)
2085 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2086
Guido van Rossum3d602e31996-07-21 02:33:56 +00002087 if (res && (nch == 3))
2088 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002089 break;
2090 case BACKQUOTE:
2091 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002092 && validate_testlist(CHILD(tree, 1))
2093 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2094 break;
2095 case NAME:
2096 case NUMBER:
2097 res = (nch == 1);
2098 break;
2099 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002100 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002101 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002102 break;
2103 default:
2104 res = 0;
2105 break;
2106 }
2107 }
2108 return (res);
2109
2110} /* validate_atom() */
2111
2112
Guido van Rossum3d602e31996-07-21 02:33:56 +00002113/* funcdef:
2114 * 'def' NAME parameters ':' suite
2115 *
2116 */
Guido van Rossum47478871996-08-21 14:32:37 +00002117static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002118validate_funcdef(tree)
2119 node *tree;
2120{
2121 return (validate_ntype(tree, funcdef)
2122 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002123 && validate_name(CHILD(tree, 0), "def")
2124 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002125 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002126 && validate_parameters(CHILD(tree, 2))
2127 && validate_suite(CHILD(tree, 4)));
2128
2129} /* validate_funcdef() */
2130
2131
Guido van Rossum47478871996-08-21 14:32:37 +00002132static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002133validate_lambdef(tree)
2134 node *tree;
2135{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002136 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002137 int res = (validate_ntype(tree, lambdef)
2138 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002139 && validate_name(CHILD(tree, 0), "lambda")
2140 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002141 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002142
Guido van Rossum3d602e31996-07-21 02:33:56 +00002143 if (res && (nch == 4))
2144 res = validate_varargslist(CHILD(tree, 1));
2145 else if (!res && !PyErr_Occurred())
2146 validate_numnodes(tree, 3, "lambdef");
2147
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002148 return (res);
2149
2150} /* validate_lambdef() */
2151
2152
Guido van Rossum3d602e31996-07-21 02:33:56 +00002153/* arglist:
2154 *
2155 * argument (',' argument)* [',']
2156 */
Guido van Rossum47478871996-08-21 14:32:37 +00002157static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002158validate_arglist(tree)
2159 node *tree;
2160{
Guido van Rossum47478871996-08-21 14:32:37 +00002161 return (validate_repeating_list(tree, arglist,
2162 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002163
2164} /* validate_arglist() */
2165
2166
2167
2168/* argument:
2169 *
2170 * [test '='] test
2171 */
Guido van Rossum47478871996-08-21 14:32:37 +00002172static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002173validate_argument(tree)
2174 node *tree;
2175{
2176 int nch = NCH(tree);
2177 int res = (validate_ntype(tree, argument)
2178 && ((nch == 1) || (nch == 3))
2179 && validate_test(CHILD(tree, 0)));
2180
2181 if (res && (nch == 3))
2182 res = (validate_equal(CHILD(tree, 1))
2183 && validate_test(CHILD(tree, 2)));
2184
2185 return (res);
2186
2187} /* validate_argument() */
2188
2189
2190
2191/* trailer:
2192 *
Guido van Rossum47478871996-08-21 14:32:37 +00002193 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002194 */
Guido van Rossum47478871996-08-21 14:32:37 +00002195static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002196validate_trailer(tree)
2197 node *tree;
2198{
2199 int nch = NCH(tree);
2200 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002201
2202 if (res) {
2203 switch (TYPE(CHILD(tree, 0))) {
2204 case LPAR:
2205 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002206 if (res && (nch == 3))
2207 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002208 break;
2209 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002210 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002211 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002212 && validate_ntype(CHILD(tree, 2), RSQB));
2213 break;
2214 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002215 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002216 && validate_ntype(CHILD(tree, 1), NAME));
2217 break;
2218 default:
2219 res = 0;
2220 break;
2221 }
2222 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002223 else
2224 validate_numnodes(tree, 2, "trailer");
2225
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002226 return (res);
2227
2228} /* validate_trailer() */
2229
2230
Guido van Rossum47478871996-08-21 14:32:37 +00002231/* subscriptlist:
2232 *
2233 * subscript (',' subscript)* [',']
2234 */
2235static int
2236validate_subscriptlist(tree)
2237 node *tree;
2238{
2239 return (validate_repeating_list(tree, subscriptlist,
2240 validate_subscript, "subscriptlist"));
2241
2242} /* validate_subscriptlist() */
2243
2244
Guido van Rossum3d602e31996-07-21 02:33:56 +00002245/* subscript:
2246 *
Guido van Rossum47478871996-08-21 14:32:37 +00002247 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002248 */
Guido van Rossum47478871996-08-21 14:32:37 +00002249static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002250validate_subscript(tree)
2251 node *tree;
2252{
Guido van Rossum47478871996-08-21 14:32:37 +00002253 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002254 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002255 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002256
Guido van Rossum47478871996-08-21 14:32:37 +00002257 if (!res) {
2258 if (!PyErr_Occurred())
2259 err_string("invalid number of arguments for subscript node");
2260 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002261 }
Guido van Rossum47478871996-08-21 14:32:37 +00002262 if (TYPE(CHILD(tree, 0)) == DOT)
2263 /* take care of ('.' '.' '.') possibility */
2264 return (validate_numnodes(tree, 3, "subscript")
2265 && validate_dot(CHILD(tree, 0))
2266 && validate_dot(CHILD(tree, 1))
2267 && validate_dot(CHILD(tree, 2)));
2268 if (nch == 1) {
2269 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002270 res = validate_test(CHILD(tree, 0));
2271 else
Guido van Rossum47478871996-08-21 14:32:37 +00002272 res = validate_colon(CHILD(tree, 0));
2273 return (res);
2274 }
2275 /* Must be [test] ':' [test] [sliceop],
2276 * but at least one of the optional components will
2277 * be present, but we don't know which yet.
2278 */
2279 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2280 res = validate_test(CHILD(tree, 0));
2281 offset = 1;
2282 }
2283 if (res)
2284 res = validate_colon(CHILD(tree, offset));
2285 if (res) {
2286 int rem = nch - ++offset;
2287 if (rem) {
2288 if (TYPE(CHILD(tree, offset)) == test) {
2289 res = validate_test(CHILD(tree, offset));
2290 ++offset;
2291 --rem;
2292 }
2293 if (res && rem)
2294 res = validate_sliceop(CHILD(tree, offset));
2295 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002296 }
2297 return (res);
2298
2299} /* validate_subscript() */
2300
2301
Guido van Rossum47478871996-08-21 14:32:37 +00002302static int
2303validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002304 node *tree;
2305{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002306 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002307 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2308 && validate_ntype(tree, sliceop);
2309 if (!res && !PyErr_Occurred()) {
2310 validate_numnodes(tree, 1, "sliceop");
2311 res = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002312 }
Guido van Rossum47478871996-08-21 14:32:37 +00002313 if (res)
2314 res = validate_colon(CHILD(tree, 0));
2315 if (res && (nch == 2))
2316 res = validate_test(CHILD(tree, 1));
2317
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002318 return (res);
2319
Guido van Rossum47478871996-08-21 14:32:37 +00002320} /* validate_sliceop() */
2321
2322
2323static int
2324validate_exprlist(tree)
2325 node *tree;
2326{
2327 return (validate_repeating_list(tree, exprlist,
2328 validate_expr, "exprlist"));
2329
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002330} /* validate_exprlist() */
2331
2332
Guido van Rossum47478871996-08-21 14:32:37 +00002333static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002334validate_dictmaker(tree)
2335 node *tree;
2336{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002337 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002338 int res = (validate_ntype(tree, dictmaker)
2339 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002340 && validate_test(CHILD(tree, 0))
2341 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002342 && validate_test(CHILD(tree, 2)));
2343
Guido van Rossum3d602e31996-07-21 02:33:56 +00002344 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002345 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002346 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002347 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002348
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002349 if (res && (nch > 3)) {
2350 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002351 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002352 while (res && (pos < nch)) {
2353 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002354 && validate_test(CHILD(tree, pos + 1))
2355 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002356 && validate_test(CHILD(tree, pos + 3)));
2357 pos += 4;
2358 }
2359 }
2360 return (res);
2361
2362} /* validate_dictmaker() */
2363
2364
Guido van Rossum47478871996-08-21 14:32:37 +00002365static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002366validate_eval_input(tree)
2367 node *tree;
2368{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002369 int pos;
2370 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002371 int res = (validate_ntype(tree, eval_input)
2372 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002373 && validate_testlist(CHILD(tree, 0))
2374 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2375
Guido van Rossum3d602e31996-07-21 02:33:56 +00002376 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002377 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002378
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002379 return (res);
2380
2381} /* validate_eval_input() */
2382
2383
Guido van Rossum47478871996-08-21 14:32:37 +00002384static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002385validate_node(tree)
2386 node *tree;
2387{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002388 int nch = 0; /* num. children on current node */
2389 int res = 1; /* result value */
2390 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002391
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002392 while (res & (tree != 0)) {
2393 nch = NCH(tree);
2394 next = 0;
2395 switch (TYPE(tree)) {
2396 /*
2397 * Definition nodes.
2398 */
2399 case funcdef:
2400 res = validate_funcdef(tree);
2401 break;
2402 case classdef:
2403 res = validate_class(tree);
2404 break;
2405 /*
2406 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002407 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002408 */
2409 case stmt:
2410 res = validate_stmt(tree);
2411 break;
2412 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002413 /*
2414 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum925e5471997-04-02 05:32:13 +00002415 * | import_stmt | global_stmt | exec_stmt | assert_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002416 */
2417 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002418 break;
2419 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002420 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002421 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2422 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2423 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002424 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2425 if (res)
2426 next = CHILD(tree, 0);
2427 else if (nch == 1)
2428 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002429 break;
2430 /*
2431 * Compound statements.
2432 */
2433 case simple_stmt:
2434 res = validate_simple_stmt(tree);
2435 break;
2436 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002437 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002438 break;
2439 /*
2440 * Fundemental statements.
2441 */
2442 case expr_stmt:
2443 res = validate_expr_stmt(tree);
2444 break;
2445 case print_stmt:
2446 res = validate_print_stmt(tree);
2447 break;
2448 case del_stmt:
2449 res = validate_del_stmt(tree);
2450 break;
2451 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002452 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002453 && validate_name(CHILD(tree, 0), "pass"));
2454 break;
2455 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002456 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002457 && validate_name(CHILD(tree, 0), "break"));
2458 break;
2459 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002460 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002461 && validate_name(CHILD(tree, 0), "continue"));
2462 break;
2463 case return_stmt:
2464 res = validate_return_stmt(tree);
2465 break;
2466 case raise_stmt:
2467 res = validate_raise_stmt(tree);
2468 break;
2469 case import_stmt:
2470 res = validate_import_stmt(tree);
2471 break;
2472 case global_stmt:
2473 res = validate_global_stmt(tree);
2474 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002475 case exec_stmt:
2476 res = validate_exec_stmt(tree);
2477 break;
Guido van Rossum925e5471997-04-02 05:32:13 +00002478 case assert_stmt:
2479 res = validate_assert_stmt(tree);
2480 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002481 case if_stmt:
2482 res = validate_if(tree);
2483 break;
2484 case while_stmt:
2485 res = validate_while(tree);
2486 break;
2487 case for_stmt:
2488 res = validate_for(tree);
2489 break;
2490 case try_stmt:
2491 res = validate_try(tree);
2492 break;
2493 case suite:
2494 res = validate_suite(tree);
2495 break;
2496 /*
2497 * Expression nodes.
2498 */
2499 case testlist:
2500 res = validate_testlist(tree);
2501 break;
2502 case test:
2503 res = validate_test(tree);
2504 break;
2505 case and_test:
2506 res = validate_and_test(tree);
2507 break;
2508 case not_test:
2509 res = validate_not_test(tree);
2510 break;
2511 case comparison:
2512 res = validate_comparison(tree);
2513 break;
2514 case exprlist:
2515 res = validate_exprlist(tree);
2516 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002517 case comp_op:
2518 res = validate_comp_op(tree);
2519 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002520 case expr:
2521 res = validate_expr(tree);
2522 break;
2523 case xor_expr:
2524 res = validate_xor_expr(tree);
2525 break;
2526 case and_expr:
2527 res = validate_and_expr(tree);
2528 break;
2529 case shift_expr:
2530 res = validate_shift_expr(tree);
2531 break;
2532 case arith_expr:
2533 res = validate_arith_expr(tree);
2534 break;
2535 case term:
2536 res = validate_term(tree);
2537 break;
2538 case factor:
2539 res = validate_factor(tree);
2540 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002541 case power:
2542 res = validate_power(tree);
2543 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002544 case atom:
2545 res = validate_atom(tree);
2546 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002547
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002548 default:
2549 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002550 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002551 res = 0;
2552 break;
2553 }
2554 tree = next;
2555 }
2556 return (res);
2557
2558} /* validate_node() */
2559
2560
Guido van Rossum47478871996-08-21 14:32:37 +00002561static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002562validate_expr_tree(tree)
2563 node *tree;
2564{
2565 int res = validate_eval_input(tree);
2566
2567 if (!res && !PyErr_Occurred())
2568 err_string("Could not validate expression tuple.");
2569
2570 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002571
2572} /* validate_expr_tree() */
2573
2574
Guido van Rossum3d602e31996-07-21 02:33:56 +00002575/* file_input:
2576 * (NEWLINE | stmt)* ENDMARKER
2577 */
Guido van Rossum47478871996-08-21 14:32:37 +00002578static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002579validate_file_input(tree)
2580 node *tree;
2581{
2582 int j = 0;
2583 int nch = NCH(tree) - 1;
2584 int res = ((nch >= 0)
2585 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002586
Guido van Rossum3d602e31996-07-21 02:33:56 +00002587 for ( ; res && (j < nch); ++j) {
2588 if (TYPE(CHILD(tree, j)) == stmt)
2589 res = validate_stmt(CHILD(tree, j));
2590 else
2591 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002592 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002593 /* This stays in to prevent any internal failues from getting to the
2594 * user. Hopefully, this won't be needed. If a user reports getting
2595 * this, we have some debugging to do.
2596 */
2597 if (!res && !PyErr_Occurred())
2598 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2599
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002600 return (res);
2601
Guido van Rossum2a288461996-08-21 21:55:43 +00002602} /* validate_file_input() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002603
2604
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002605/* Functions exported by this module. Most of this should probably
2606 * be converted into an AST object with methods, but that is better
2607 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002608 * We'd really have to write a wrapper around it all anyway to allow
2609 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002610 */
2611static PyMethodDef parser_functions[] = {
Guido van Rossum3d602e31996-07-21 02:33:56 +00002612 {"ast2tuple", parser_ast2tuple, 1,
2613 "Creates a tuple-tree representation of an AST."},
Guido van Rossum47478871996-08-21 14:32:37 +00002614 {"ast2list", parser_ast2list, 1,
2615 "Creates a list-tree representation of an AST."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002616 {"compileast", parser_compileast, 1,
2617 "Compiles an AST object into a code object."},
2618 {"expr", parser_expr, 1,
2619 "Creates an AST object from an expression."},
2620 {"isexpr", parser_isexpr, 1,
2621 "Determines if an AST object was created from an expression."},
2622 {"issuite", parser_issuite, 1,
2623 "Determines if an AST object was created from a suite."},
2624 {"suite", parser_suite, 1,
2625 "Creates an AST object from a suite."},
Guido van Rossum47478871996-08-21 14:32:37 +00002626 {"sequence2ast", parser_tuple2ast, 1,
2627 "Creates an AST object from a tree representation."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002628 {"tuple2ast", parser_tuple2ast, 1,
Guido van Rossum47478871996-08-21 14:32:37 +00002629 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002630
2631 {0, 0, 0}
2632 };
2633
2634
Guido van Rossum52f2c051993-11-10 12:53:24 +00002635void
Guido van Rossum3d602e31996-07-21 02:33:56 +00002636initparser()
2637 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002638 PyObject* module;
2639 PyObject* dict;
2640
2641 PyAST_Type.ob_type = &PyType_Type;
2642 module = Py_InitModule("parser", parser_functions);
2643 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002644
2645 parser_error = PyString_FromString("parser.ParserError");
2646
2647 if ((parser_error == 0)
2648 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2649 /*
2650 * This is serious.
2651 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002652 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002653 }
2654 /*
2655 * Nice to have, but don't cry if we fail.
2656 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002657 Py_INCREF(&PyAST_Type);
2658 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2659
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002660 PyDict_SetItemString(dict, "__copyright__",
2661 PyString_FromString(parser_copyright_string));
2662 PyDict_SetItemString(dict, "__doc__",
2663 PyString_FromString(parser_doc_string));
2664 PyDict_SetItemString(dict, "__version__",
2665 PyString_FromString(parser_version_string));
2666
2667} /* initparser() */
2668
2669
2670/*
Guido van Rossum3d602e31996-07-21 02:33:56 +00002671 * end of parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002672 */