blob: 4167eb10cedb381644b277d8c2e43ce355b9dd87 [file] [log] [blame]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001/* parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002 *
Guido van Rossum47478871996-08-21 14:32:37 +00003 * Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic
4 * Institute and State University, Blacksburg, Virginia, USA.
5 * Portions copyright 1991-1995 by Stichting Mathematisch Centrum,
6 * Amsterdam, The Netherlands. Copying is permitted under the terms
7 * associated with the main Python distribution, with the additional
8 * restriction that this additional notice be included and maintained
9 * on all distributed copies.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000010 *
Guido van Rossum47478871996-08-21 14:32:37 +000011 * This module serves to replace the original parser module written
12 * by Guido. The functionality is not matched precisely, but the
13 * original may be implemented on top of this. This is desirable
14 * since the source of the text to be parsed is now divorced from
15 * this interface.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000016 *
Guido van Rossum47478871996-08-21 14:32:37 +000017 * Unlike the prior interface, the ability to give a parse tree
18 * produced by Python code as a tuple to the compiler is enabled by
19 * this module. See the documentation for more details.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000020 */
21
22#include "Python.h" /* general Python API */
23#include "graminit.h" /* symbols defined in the grammar */
24#include "node.h" /* internal parser structure */
25#include "token.h" /* token definitions */
26 /* ISTERMINAL() / ISNONTERMINAL() */
Guido van Rossum3d602e31996-07-21 02:33:56 +000027#include "compile.h" /* PyNode_Compile() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000028
29/*
30 * All the "fudge" declarations are here:
Guido van Rossum3d602e31996-07-21 02:33:56 +000031 *
32 * This isn't part of the Python runtime, but it's in the library somewhere.
Guido van Rossum2a288461996-08-21 21:55:43 +000033 * Where it is varies a bit, so just declare it. Don't use any prototype;
34 * different systems declare it a little differently, and we don't need the
35 * extra warnings.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000036 */
Guido van Rossum3d602e31996-07-21 02:33:56 +000037extern char* strdup();
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000038
39
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000040/* String constants used to initialize module attributes.
41 *
42 */
43static char*
44parser_copyright_string
Guido van Rossum2a288461996-08-21 21:55:43 +000045= "Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
46University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
47Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\
48Centrum, Amsterdam, The Netherlands.";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000049
50
51static char*
52parser_doc_string
53= "This is an interface to Python's internal parser.";
54
55static char*
Guido van Rossum47478871996-08-21 14:32:37 +000056parser_version_string = "0.4";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000057
58
Guido van Rossum2a288461996-08-21 21:55:43 +000059typedef PyObject* (*SeqMaker) Py_PROTO((int length));
60typedef void (*SeqInserter) Py_PROTO((PyObject* sequence,
61 int index,
62 PyObject* element));
Guido van Rossum47478871996-08-21 14:32:37 +000063
Guido van Rossum3d602e31996-07-21 02:33:56 +000064/* The function below is copyrigthed by Stichting Mathematisch Centrum. The
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000065 * original copyright statement is included below, and continues to apply
66 * in full to the function immediately following. All other material is
67 * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
68 * Institute and State University. Changes were made to comply with the
Guido van Rossum2a288461996-08-21 21:55:43 +000069 * new naming conventions. Added arguments to provide support for creating
70 * lists as well as tuples, and optionally including the line numbers.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000071 */
72
Guido van Rossum52f2c051993-11-10 12:53:24 +000073/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +000074Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
75The Netherlands.
Guido van Rossum52f2c051993-11-10 12:53:24 +000076
77 All Rights Reserved
78
Guido van Rossum3d602e31996-07-21 02:33:56 +000079Permission to use, copy, modify, and distribute this software and its
80documentation for any purpose and without fee is hereby granted,
Guido van Rossum52f2c051993-11-10 12:53:24 +000081provided that the above copyright notice appear in all copies and that
Guido van Rossum3d602e31996-07-21 02:33:56 +000082both that copyright notice and this permission notice appear in
Guido van Rossum52f2c051993-11-10 12:53:24 +000083supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000084Centrum or CWI or Corporation for National Research Initiatives or
85CNRI not be used in advertising or publicity pertaining to
86distribution of the software without specific, written prior
87permission.
Guido van Rossum52f2c051993-11-10 12:53:24 +000088
Guido van Rossumd266eb41996-10-25 14:44:06 +000089While CWI is the initial source for this software, a modified version
90is made available by the Corporation for National Research Initiatives
91(CNRI) at the Internet address ftp://ftp.python.org.
92
93STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
94REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
95MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
96CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
97DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
98PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
99TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
100PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum52f2c051993-11-10 12:53:24 +0000101
102******************************************************************/
103
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000104static PyObject*
Guido van Rossum47478871996-08-21 14:32:37 +0000105node2tuple(n, mkseq, addelem, lineno)
106 node *n; /* node to convert */
107 SeqMaker mkseq; /* create sequence */
108 SeqInserter addelem; /* func. to add elem. in seq. */
109 int lineno; /* include line numbers? */
110{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000111 if (n == NULL) {
112 Py_INCREF(Py_None);
113 return Py_None;
114 }
115 if (ISNONTERMINAL(TYPE(n))) {
116 int i;
117 PyObject *v, *w;
Guido van Rossum47478871996-08-21 14:32:37 +0000118 v = mkseq(1 + NCH(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000119 if (v == NULL)
120 return v;
121 w = PyInt_FromLong(TYPE(n));
122 if (w == NULL) {
123 Py_DECREF(v);
124 return NULL;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000125 }
Guido van Rossum47478871996-08-21 14:32:37 +0000126 addelem(v, 0, w);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000127 for (i = 0; i < NCH(n); i++) {
Guido van Rossum47478871996-08-21 14:32:37 +0000128 w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000129 if (w == NULL) {
130 Py_DECREF(v);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000131 return NULL;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000132 }
Guido van Rossum47478871996-08-21 14:32:37 +0000133 addelem(v, i+1, w);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000134 }
Guido van Rossum47478871996-08-21 14:32:37 +0000135 return (v);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000136 }
137 else if (ISTERMINAL(TYPE(n))) {
Guido van Rossum47478871996-08-21 14:32:37 +0000138 PyObject *result = mkseq(2 + lineno);
139 if (result != NULL) {
140 addelem(result, 0, PyInt_FromLong(TYPE(n)));
141 addelem(result, 1, PyString_FromString(STR(n)));
142 if (lineno == 1)
143 addelem(result, 2, PyInt_FromLong(n->n_lineno));
144 }
145 return (result);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000146 }
147 else {
148 PyErr_SetString(PyExc_SystemError,
149 "unrecognized parse tree node type");
150 return NULL;
151 }
Guido van Rossum47478871996-08-21 14:32:37 +0000152} /* node2tuple() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000153/*
154 * End of material copyrighted by Stichting Mathematisch Centrum.
155 */
Guido van Rossum52f2c051993-11-10 12:53:24 +0000156
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000157
158
159/* There are two types of intermediate objects we're interested in:
160 * 'eval' and 'exec' types. These constants can be used in the ast_type
161 * field of the object type to identify which any given object represents.
162 * These should probably go in an external header to allow other extensions
163 * to use them, but then, we really should be using C++ too. ;-)
164 *
Guido van Rossum3d602e31996-07-21 02:33:56 +0000165 * The PyAST_FRAGMENT type is not currently supported. Maybe not useful?
166 * Haven't decided yet.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000167 */
168
169#define PyAST_EXPR 1
170#define PyAST_SUITE 2
171#define PyAST_FRAGMENT 3
172
173
174/* These are the internal objects and definitions required to implement the
175 * AST type. Most of the internal names are more reminiscent of the 'old'
176 * naming style, but the code uses the new naming convention.
177 */
178
179static PyObject*
180parser_error = 0;
181
182
183typedef struct _PyAST_Object {
184
185 PyObject_HEAD /* standard object header */
186 node* ast_node; /* the node* returned by the parser */
187 int ast_type; /* EXPR or SUITE ? */
188
189} PyAST_Object;
190
191
Guido van Rossum2a288461996-08-21 21:55:43 +0000192staticforward void parser_free Py_PROTO((PyAST_Object *ast));
193staticforward int parser_compare Py_PROTO((PyAST_Object *left,
194 PyAST_Object *right));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000195
196
197/* static */
198PyTypeObject PyAST_Type = {
199
Guido van Rossumf2b2dac1997-01-23 23:29:44 +0000200 PyObject_HEAD_INIT(NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000201 0,
202 "ast", /* tp_name */
203 sizeof(PyAST_Object), /* tp_basicsize */
204 0, /* tp_itemsize */
205 (destructor)parser_free, /* tp_dealloc */
206 0, /* tp_print */
207 0, /* tp_getattr */
208 0, /* tp_setattr */
209 (cmpfunc)parser_compare, /* tp_compare */
210 0, /* tp_repr */
211 0, /* tp_as_number */
212 0, /* tp_as_sequence */
213 0, /* tp_as_mapping */
214 0, /* tp_hash */
215 0, /* tp_call */
216 0 /* tp_str */
217
218}; /* PyAST_Type */
219
220
221static int
222parser_compare_nodes(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000223 node *left;
224 node *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000225{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000226 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000227
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000228 if (TYPE(left) < TYPE(right))
229 return (-1);
230
231 if (TYPE(right) < TYPE(left))
232 return (1);
233
234 if (ISTERMINAL(TYPE(left)))
235 return (strcmp(STR(left), STR(right)));
236
237 if (NCH(left) < NCH(right))
238 return (-1);
239
240 if (NCH(right) < NCH(left))
241 return (1);
242
243 for (j = 0; j < NCH(left); ++j) {
244 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
245
246 if (v)
247 return (v);
248 }
249 return (0);
250
251} /* parser_compare_nodes() */
252
253
254/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
255 *
256 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
257 * This really just wraps a call to parser_compare_nodes() with some easy
258 * checks and protection code.
259 *
260 */
261static int
262parser_compare(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000263 PyAST_Object *left;
264 PyAST_Object *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000265{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000266 if (left == right)
267 return (0);
268
269 if ((left == 0) || (right == 0))
270 return (-1);
271
272 return (parser_compare_nodes(left->ast_node, right->ast_node));
273
274} /* parser_compare() */
275
276
277/* parser_newastobject(node* ast)
278 *
279 * Allocates a new Python object representing an AST. This is simply the
280 * 'wrapper' object that holds a node* and allows it to be passed around in
281 * Python code.
282 *
283 */
284static PyObject*
285parser_newastobject(ast, type)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000286 node *ast;
287 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000288{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000289 PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
290
291 if (o != 0) {
292 o->ast_node = ast;
293 o->ast_type = type;
294 }
295 return ((PyObject*)o);
296
297} /* parser_newastobject() */
298
299
300/* void parser_free(PyAST_Object* ast)
301 *
302 * This is called by a del statement that reduces the reference count to 0.
303 *
304 */
305static void
306parser_free(ast)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000307 PyAST_Object *ast;
Guido van Rossum47478871996-08-21 14:32:37 +0000308{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000309 PyNode_Free(ast->ast_node);
310 PyMem_DEL(ast);
311
312} /* parser_free() */
313
314
315/* parser_ast2tuple(PyObject* self, PyObject* args)
316 *
317 * This provides conversion from a node* to a tuple object that can be
318 * returned to the Python-level caller. The AST object is not modified.
319 *
320 */
321static PyObject*
322parser_ast2tuple(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000323 PyObject *self;
324 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000325{
326 PyObject *ast;
327 PyObject *line_option = 0;
328 PyObject *res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000329
Guido van Rossum47478871996-08-21 14:32:37 +0000330 if (PyArg_ParseTuple(args, "O!|O:ast2tuple", &PyAST_Type, &ast,
331 &line_option)) {
332 int lineno = 0;
333 if (line_option != 0) {
334 lineno = PyObject_IsTrue(line_option);
335 lineno = lineno ? 1 : 0;
336 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000337 /*
338 * Convert AST into a tuple representation. Use Guido's function,
339 * since it's known to work already.
340 */
Guido van Rossum47478871996-08-21 14:32:37 +0000341 res = node2tuple(((PyAST_Object*)ast)->ast_node,
342 PyTuple_New, PyTuple_SetItem, lineno);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000343 }
344 return (res);
345
346} /* parser_ast2tuple() */
347
348
Guido van Rossum47478871996-08-21 14:32:37 +0000349/* parser_ast2tuple(PyObject* self, PyObject* args)
350 *
351 * This provides conversion from a node* to a tuple object that can be
352 * returned to the Python-level caller. The AST object is not modified.
353 *
354 */
355static PyObject*
356parser_ast2list(self, args)
357 PyObject *self;
358 PyObject *args;
359{
360 PyObject *ast;
361 PyObject *line_option = 0;
362 PyObject *res = 0;
363
364 if (PyArg_ParseTuple(args, "O!|O:ast2list", &PyAST_Type, &ast,
365 &line_option)) {
366 int lineno = 0;
367 if (line_option != 0) {
368 lineno = PyObject_IsTrue(line_option);
369 lineno = lineno ? 1 : 0;
370 }
371 /*
372 * Convert AST into a tuple representation. Use Guido's function,
373 * since it's known to work already.
374 */
375 res = node2tuple(((PyAST_Object*)ast)->ast_node,
376 PyList_New, PyList_SetItem, lineno);
377 }
378 return (res);
379
380} /* parser_ast2list() */
381
382
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000383/* parser_compileast(PyObject* self, PyObject* args)
384 *
385 * This function creates code objects from the parse tree represented by
386 * the passed-in data object. An optional file name is passed in as well.
387 *
388 */
389static PyObject*
390parser_compileast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000391 PyObject *self;
392 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000393{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000394 PyAST_Object* ast;
395 PyObject* res = 0;
396 char* str = "<ast>";
397
398 if (PyArg_ParseTuple(args, "O!|s", &PyAST_Type, &ast, &str))
Guido van Rossum3d602e31996-07-21 02:33:56 +0000399 res = (PyObject*) PyNode_Compile(ast->ast_node, str);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000400
401 return (res);
402
403} /* parser_compileast() */
404
405
406/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
407 * PyObject* parser_issuite(PyObject* self, PyObject* args)
408 *
409 * Checks the passed-in AST object to determine if it is an expression or
410 * a statement suite, respectively. The return is a Python truth value.
411 *
412 */
413static PyObject*
414parser_isexpr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000415 PyObject *self;
416 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000417{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000418 PyAST_Object* ast;
419 PyObject* res = 0;
420
421 if (PyArg_ParseTuple(args, "O!:isexpr", &PyAST_Type, &ast)) {
422 /*
423 * Check to see if the AST represents an expression or not.
424 */
425 res = (ast->ast_type == PyAST_EXPR) ? Py_True : Py_False;
426 Py_INCREF(res);
427 }
428 return (res);
429
430} /* parser_isexpr() */
431
432
433static PyObject*
434parser_issuite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000435 PyObject *self;
436 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000437{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000438 PyAST_Object* ast;
439 PyObject* res = 0;
440
Guido van Rossum3d602e31996-07-21 02:33:56 +0000441 if (PyArg_ParseTuple(args, "O!:issuite", &PyAST_Type, &ast)) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000442 /*
443 * Check to see if the AST represents an expression or not.
444 */
445 res = (ast->ast_type == PyAST_EXPR) ? Py_False : Py_True;
446 Py_INCREF(res);
447 }
448 return (res);
449
450} /* parser_issuite() */
451
452
Guido van Rossum3d602e31996-07-21 02:33:56 +0000453/* err_string(char* message)
454 *
455 * Sets the error string for an exception of type ParserError.
456 *
457 */
458static void
459err_string(message)
460 char *message;
Guido van Rossum47478871996-08-21 14:32:37 +0000461{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000462 PyErr_SetString(parser_error, message);
463
464} /* err_string() */
465
466
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000467/* PyObject* parser_do_parse(PyObject* args, int type)
468 *
469 * Internal function to actually execute the parse and return the result if
470 * successful, or set an exception if not.
471 *
472 */
473static PyObject*
474parser_do_parse(args, type)
475 PyObject *args;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000476 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000477{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000478 char* string = 0;
479 PyObject* res = 0;
480
481 if (PyArg_ParseTuple(args, "s", &string)) {
482 node* n = PyParser_SimpleParseString(string,
483 (type == PyAST_EXPR)
484 ? eval_input : file_input);
485
486 if (n != 0)
487 res = parser_newastobject(n, type);
488 else
Guido van Rossum3d602e31996-07-21 02:33:56 +0000489 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000490 }
491 return (res);
492
493} /* parser_do_parse() */
494
495
496/* PyObject* parser_expr(PyObject* self, PyObject* args)
497 * PyObject* parser_suite(PyObject* self, PyObject* args)
498 *
499 * External interfaces to the parser itself. Which is called determines if
500 * the parser attempts to recognize an expression ('eval' form) or statement
501 * suite ('exec' form). The real work is done by parser_do_parse() above.
502 *
503 */
504static PyObject*
505parser_expr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000506 PyObject *self;
507 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000508{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000509 return (parser_do_parse(args, PyAST_EXPR));
510
511} /* parser_expr() */
512
513
514static PyObject*
515parser_suite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000516 PyObject *self;
517 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000518{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000519 return (parser_do_parse(args, PyAST_SUITE));
520
521} /* parser_suite() */
522
523
524
525/* This is the messy part of the code. Conversion from a tuple to an AST
526 * object requires that the input tuple be valid without having to rely on
527 * catching an exception from the compiler. This is done to allow the
528 * compiler itself to remain fast, since most of its input will come from
529 * the parser directly, and therefore be known to be syntactically correct.
530 * This validation is done to ensure that we don't core dump the compile
531 * phase, returning an exception instead.
532 *
533 * Two aspects can be broken out in this code: creating a node tree from
534 * the tuple passed in, and verifying that it is indeed valid. It may be
535 * advantageous to expand the number of AST types to include funcdefs and
536 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
537 * here. They are not necessary, and not quite as useful in a raw form.
538 * For now, let's get expressions and suites working reliably.
539 */
540
541
Guido van Rossum2a288461996-08-21 21:55:43 +0000542staticforward node* build_node_tree Py_PROTO((PyObject *tuple));
543staticforward int validate_expr_tree Py_PROTO((node *tree));
544staticforward int validate_file_input Py_PROTO((node *tree));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000545
546
547/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
548 *
549 * This is the public function, called from the Python code. It receives a
550 * single tuple object from the caller, and creates an AST object if the
551 * tuple can be validated. It does this by checking the first code of the
552 * tuple, and, if acceptable, builds the internal representation. If this
553 * step succeeds, the internal representation is validated as fully as
554 * possible with the various validate_*() routines defined below.
555 *
556 * This function must be changed if support is to be added for PyAST_FRAGMENT
557 * AST objects.
558 *
559 */
560static PyObject*
561parser_tuple2ast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000562 PyObject *self;
563 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000564{
565 PyObject *ast = 0;
566 PyObject *tuple = 0;
567 PyObject *temp = 0;
568 int ok;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000569 int start_sym = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000570
Guido van Rossum47478871996-08-21 14:32:37 +0000571 if (!PyArg_ParseTuple(args, "O:tuple2ast", &tuple))
572 return (0);
573 if (!PySequence_Check(tuple)) {
574 PyErr_SetString(PyExc_ValueError,
575 "tuple2ast() requires a single sequence argument");
576 return (0);
577 }
578 /*
579 * This mess of tests is written this way so we can use the abstract
580 * object interface (AOI). Unfortunately, the AOI increments reference
581 * counts, which requires that we store a pointer to retrieved object
582 * so we can DECREF it after the check. But we really should accept
583 * lists as well as tuples at the very least.
584 */
585 ok = PyObject_Length(tuple) >= 2;
586 if (ok) {
587 temp = PySequence_GetItem(tuple, 0);
588 ok = (temp != NULL) && PyInt_Check(temp);
589 if (ok)
590 /* this is used after the initial checks: */
591 start_sym = PyInt_AsLong(temp);
592 Py_XDECREF(temp);
593 }
594 if (ok) {
595 temp = PySequence_GetItem(tuple, 1);
596 ok = (temp != NULL) && PySequence_Check(temp);
597 Py_XDECREF(temp);
598 }
599 if (ok) {
600 temp = PySequence_GetItem(tuple, 1);
601 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
602 if (ok) {
603 PyObject *temp2 = PySequence_GetItem(temp, 0);
604 if (temp2 != NULL) {
605 ok = PyInt_Check(temp2);
606 Py_DECREF(temp2);
607 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000608 }
Guido van Rossum47478871996-08-21 14:32:37 +0000609 Py_XDECREF(temp);
610 }
611 /* If we've failed at some point, get out of here. */
612 if (!ok) {
613 err_string("malformed sequence for tuple2ast()");
614 return (0);
615 }
616 /*
617 * This might be a valid parse tree, but let's do a quick check
618 * before we jump the gun.
619 */
620 if (start_sym == eval_input) {
621 /* Might be an eval form. */
622 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000623
Guido van Rossum47478871996-08-21 14:32:37 +0000624 if ((expression != 0) && validate_expr_tree(expression))
625 ast = parser_newastobject(expression, PyAST_EXPR);
626 }
627 else if (start_sym == file_input) {
628 /* This looks like an exec form so far. */
629 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000630
Guido van Rossum47478871996-08-21 14:32:37 +0000631 if ((suite_tree != 0) && validate_file_input(suite_tree))
632 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000633 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000634 else
Guido van Rossum47478871996-08-21 14:32:37 +0000635 /* This is a fragment, and is not yet supported. Maybe they
636 * will be if I find a use for them.
637 */
638 err_string("Fragmentary parse trees not supported.");
639
640 /* Make sure we throw an exception on all errors. We should never
641 * get this, but we'd do well to be sure something is done.
642 */
643 if ((ast == 0) && !PyErr_Occurred())
644 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000645
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000646 return (ast);
647
648} /* parser_tuple2ast() */
649
650
651/* int check_terminal_tuple()
652 *
Guido van Rossum47478871996-08-21 14:32:37 +0000653 * Check a tuple to determine that it is indeed a valid terminal
654 * node. The node is known to be required as a terminal, so we throw
655 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000656 *
Guido van Rossum47478871996-08-21 14:32:37 +0000657 * The format of an acceptable terminal tuple is "(is[i])": the fact
658 * that elem is a tuple and the integer is a valid terminal symbol
659 * has been established before this function is called. We must
660 * check the length of the tuple and the type of the second element
661 * and optional third element. We do *NOT* check the actual text of
662 * the string element, which we could do in many cases. This is done
663 * by the validate_*() functions which operate on the internal
664 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000665 */
666static int
Guido van Rossum47478871996-08-21 14:32:37 +0000667check_terminal_tuple(elem)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000668 PyObject *elem;
Guido van Rossum47478871996-08-21 14:32:37 +0000669{
670 int len = PyObject_Length(elem);
671 int res = 1;
672 char* str = "Illegal terminal symbol; bad node length.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000673
Guido van Rossum47478871996-08-21 14:32:37 +0000674 if ((len == 2) || (len == 3)) {
675 PyObject *temp = PySequence_GetItem(elem, 1);
676 res = PyString_Check(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000677 str = "Illegal terminal symbol; expected a string.";
Guido van Rossum47478871996-08-21 14:32:37 +0000678 if (res && (len == 3)) {
679 PyObject* third = PySequence_GetItem(elem, 2);
680 res = PyInt_Check(third);
681 str = "Invalid third element of terminal node.";
682 Py_XDECREF(third);
683 }
684 Py_XDECREF(temp);
685 }
686 else {
687 res = 0;
688 }
689 if (!res) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000690 elem = Py_BuildValue("(os)", elem, str);
691 PyErr_SetObject(parser_error, elem);
692 }
693 return (res);
694
695} /* check_terminal_tuple() */
696
697
698/* node* build_node_children()
699 *
700 * Iterate across the children of the current non-terminal node and build
701 * their structures. If successful, return the root of this portion of
702 * the tree, otherwise, 0. Any required exception will be specified already,
703 * and no memory will have been deallocated.
704 *
705 */
706static node*
707build_node_children(tuple, root, line_num)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000708 PyObject *tuple;
709 node *root;
710 int *line_num;
Guido van Rossum47478871996-08-21 14:32:37 +0000711{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000712 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000713 int i;
714
715 for (i = 1; i < len; ++i) {
716 /* elem must always be a tuple, however simple */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000717 PyObject* elem = PySequence_GetItem(tuple, i);
Guido van Rossum47478871996-08-21 14:32:37 +0000718 int ok = elem != NULL;
719 long type = 0;
720 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000721
Guido van Rossum47478871996-08-21 14:32:37 +0000722 if (ok)
723 ok = PySequence_Check(elem);
724 if (ok) {
725 PyObject *temp = PySequence_GetItem(elem, 0);
726 if (temp == NULL)
727 ok = 0;
728 else {
729 ok = PyInt_Check(temp);
730 if (ok)
731 type = PyInt_AsLong(temp);
732 Py_DECREF(temp);
733 }
734 }
735 if (!ok) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000736 PyErr_SetObject(parser_error,
737 Py_BuildValue("(os)", elem,
738 "Illegal node construct."));
Guido van Rossum47478871996-08-21 14:32:37 +0000739 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000740 return (0);
741 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000742 if (ISTERMINAL(type)) {
Guido van Rossum47478871996-08-21 14:32:37 +0000743 if (check_terminal_tuple(elem)) {
744 PyObject *temp = PySequence_GetItem(elem, 1);
745
746 strn = strdup(PyString_AsString(temp));
747 Py_XDECREF(temp);
748
749 if (PyObject_Length(elem) == 3) {
750 PyObject* temp = PySequence_GetItem(elem, 2);
751 *line_num = PyInt_AsLong(temp);
752 Py_DECREF(temp);
753 }
754 }
755 else {
756 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000757 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000758 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000759 }
760 else if (!ISNONTERMINAL(type)) {
761 /*
762 * It has to be one or the other; this is an error.
763 * Throw an exception.
764 */
765 PyErr_SetObject(parser_error,
766 Py_BuildValue("(os)", elem,
767 "Unknown node type."));
Guido van Rossum47478871996-08-21 14:32:37 +0000768 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000769 return (0);
770 }
771 PyNode_AddChild(root, type, strn, *line_num);
772
773 if (ISNONTERMINAL(type)) {
774 node* new_child = CHILD(root, i - 1);
775
Guido van Rossum47478871996-08-21 14:32:37 +0000776 if (new_child != build_node_children(elem, new_child, line_num)) {
777 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000778 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000779 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000780 }
Guido van Rossum47478871996-08-21 14:32:37 +0000781 else if (type == NEWLINE) { /* It's true: we increment the */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000782 ++(*line_num); /* line number *after* the newline! */
Guido van Rossum47478871996-08-21 14:32:37 +0000783 }
784 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000785 }
786 return (root);
787
788} /* build_node_children() */
789
790
791static node*
792build_node_tree(tuple)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000793 PyObject *tuple;
Guido van Rossum47478871996-08-21 14:32:37 +0000794{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000795 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000796 PyObject *temp = PySequence_GetItem(tuple, 0);
797 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000798
Guido van Rossum47478871996-08-21 14:32:37 +0000799 if (temp != NULL)
800 num = PyInt_AsLong(temp);
801 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000802 if (ISTERMINAL(num)) {
803 /*
804 * The tuple is simple, but it doesn't start with a start symbol.
805 * Throw an exception now and be done with it.
806 */
807 tuple = Py_BuildValue("(os)", tuple,
Guido van Rossum3d602e31996-07-21 02:33:56 +0000808 "Illegal ast tuple; cannot start with terminal symbol.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000809 PyErr_SetObject(parser_error, tuple);
810 }
811 else if (ISNONTERMINAL(num)) {
812 /*
813 * Not efficient, but that can be handled later.
814 */
815 int line_num = 0;
816
817 res = PyNode_New(num);
818 if (res != build_node_children(tuple, res, &line_num)) {
819 PyNode_Free(res);
820 res = 0;
821 }
822 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000823 else
824 /* The tuple is illegal -- if the number is neither TERMINAL nor
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000825 * NONTERMINAL, we can't use it.
826 */
827 PyErr_SetObject(parser_error,
828 Py_BuildValue("(os)", tuple,
829 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000830
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000831 return (res);
832
833} /* build_node_tree() */
834
835
Guido van Rossum360a9341996-08-21 19:04:10 +0000836#ifdef HAVE_OLD_CPP
Guido van Rossum2a288461996-08-21 21:55:43 +0000837#define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000838#else
Guido van Rossum2a288461996-08-21 21:55:43 +0000839#define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000840#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000841
842
843/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000844 * Validation routines used within the validation section:
845 */
Guido van Rossum2a288461996-08-21 21:55:43 +0000846staticforward int validate_terminal Py_PROTO((node *terminal,
847 int type, char *string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000848
849#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
850#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
851#define validate_colon(ch) validate_terminal(ch, COLON, ":")
852#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
853#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
854#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000855#define validate_indent(ch) validate_terminal(ch, INDENT, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000856#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000857#define validate_newline(ch) validate_terminal(ch, NEWLINE, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000858#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
859#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
860#define validate_star(ch) validate_terminal(ch, STAR, "*")
861#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000862#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
Guido van Rossum47478871996-08-21 14:32:37 +0000863#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000864#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000865
Guido van Rossum3d602e31996-07-21 02:33:56 +0000866VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000867VALIDATER(class); VALIDATER(node);
868VALIDATER(parameters); VALIDATER(suite);
869VALIDATER(testlist); VALIDATER(varargslist);
870VALIDATER(fpdef); VALIDATER(fplist);
871VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000872VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000873VALIDATER(print_stmt); VALIDATER(del_stmt);
874VALIDATER(return_stmt);
875VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000876VALIDATER(global_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000877VALIDATER(exec_stmt); VALIDATER(compound_stmt);
878VALIDATER(while); VALIDATER(for);
879VALIDATER(try); VALIDATER(except_clause);
880VALIDATER(test); VALIDATER(and_test);
881VALIDATER(not_test); VALIDATER(comparison);
882VALIDATER(comp_op); VALIDATER(expr);
883VALIDATER(xor_expr); VALIDATER(and_expr);
884VALIDATER(shift_expr); VALIDATER(arith_expr);
885VALIDATER(term); VALIDATER(factor);
886VALIDATER(atom); VALIDATER(lambdef);
887VALIDATER(trailer); VALIDATER(subscript);
Guido van Rossum47478871996-08-21 14:32:37 +0000888VALIDATER(subscriptlist); VALIDATER(sliceop);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000889VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000890VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000891
892
893#define is_even(n) (((n) & 1) == 0)
894#define is_odd(n) (((n) & 1) == 1)
895
896
897static int
898validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000899 node *n;
900 int t;
Guido van Rossum47478871996-08-21 14:32:37 +0000901{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000902 int res = (TYPE(n) == t);
903
904 if (!res) {
905 char buffer[128];
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000906 sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000907 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000908 }
909 return (res);
910
911} /* validate_ntype() */
912
913
914static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000915validate_numnodes(n, num, name)
916 node *n;
917 int num;
918 const char *const name;
Guido van Rossum47478871996-08-21 14:32:37 +0000919{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000920 if (NCH(n) != num) {
921 char buff[60];
922 sprintf(buff, "Illegal number of children for %s node.", name);
923 err_string(buff);
924 }
925 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000926
Guido van Rossum3d602e31996-07-21 02:33:56 +0000927} /* validate_numnodes() */
928
929
930static int
931validate_terminal(terminal, type, string)
932 node *terminal;
933 int type;
934 char *string;
Guido van Rossum47478871996-08-21 14:32:37 +0000935{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000936 int res = (validate_ntype(terminal, type)
937 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
938
939 if (!res && !PyErr_Occurred()) {
940 char buffer[60];
941 sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
942 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000943 }
944 return (res);
945
946} /* validate_terminal() */
947
948
Guido van Rossum47478871996-08-21 14:32:37 +0000949/* X (',' X) [',']
950 */
951static int
952validate_repeating_list(tree, ntype, vfunc, name)
953 node *tree;
954 int ntype;
955 int (*vfunc)();
956 const char *const name;
957{
958 int nch = NCH(tree);
959 int res = (nch && validate_ntype(tree, ntype)
960 && vfunc(CHILD(tree, 0)));
961
962 if (!res && !PyErr_Occurred())
963 validate_numnodes(tree, 1, name);
964 else {
965 if (is_even(nch))
966 res = validate_comma(CHILD(tree, --nch));
967 if (res && nch > 1) {
968 int pos = 1;
969 for ( ; res && pos < nch; pos += 2)
970 res = (validate_comma(CHILD(tree, pos))
971 && vfunc(CHILD(tree, pos + 1)));
972 }
973 }
974 return (res);
975
976} /* validate_repeating_list() */
977
978
Guido van Rossum3d602e31996-07-21 02:33:56 +0000979/* VALIDATE(class)
980 *
981 * classdef:
982 * 'class' NAME ['(' testlist ')'] ':' suite
983 */
Guido van Rossum47478871996-08-21 14:32:37 +0000984static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000985validate_class(tree)
986 node *tree;
987{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000988 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000989 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000990
Guido van Rossum3d602e31996-07-21 02:33:56 +0000991 if (res) {
992 res = (validate_name(CHILD(tree, 0), "class")
993 && validate_ntype(CHILD(tree, 1), NAME)
994 && validate_colon(CHILD(tree, nch - 2))
995 && validate_suite(CHILD(tree, nch - 1)));
996 }
997 else
998 validate_numnodes(tree, 4, "class");
999 if (res && (nch == 7)) {
1000 res = (validate_lparen(CHILD(tree, 2))
1001 && validate_testlist(CHILD(tree, 3))
1002 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001003 }
1004 return (res);
1005
1006} /* validate_class() */
1007
1008
Guido van Rossum3d602e31996-07-21 02:33:56 +00001009/* if_stmt:
1010 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1011 */
Guido van Rossum47478871996-08-21 14:32:37 +00001012static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001013validate_if(tree)
1014 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001015{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001016 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001017 int res = (validate_ntype(tree, if_stmt)
1018 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001019 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +00001020 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001021 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001022 && validate_suite(CHILD(tree, 3)));
1023
1024 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001025 /* ... 'else' ':' suite */
1026 res = (validate_name(CHILD(tree, nch - 3), "else")
1027 && validate_colon(CHILD(tree, nch - 2))
1028 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001029 nch -= 3;
1030 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001031 else if (!res && !PyErr_Occurred())
1032 validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001033 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001034 /* Will catch the case for nch < 4 */
1035 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001036 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001037 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001038 int j = 4;
1039 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001040 res = (validate_name(CHILD(tree, j), "elif")
1041 && validate_colon(CHILD(tree, j + 2))
1042 && validate_test(CHILD(tree, j + 1))
1043 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001044 j += 4;
1045 }
1046 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001047 return (res);
1048
1049} /* validate_if() */
1050
1051
Guido van Rossum3d602e31996-07-21 02:33:56 +00001052/* parameters:
1053 * '(' [varargslist] ')'
1054 *
1055 */
Guido van Rossum47478871996-08-21 14:32:37 +00001056static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001057validate_parameters(tree)
1058 node *tree;
1059{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001060 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001061 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001062
Guido van Rossum3d602e31996-07-21 02:33:56 +00001063 if (res) {
1064 res = (validate_lparen(CHILD(tree, 0))
1065 && validate_rparen(CHILD(tree, nch - 1)));
1066 if (res && (nch == 3))
1067 res = validate_varargslist(CHILD(tree, 1));
1068 }
1069 else
1070 validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001071
1072 return (res);
1073
1074} /* validate_parameters() */
1075
1076
Guido van Rossum3d602e31996-07-21 02:33:56 +00001077/* VALIDATE(suite)
1078 *
1079 * suite:
1080 * simple_stmt
1081 * | NEWLINE INDENT stmt+ DEDENT
1082 */
Guido van Rossum47478871996-08-21 14:32:37 +00001083static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001084validate_suite(tree)
1085 node *tree;
1086{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001087 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001088 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001089
Guido van Rossum3d602e31996-07-21 02:33:56 +00001090 if (res && (nch == 1))
1091 res = validate_simple_stmt(CHILD(tree, 0));
1092 else if (res) {
1093 /* NEWLINE INDENT stmt+ DEDENT */
1094 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001095 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001096 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001097 && validate_dedent(CHILD(tree, nch - 1)));
1098
Guido van Rossum3d602e31996-07-21 02:33:56 +00001099 if (res && (nch > 4)) {
1100 int i = 3;
1101 --nch; /* forget the DEDENT */
1102 for ( ; res && (i < nch); ++i)
1103 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001104 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001105 else if (nch < 4)
1106 validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001107 }
1108 return (res);
1109
1110} /* validate_suite() */
1111
1112
Guido van Rossum47478871996-08-21 14:32:37 +00001113static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001114validate_testlist(tree)
1115 node *tree;
1116{
Guido van Rossum47478871996-08-21 14:32:37 +00001117 return (validate_repeating_list(tree, testlist,
1118 validate_test, "testlist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001119
1120} /* validate_testlist() */
1121
1122
Guido van Rossum3d602e31996-07-21 02:33:56 +00001123/* VALIDATE(varargslist)
1124 *
1125 * varargslist:
1126 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1127 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1128 *
1129 * (fpdef ['=' test] ',')*
1130 * ('*' NAME [',' ('**'|'*' '*') NAME]
1131 * | ('**'|'*' '*') NAME)
1132 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1133 *
1134 */
Guido van Rossum47478871996-08-21 14:32:37 +00001135static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001136validate_varargslist(tree)
1137 node *tree;
1138{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001139 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001140 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001141
Guido van Rossum3d602e31996-07-21 02:33:56 +00001142 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1143 /* (fpdef ['=' test] ',')*
1144 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1145 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001146 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001147 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001148
Guido van Rossum3d602e31996-07-21 02:33:56 +00001149 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1150 res = validate_fpdef(CHILD(tree, pos));
1151 if (res) {
1152 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1153 res = validate_test(CHILD(tree, pos + 2));
1154 pos += 2;
1155 }
1156 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001157 pos += 2;
1158 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001159 }
1160 if (res) {
1161 remaining = nch - pos;
1162 res = ((remaining == 2) || (remaining == 3)
1163 || (remaining == 5) || (remaining == 6));
1164 if (!res)
1165 validate_numnodes(tree, 2, "varargslist");
1166 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1167 return ((remaining == 2)
1168 && validate_ntype(CHILD(tree, pos+1), NAME));
1169 else {
1170 res = validate_star(CHILD(tree, pos++));
1171 --remaining;
1172 }
1173 }
1174 if (res) {
1175 if (remaining == 2) {
1176 res = (validate_star(CHILD(tree, pos))
1177 && validate_ntype(CHILD(tree, pos + 1), NAME));
1178 }
1179 else {
1180 res = validate_ntype(CHILD(tree, pos++), NAME);
1181 if (res && (remaining >= 4)) {
1182 res = validate_comma(CHILD(tree, pos));
1183 if (--remaining == 3)
Fred Drakee1607a81996-09-11 21:58:26 +00001184 res = (validate_star(CHILD(tree, pos + 1))
1185 && validate_star(CHILD(tree, pos + 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001186 else
1187 validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1188 }
1189 }
1190 }
1191 if (!res && !PyErr_Occurred())
1192 err_string("Incorrect validation of variable arguments list.");
1193 }
1194 else if (res) {
1195 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1196 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1197 --nch;
1198
1199 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1200 res = (is_odd(nch)
1201 && validate_fpdef(CHILD(tree, 0)));
1202
1203 if (res && (nch > 1)) {
1204 int pos = 1;
1205 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1206 res = validate_test(CHILD(tree, 2));
1207 pos += 2;
1208 }
1209 /* ... (',' fpdef ['=' test])* */
1210 for ( ; res && (pos < nch); pos += 2) {
1211 /* ',' fpdef */
1212 res = (validate_comma(CHILD(tree, pos))
1213 && validate_fpdef(CHILD(tree, pos + 1)));
1214 if (res
1215 && ((nch - pos) > 2)
1216 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1217 /* ['=' test] */
1218 res = validate_test(CHILD(tree, pos + 3));
1219 pos += 2;
1220 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001221 }
1222 }
1223 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001224 else
1225 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001226
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001227 return (res);
1228
1229} /* validate_varargslist() */
1230
1231
Guido van Rossum3d602e31996-07-21 02:33:56 +00001232/* VALIDATE(fpdef)
1233 *
1234 * fpdef:
1235 * NAME
1236 * | '(' fplist ')'
1237 */
Guido van Rossum47478871996-08-21 14:32:37 +00001238static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001239validate_fpdef(tree)
1240 node *tree;
1241{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001242 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001243 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001244
Guido van Rossum3d602e31996-07-21 02:33:56 +00001245 if (res) {
1246 if (nch == 1)
1247 res = validate_ntype(CHILD(tree, 0), NAME);
1248 else if (nch == 3)
1249 res = (validate_lparen(CHILD(tree, 0))
1250 && validate_fplist(CHILD(tree, 1))
1251 && validate_rparen(CHILD(tree, 2)));
1252 else
1253 validate_numnodes(tree, 1, "fpdef");
1254 }
1255 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001256
1257} /* validate_fpdef() */
1258
1259
Guido van Rossum47478871996-08-21 14:32:37 +00001260static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001261validate_fplist(tree)
1262 node *tree;
1263{
Guido van Rossum47478871996-08-21 14:32:37 +00001264 return (validate_repeating_list(tree, fplist,
1265 validate_fpdef, "fplist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001266
1267} /* validate_fplist() */
1268
1269
Guido van Rossum3d602e31996-07-21 02:33:56 +00001270/* simple_stmt | compound_stmt
1271 *
1272 */
Guido van Rossum47478871996-08-21 14:32:37 +00001273static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001274validate_stmt(tree)
1275 node *tree;
1276{
1277 int res = (validate_ntype(tree, stmt)
1278 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001279
Guido van Rossum3d602e31996-07-21 02:33:56 +00001280 if (res) {
1281 tree = CHILD(tree, 0);
1282
1283 if (TYPE(tree) == simple_stmt)
1284 res = validate_simple_stmt(tree);
1285 else
1286 res = validate_compound_stmt(tree);
1287 }
1288 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001289
1290} /* validate_stmt() */
1291
1292
Guido van Rossum3d602e31996-07-21 02:33:56 +00001293/* small_stmt (';' small_stmt)* [';'] NEWLINE
1294 *
1295 */
Guido van Rossum47478871996-08-21 14:32:37 +00001296static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001297validate_simple_stmt(tree)
1298 node *tree;
1299{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001300 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001301 int res = (validate_ntype(tree, simple_stmt)
1302 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001303 && validate_small_stmt(CHILD(tree, 0))
1304 && validate_newline(CHILD(tree, nch - 1)));
1305
Guido van Rossum3d602e31996-07-21 02:33:56 +00001306 if (nch < 2)
1307 res = validate_numnodes(tree, 2, "simple_stmt");
1308 --nch; /* forget the NEWLINE */
1309 if (res && is_even(nch))
1310 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001311 if (res && (nch > 2)) {
1312 int i;
1313
Guido van Rossum3d602e31996-07-21 02:33:56 +00001314 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001315 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001316 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001317 }
1318 return (res);
1319
1320} /* validate_simple_stmt() */
1321
1322
Guido van Rossum47478871996-08-21 14:32:37 +00001323static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001324validate_small_stmt(tree)
1325 node *tree;
1326{
1327 int nch = NCH(tree);
1328 int res = (validate_numnodes(tree, 1, "small_stmt")
1329 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1330 || (TYPE(CHILD(tree, 0)) == print_stmt)
1331 || (TYPE(CHILD(tree, 0)) == del_stmt)
1332 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1333 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1334 || (TYPE(CHILD(tree, 0)) == import_stmt)
1335 || (TYPE(CHILD(tree, 0)) == global_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001336 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1337
1338 if (res)
1339 res = validate_node(CHILD(tree, 0));
1340 else if (nch == 1) {
1341 char buffer[60];
1342 sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1343 TYPE(CHILD(tree, 0)));
1344 err_string(buffer);
1345 }
1346 return (res);
1347
1348} /* validate_small_stmt */
1349
1350
1351/* compound_stmt:
1352 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1353 */
Guido van Rossum47478871996-08-21 14:32:37 +00001354static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001355validate_compound_stmt(tree)
1356 node *tree;
1357{
1358 int res = (validate_ntype(tree, compound_stmt)
1359 && validate_numnodes(tree, 1, "compound_stmt"));
1360
1361 if (!res)
1362 return (0);
1363
1364 tree = CHILD(tree, 0);
1365 res = ((TYPE(tree) == if_stmt)
1366 || (TYPE(tree) == while_stmt)
1367 || (TYPE(tree) == for_stmt)
1368 || (TYPE(tree) == try_stmt)
1369 || (TYPE(tree) == funcdef)
1370 || (TYPE(tree) == classdef));
1371 if (res)
1372 res = validate_node(tree);
1373 else {
1374 char buffer[60];
1375 sprintf(buffer, "Illegal compound statement type: %d.", TYPE(tree));
1376 err_string(buffer);
1377 }
1378 return (res);
1379
1380} /* validate_compound_stmt() */
1381
1382
Guido van Rossum47478871996-08-21 14:32:37 +00001383static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001384validate_expr_stmt(tree)
1385 node *tree;
1386{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001387 int j;
1388 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001389 int res = (validate_ntype(tree, expr_stmt)
1390 && is_odd(nch)
1391 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001392
Guido van Rossum3d602e31996-07-21 02:33:56 +00001393 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001394 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001395 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001396
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001397 return (res);
1398
1399} /* validate_expr_stmt() */
1400
1401
Guido van Rossum3d602e31996-07-21 02:33:56 +00001402/* print_stmt:
1403 *
1404 * 'print' (test ',')* [test]
1405 *
1406 */
Guido van Rossum47478871996-08-21 14:32:37 +00001407static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001408validate_print_stmt(tree)
1409 node *tree;
1410{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001411 int j;
1412 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001413 int res = (validate_ntype(tree, print_stmt)
1414 && (nch != 0)
1415 && validate_name(CHILD(tree, 0), "print"));
1416
1417 if (res && is_even(nch)) {
1418 res = validate_test(CHILD(tree, nch - 1));
1419 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001420 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001421 else if (!res && !PyErr_Occurred())
1422 validate_numnodes(tree, 1, "print_stmt");
1423 for (j = 1; res && (j < nch); j += 2)
1424 res = (validate_test(CHILD(tree, j))
1425 && validate_ntype(CHILD(tree, j + 1), COMMA));
1426
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001427 return (res);
1428
1429} /* validate_print_stmt() */
1430
1431
Guido van Rossum47478871996-08-21 14:32:37 +00001432static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001433validate_del_stmt(tree)
1434 node *tree;
1435{
1436 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001437 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001438 && validate_exprlist(CHILD(tree, 1)));
1439
1440} /* validate_del_stmt() */
1441
1442
Guido van Rossum47478871996-08-21 14:32:37 +00001443static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001444validate_return_stmt(tree)
1445 node *tree;
1446{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001447 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001448 int res = (validate_ntype(tree, return_stmt)
1449 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001450 && validate_name(CHILD(tree, 0), "return"));
1451
Guido van Rossum3d602e31996-07-21 02:33:56 +00001452 if (res && (nch == 2))
1453 res = validate_testlist(CHILD(tree, 1));
1454
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001455 return (res);
1456
1457} /* validate_return_stmt() */
1458
1459
Guido van Rossum47478871996-08-21 14:32:37 +00001460static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001461validate_raise_stmt(tree)
1462 node *tree;
1463{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001464 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001465 int res = (validate_ntype(tree, raise_stmt)
1466 && ((nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001467
Guido van Rossum3d602e31996-07-21 02:33:56 +00001468 if (res) {
1469 res = (validate_name(CHILD(tree, 0), "raise")
1470 && validate_test(CHILD(tree, 1)));
1471 if (res && nch > 2) {
1472 res = (validate_comma(CHILD(tree, 2))
1473 && validate_test(CHILD(tree, 3)));
1474 if (res && (nch > 4))
1475 res = (validate_comma(CHILD(tree, 4))
1476 && validate_test(CHILD(tree, 5)));
1477 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001478 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001479 else
1480 validate_numnodes(tree, 2, "raise");
1481 if (res && (nch == 4))
1482 res = (validate_comma(CHILD(tree, 2))
1483 && validate_test(CHILD(tree, 3)));
1484
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001485 return (res);
1486
1487} /* validate_raise_stmt() */
1488
1489
Guido van Rossum3d602e31996-07-21 02:33:56 +00001490/* import_stmt:
1491 *
1492 * 'import' dotted_name (',' dotted_name)*
1493 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1494 */
Guido van Rossum47478871996-08-21 14:32:37 +00001495static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001496validate_import_stmt(tree)
1497 node *tree;
1498{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001499 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001500 int res = (validate_ntype(tree, import_stmt)
1501 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001502 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001503 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001504
1505 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001506 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001507
Guido van Rossum3d602e31996-07-21 02:33:56 +00001508 for (j = 2; res && (j < nch); j += 2)
1509 res = (validate_comma(CHILD(tree, j))
1510 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001511 }
1512 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001513 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001514 && validate_name(CHILD(tree, 2), "import"));
1515 if (nch == 4) {
1516 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001517 || (TYPE(CHILD(tree, 3)) == STAR));
1518 if (!res)
1519 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001520 }
1521 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001522 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001523 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001524 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001525 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001526 res = (validate_comma(CHILD(tree, j))
1527 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001528 }
1529 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001530 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001531 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001532
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001533 return (res);
1534
1535} /* validate_import_stmt() */
1536
1537
Guido van Rossum47478871996-08-21 14:32:37 +00001538static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001539validate_global_stmt(tree)
1540 node *tree;
1541{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001542 int j;
1543 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001544 int res = (validate_ntype(tree, global_stmt)
1545 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001546
Guido van Rossum3d602e31996-07-21 02:33:56 +00001547 if (res)
1548 res = (validate_name(CHILD(tree, 0), "global")
1549 && validate_ntype(CHILD(tree, 1), NAME));
1550 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001551 res = (validate_comma(CHILD(tree, j))
1552 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001553
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001554 return (res);
1555
1556} /* validate_global_stmt() */
1557
1558
Guido van Rossum3d602e31996-07-21 02:33:56 +00001559/* exec_stmt:
1560 *
1561 * 'exec' expr ['in' test [',' test]]
1562 */
Guido van Rossum47478871996-08-21 14:32:37 +00001563static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001564validate_exec_stmt(tree)
1565 node *tree;
1566{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001567 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001568 int res = (validate_ntype(tree, exec_stmt)
1569 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001570 && validate_name(CHILD(tree, 0), "exec")
1571 && validate_expr(CHILD(tree, 1)));
1572
Guido van Rossum3d602e31996-07-21 02:33:56 +00001573 if (!res && !PyErr_Occurred())
1574 err_string("Illegal exec statement.");
1575 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001576 res = (validate_name(CHILD(tree, 2), "in")
1577 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001578 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001579 res = (validate_comma(CHILD(tree, 4))
1580 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001581
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001582 return (res);
1583
1584} /* validate_exec_stmt() */
1585
1586
Guido van Rossum47478871996-08-21 14:32:37 +00001587static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001588validate_while(tree)
1589 node *tree;
1590{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001591 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001592 int res = (validate_ntype(tree, while_stmt)
1593 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001594 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001595 && validate_test(CHILD(tree, 1))
1596 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001597 && validate_suite(CHILD(tree, 3)));
1598
Guido van Rossum3d602e31996-07-21 02:33:56 +00001599 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001600 res = (validate_name(CHILD(tree, 4), "else")
1601 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001602 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001603
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001604 return (res);
1605
1606} /* validate_while() */
1607
1608
Guido van Rossum47478871996-08-21 14:32:37 +00001609static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001610validate_for(tree)
1611 node *tree;
1612{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001613 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001614 int res = (validate_ntype(tree, for_stmt)
1615 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001616 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001617 && validate_exprlist(CHILD(tree, 1))
1618 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001619 && validate_testlist(CHILD(tree, 3))
1620 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001621 && validate_suite(CHILD(tree, 5)));
1622
Guido van Rossum3d602e31996-07-21 02:33:56 +00001623 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001624 res = (validate_name(CHILD(tree, 6), "else")
1625 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001626 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001627
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001628 return (res);
1629
1630} /* validate_for() */
1631
1632
Guido van Rossum3d602e31996-07-21 02:33:56 +00001633/* try_stmt:
1634 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1635 * | 'try' ':' suite 'finally' ':' suite
1636 *
1637 */
Guido van Rossum47478871996-08-21 14:32:37 +00001638static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001639validate_try(tree)
1640 node *tree;
1641{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001642 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001643 int pos = 3;
1644 int res = (validate_ntype(tree, try_stmt)
1645 && (nch >= 6) && ((nch % 3) == 0));
1646
1647 if (res)
1648 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001649 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001650 && validate_suite(CHILD(tree, 2))
1651 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001652 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001653 else {
1654 const char* name = "execpt";
1655 char buffer[60];
1656 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1657 name = STR(CHILD(tree, nch - 3));
1658 sprintf(buffer, "Illegal number of children for try/%s node.", name);
1659 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001660 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001661 /* Skip past except_clause sections: */
1662 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1663 res = (validate_except_clause(CHILD(tree, pos))
1664 && validate_colon(CHILD(tree, pos + 1))
1665 && validate_suite(CHILD(tree, pos + 2)));
1666 pos += 3;
1667 }
1668 if (res && (pos < nch)) {
1669 res = validate_ntype(CHILD(tree, pos), NAME);
1670 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1671 res = (validate_numnodes(tree, 6, "try/finally")
1672 && validate_colon(CHILD(tree, 4))
1673 && validate_suite(CHILD(tree, 5)));
1674 else if (res)
1675 if (nch == (pos + 3)) {
1676 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1677 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1678 if (!res)
1679 err_string("Illegal trailing triple in try statement.");
1680 }
1681 else if (nch == (pos + 6))
1682 res = (validate_name(CHILD(tree, pos), "except")
1683 && validate_colon(CHILD(tree, pos + 1))
1684 && validate_suite(CHILD(tree, pos + 2))
1685 && validate_name(CHILD(tree, pos + 3), "else"));
1686 else
1687 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001688 }
1689 return (res);
1690
1691} /* validate_try() */
1692
1693
Guido van Rossum47478871996-08-21 14:32:37 +00001694static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001695validate_except_clause(tree)
1696 node *tree;
1697{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001698 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001699 int res = (validate_ntype(tree, except_clause)
1700 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001701 && validate_name(CHILD(tree, 0), "except"));
1702
Guido van Rossum3d602e31996-07-21 02:33:56 +00001703 if (res && (nch > 1))
1704 res = validate_test(CHILD(tree, 1));
1705 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001706 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001707 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001708
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001709 return (res);
1710
1711} /* validate_except_clause() */
1712
1713
Guido van Rossum47478871996-08-21 14:32:37 +00001714static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001715validate_test(tree)
1716 node *tree;
1717{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001718 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001719 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001720
Guido van Rossum3d602e31996-07-21 02:33:56 +00001721 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001722 res = ((nch == 1)
1723 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001724 else if (res) {
1725 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001726 res = validate_and_test(CHILD(tree, 0));
1727 for (pos = 1; res && (pos < nch); pos += 2)
1728 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001729 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001730 }
1731 return (res);
1732
1733} /* validate_test() */
1734
1735
Guido van Rossum47478871996-08-21 14:32:37 +00001736static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001737validate_and_test(tree)
1738 node *tree;
1739{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001740 int pos;
1741 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001742 int res = (validate_ntype(tree, and_test)
1743 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001744 && validate_not_test(CHILD(tree, 0)));
1745
Guido van Rossum3d602e31996-07-21 02:33:56 +00001746 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001747 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001748 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001749
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001750 return (res);
1751
1752} /* validate_and_test() */
1753
1754
Guido van Rossum47478871996-08-21 14:32:37 +00001755static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001756validate_not_test(tree)
1757 node *tree;
1758{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001759 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001760 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001761
Guido van Rossum3d602e31996-07-21 02:33:56 +00001762 if (res) {
1763 if (nch == 2)
1764 res = (validate_name(CHILD(tree, 0), "not")
1765 && validate_not_test(CHILD(tree, 1)));
1766 else if (nch == 1)
1767 res = validate_comparison(CHILD(tree, 0));
1768 }
1769 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001770
1771} /* validate_not_test() */
1772
1773
Guido van Rossum47478871996-08-21 14:32:37 +00001774static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001775validate_comparison(tree)
1776 node *tree;
1777{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001778 int pos;
1779 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001780 int res = (validate_ntype(tree, comparison)
1781 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001782 && validate_expr(CHILD(tree, 0)));
1783
Guido van Rossum3d602e31996-07-21 02:33:56 +00001784 for (pos = 1; res && (pos < nch); pos += 2)
1785 res = (validate_comp_op(CHILD(tree, pos))
1786 && validate_expr(CHILD(tree, pos + 1)));
1787
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001788 return (res);
1789
1790} /* validate_comparison() */
1791
1792
Guido van Rossum47478871996-08-21 14:32:37 +00001793static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001794validate_comp_op(tree)
1795 node *tree;
1796{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001797 int res = 0;
1798 int nch = NCH(tree);
1799
Guido van Rossum3d602e31996-07-21 02:33:56 +00001800 if (!validate_ntype(tree, comp_op))
1801 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001802 if (nch == 1) {
1803 /*
1804 * Only child will be a terminal with a well-defined symbolic name
1805 * or a NAME with a string of either 'is' or 'in'
1806 */
1807 tree = CHILD(tree, 0);
1808 switch (TYPE(tree)) {
1809 case LESS:
1810 case GREATER:
1811 case EQEQUAL:
1812 case EQUAL:
1813 case LESSEQUAL:
1814 case GREATEREQUAL:
1815 case NOTEQUAL:
1816 res = 1;
1817 break;
1818 case NAME:
1819 res = ((strcmp(STR(tree), "in") == 0)
1820 || (strcmp(STR(tree), "is") == 0));
1821 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001822 char buff[128];
1823 sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1824 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001825 }
1826 break;
1827 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001828 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001829 break;
1830 }
1831 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001832 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001833 res = (validate_ntype(CHILD(tree, 0), NAME)
1834 && validate_ntype(CHILD(tree, 1), NAME)
1835 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1836 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1837 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1838 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001839 if (!res && !PyErr_Occurred())
1840 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001841 }
1842 return (res);
1843
1844} /* validate_comp_op() */
1845
1846
Guido van Rossum47478871996-08-21 14:32:37 +00001847static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001848validate_expr(tree)
1849 node *tree;
1850{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001851 int j;
1852 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001853 int res = (validate_ntype(tree, expr)
1854 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001855 && validate_xor_expr(CHILD(tree, 0)));
1856
Guido van Rossum3d602e31996-07-21 02:33:56 +00001857 for (j = 2; res && (j < nch); j += 2)
1858 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001859 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001860
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001861 return (res);
1862
1863} /* validate_expr() */
1864
1865
Guido van Rossum47478871996-08-21 14:32:37 +00001866static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001867validate_xor_expr(tree)
1868 node *tree;
1869{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001870 int j;
1871 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001872 int res = (validate_ntype(tree, xor_expr)
1873 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001874 && validate_and_expr(CHILD(tree, 0)));
1875
Guido van Rossum3d602e31996-07-21 02:33:56 +00001876 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001877 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001878 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001879
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001880 return (res);
1881
1882} /* validate_xor_expr() */
1883
1884
Guido van Rossum47478871996-08-21 14:32:37 +00001885static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001886validate_and_expr(tree)
1887 node *tree;
1888{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001889 int pos;
1890 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001891 int res = (validate_ntype(tree, and_expr)
1892 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001893 && validate_shift_expr(CHILD(tree, 0)));
1894
Guido van Rossum3d602e31996-07-21 02:33:56 +00001895 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001896 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001897 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001898
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001899 return (res);
1900
1901} /* validate_and_expr() */
1902
1903
1904static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001905validate_chain_two_ops(tree, termvalid, op1, op2)
1906 node *tree;
1907 int (*termvalid)();
1908 int op1;
1909 int op2;
1910 {
1911 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001912 int nch = NCH(tree);
1913 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001914 && (*termvalid)(CHILD(tree, 0)));
1915
Guido van Rossum3d602e31996-07-21 02:33:56 +00001916 for ( ; res && (pos < nch); pos += 2) {
1917 if (TYPE(CHILD(tree, pos)) != op1)
1918 res = validate_ntype(CHILD(tree, pos), op2);
1919 if (res)
1920 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001921 }
1922 return (res);
1923
1924} /* validate_chain_two_ops() */
1925
1926
Guido van Rossum47478871996-08-21 14:32:37 +00001927static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001928validate_shift_expr(tree)
1929 node *tree;
1930{
1931 return (validate_ntype(tree, shift_expr)
1932 && validate_chain_two_ops(tree, validate_arith_expr,
1933 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001934
1935} /* validate_shift_expr() */
1936
1937
Guido van Rossum47478871996-08-21 14:32:37 +00001938static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001939validate_arith_expr(tree)
1940 node *tree;
1941{
1942 return (validate_ntype(tree, arith_expr)
1943 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001944
1945} /* validate_arith_expr() */
1946
1947
Guido van Rossum47478871996-08-21 14:32:37 +00001948static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001949validate_term(tree)
1950 node *tree;
1951{
1952 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001953 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001954 int res = (validate_ntype(tree, term)
1955 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001956 && validate_factor(CHILD(tree, 0)));
1957
Guido van Rossum3d602e31996-07-21 02:33:56 +00001958 for ( ; res && (pos < nch); pos += 2)
1959 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001960 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001961 || (TYPE(CHILD(tree, pos)) == PERCENT))
1962 && validate_factor(CHILD(tree, pos + 1)));
1963
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001964 return (res);
1965
1966} /* validate_term() */
1967
1968
Guido van Rossum3d602e31996-07-21 02:33:56 +00001969/* factor:
1970 *
1971 * factor: ('+'|'-'|'~') factor | power
1972 */
Guido van Rossum47478871996-08-21 14:32:37 +00001973static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001974validate_factor(tree)
1975 node *tree;
1976{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001977 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001978 int res = (validate_ntype(tree, factor)
1979 && (((nch == 2)
1980 && ((TYPE(CHILD(tree, 0)) == PLUS)
1981 || (TYPE(CHILD(tree, 0)) == MINUS)
1982 || (TYPE(CHILD(tree, 0)) == TILDE))
1983 && validate_factor(CHILD(tree, 1)))
1984 || ((nch == 1)
1985 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001986 return (res);
1987
1988} /* validate_factor() */
1989
1990
Guido van Rossum3d602e31996-07-21 02:33:56 +00001991/* power:
1992 *
1993 * power: atom trailer* ('**' factor)*
1994 */
Guido van Rossum47478871996-08-21 14:32:37 +00001995static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001996validate_power(tree)
1997 node *tree;
1998{
1999 int pos = 1;
2000 int nch = NCH(tree);
2001 int res = (validate_ntype(tree, power) && (nch >= 1)
2002 && validate_atom(CHILD(tree, 0)));
2003
2004 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2005 res = validate_trailer(CHILD(tree, pos++));
2006 if (res && (pos < nch)) {
2007 if (!is_even(nch - pos)) {
2008 err_string("Illegal number of nodes for 'power'.");
2009 return (0);
2010 }
2011 for ( ; res && (pos < (nch - 1)); pos += 2)
2012 res = (validate_doublestar(CHILD(tree, pos))
2013 && validate_factor(CHILD(tree, pos + 1)));
2014 }
2015 return (res);
2016
2017} /* validate_power() */
2018
2019
Guido van Rossum47478871996-08-21 14:32:37 +00002020static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002021validate_atom(tree)
2022 node *tree;
2023{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002024 int pos;
2025 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002026 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002027
2028 if (res) {
2029 switch (TYPE(CHILD(tree, 0))) {
2030 case LPAR:
2031 res = ((nch <= 3)
2032 && (validate_rparen(CHILD(tree, nch - 1))));
2033
Guido van Rossum3d602e31996-07-21 02:33:56 +00002034 if (res && (nch == 3))
2035 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002036 break;
2037 case LSQB:
2038 res = ((nch <= 3)
2039 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2040
Guido van Rossum3d602e31996-07-21 02:33:56 +00002041 if (res && (nch == 3))
2042 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002043 break;
2044 case LBRACE:
2045 res = ((nch <= 3)
2046 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2047
Guido van Rossum3d602e31996-07-21 02:33:56 +00002048 if (res && (nch == 3))
2049 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002050 break;
2051 case BACKQUOTE:
2052 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002053 && validate_testlist(CHILD(tree, 1))
2054 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2055 break;
2056 case NAME:
2057 case NUMBER:
2058 res = (nch == 1);
2059 break;
2060 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002061 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002062 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002063 break;
2064 default:
2065 res = 0;
2066 break;
2067 }
2068 }
2069 return (res);
2070
2071} /* validate_atom() */
2072
2073
Guido van Rossum3d602e31996-07-21 02:33:56 +00002074/* funcdef:
2075 * 'def' NAME parameters ':' suite
2076 *
2077 */
Guido van Rossum47478871996-08-21 14:32:37 +00002078static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002079validate_funcdef(tree)
2080 node *tree;
2081{
2082 return (validate_ntype(tree, funcdef)
2083 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002084 && validate_name(CHILD(tree, 0), "def")
2085 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002086 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002087 && validate_parameters(CHILD(tree, 2))
2088 && validate_suite(CHILD(tree, 4)));
2089
2090} /* validate_funcdef() */
2091
2092
Guido van Rossum47478871996-08-21 14:32:37 +00002093static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002094validate_lambdef(tree)
2095 node *tree;
2096{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002097 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002098 int res = (validate_ntype(tree, lambdef)
2099 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002100 && validate_name(CHILD(tree, 0), "lambda")
2101 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002102 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002103
Guido van Rossum3d602e31996-07-21 02:33:56 +00002104 if (res && (nch == 4))
2105 res = validate_varargslist(CHILD(tree, 1));
2106 else if (!res && !PyErr_Occurred())
2107 validate_numnodes(tree, 3, "lambdef");
2108
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002109 return (res);
2110
2111} /* validate_lambdef() */
2112
2113
Guido van Rossum3d602e31996-07-21 02:33:56 +00002114/* arglist:
2115 *
2116 * argument (',' argument)* [',']
2117 */
Guido van Rossum47478871996-08-21 14:32:37 +00002118static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002119validate_arglist(tree)
2120 node *tree;
2121{
Guido van Rossum47478871996-08-21 14:32:37 +00002122 return (validate_repeating_list(tree, arglist,
2123 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002124
2125} /* validate_arglist() */
2126
2127
2128
2129/* argument:
2130 *
2131 * [test '='] test
2132 */
Guido van Rossum47478871996-08-21 14:32:37 +00002133static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002134validate_argument(tree)
2135 node *tree;
2136{
2137 int nch = NCH(tree);
2138 int res = (validate_ntype(tree, argument)
2139 && ((nch == 1) || (nch == 3))
2140 && validate_test(CHILD(tree, 0)));
2141
2142 if (res && (nch == 3))
2143 res = (validate_equal(CHILD(tree, 1))
2144 && validate_test(CHILD(tree, 2)));
2145
2146 return (res);
2147
2148} /* validate_argument() */
2149
2150
2151
2152/* trailer:
2153 *
Guido van Rossum47478871996-08-21 14:32:37 +00002154 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002155 */
Guido van Rossum47478871996-08-21 14:32:37 +00002156static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002157validate_trailer(tree)
2158 node *tree;
2159{
2160 int nch = NCH(tree);
2161 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002162
2163 if (res) {
2164 switch (TYPE(CHILD(tree, 0))) {
2165 case LPAR:
2166 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002167 if (res && (nch == 3))
2168 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002169 break;
2170 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002171 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002172 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002173 && validate_ntype(CHILD(tree, 2), RSQB));
2174 break;
2175 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002176 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002177 && validate_ntype(CHILD(tree, 1), NAME));
2178 break;
2179 default:
2180 res = 0;
2181 break;
2182 }
2183 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002184 else
2185 validate_numnodes(tree, 2, "trailer");
2186
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002187 return (res);
2188
2189} /* validate_trailer() */
2190
2191
Guido van Rossum47478871996-08-21 14:32:37 +00002192/* subscriptlist:
2193 *
2194 * subscript (',' subscript)* [',']
2195 */
2196static int
2197validate_subscriptlist(tree)
2198 node *tree;
2199{
2200 return (validate_repeating_list(tree, subscriptlist,
2201 validate_subscript, "subscriptlist"));
2202
2203} /* validate_subscriptlist() */
2204
2205
Guido van Rossum3d602e31996-07-21 02:33:56 +00002206/* subscript:
2207 *
Guido van Rossum47478871996-08-21 14:32:37 +00002208 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002209 */
Guido van Rossum47478871996-08-21 14:32:37 +00002210static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002211validate_subscript(tree)
2212 node *tree;
2213{
Guido van Rossum47478871996-08-21 14:32:37 +00002214 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002215 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002216 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002217
Guido van Rossum47478871996-08-21 14:32:37 +00002218 if (!res) {
2219 if (!PyErr_Occurred())
2220 err_string("invalid number of arguments for subscript node");
2221 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002222 }
Guido van Rossum47478871996-08-21 14:32:37 +00002223 if (TYPE(CHILD(tree, 0)) == DOT)
2224 /* take care of ('.' '.' '.') possibility */
2225 return (validate_numnodes(tree, 3, "subscript")
2226 && validate_dot(CHILD(tree, 0))
2227 && validate_dot(CHILD(tree, 1))
2228 && validate_dot(CHILD(tree, 2)));
2229 if (nch == 1) {
2230 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002231 res = validate_test(CHILD(tree, 0));
2232 else
Guido van Rossum47478871996-08-21 14:32:37 +00002233 res = validate_colon(CHILD(tree, 0));
2234 return (res);
2235 }
2236 /* Must be [test] ':' [test] [sliceop],
2237 * but at least one of the optional components will
2238 * be present, but we don't know which yet.
2239 */
2240 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2241 res = validate_test(CHILD(tree, 0));
2242 offset = 1;
2243 }
2244 if (res)
2245 res = validate_colon(CHILD(tree, offset));
2246 if (res) {
2247 int rem = nch - ++offset;
2248 if (rem) {
2249 if (TYPE(CHILD(tree, offset)) == test) {
2250 res = validate_test(CHILD(tree, offset));
2251 ++offset;
2252 --rem;
2253 }
2254 if (res && rem)
2255 res = validate_sliceop(CHILD(tree, offset));
2256 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002257 }
2258 return (res);
2259
2260} /* validate_subscript() */
2261
2262
Guido van Rossum47478871996-08-21 14:32:37 +00002263static int
2264validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002265 node *tree;
2266{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002267 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002268 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2269 && validate_ntype(tree, sliceop);
2270 if (!res && !PyErr_Occurred()) {
2271 validate_numnodes(tree, 1, "sliceop");
2272 res = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002273 }
Guido van Rossum47478871996-08-21 14:32:37 +00002274 if (res)
2275 res = validate_colon(CHILD(tree, 0));
2276 if (res && (nch == 2))
2277 res = validate_test(CHILD(tree, 1));
2278
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002279 return (res);
2280
Guido van Rossum47478871996-08-21 14:32:37 +00002281} /* validate_sliceop() */
2282
2283
2284static int
2285validate_exprlist(tree)
2286 node *tree;
2287{
2288 return (validate_repeating_list(tree, exprlist,
2289 validate_expr, "exprlist"));
2290
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002291} /* validate_exprlist() */
2292
2293
Guido van Rossum47478871996-08-21 14:32:37 +00002294static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002295validate_dictmaker(tree)
2296 node *tree;
2297{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002298 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002299 int res = (validate_ntype(tree, dictmaker)
2300 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002301 && validate_test(CHILD(tree, 0))
2302 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002303 && validate_test(CHILD(tree, 2)));
2304
Guido van Rossum3d602e31996-07-21 02:33:56 +00002305 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002306 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002307 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002308 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002309
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002310 if (res && (nch > 3)) {
2311 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002312 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002313 while (res && (pos < nch)) {
2314 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002315 && validate_test(CHILD(tree, pos + 1))
2316 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002317 && validate_test(CHILD(tree, pos + 3)));
2318 pos += 4;
2319 }
2320 }
2321 return (res);
2322
2323} /* validate_dictmaker() */
2324
2325
Guido van Rossum47478871996-08-21 14:32:37 +00002326static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002327validate_eval_input(tree)
2328 node *tree;
2329{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002330 int pos;
2331 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002332 int res = (validate_ntype(tree, eval_input)
2333 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002334 && validate_testlist(CHILD(tree, 0))
2335 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2336
Guido van Rossum3d602e31996-07-21 02:33:56 +00002337 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002338 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002339
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002340 return (res);
2341
2342} /* validate_eval_input() */
2343
2344
Guido van Rossum47478871996-08-21 14:32:37 +00002345static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002346validate_node(tree)
2347 node *tree;
2348{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002349 int nch = 0; /* num. children on current node */
2350 int res = 1; /* result value */
2351 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002352
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002353 while (res & (tree != 0)) {
2354 nch = NCH(tree);
2355 next = 0;
2356 switch (TYPE(tree)) {
2357 /*
2358 * Definition nodes.
2359 */
2360 case funcdef:
2361 res = validate_funcdef(tree);
2362 break;
2363 case classdef:
2364 res = validate_class(tree);
2365 break;
2366 /*
2367 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002368 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002369 */
2370 case stmt:
2371 res = validate_stmt(tree);
2372 break;
2373 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002374 /*
2375 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum47478871996-08-21 14:32:37 +00002376 * | import_stmt | global_stmt | exec_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002377 */
2378 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002379 break;
2380 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002381 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002382 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2383 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2384 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002385 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2386 if (res)
2387 next = CHILD(tree, 0);
2388 else if (nch == 1)
2389 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002390 break;
2391 /*
2392 * Compound statements.
2393 */
2394 case simple_stmt:
2395 res = validate_simple_stmt(tree);
2396 break;
2397 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002398 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002399 break;
2400 /*
2401 * Fundemental statements.
2402 */
2403 case expr_stmt:
2404 res = validate_expr_stmt(tree);
2405 break;
2406 case print_stmt:
2407 res = validate_print_stmt(tree);
2408 break;
2409 case del_stmt:
2410 res = validate_del_stmt(tree);
2411 break;
2412 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002413 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002414 && validate_name(CHILD(tree, 0), "pass"));
2415 break;
2416 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002417 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002418 && validate_name(CHILD(tree, 0), "break"));
2419 break;
2420 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002421 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002422 && validate_name(CHILD(tree, 0), "continue"));
2423 break;
2424 case return_stmt:
2425 res = validate_return_stmt(tree);
2426 break;
2427 case raise_stmt:
2428 res = validate_raise_stmt(tree);
2429 break;
2430 case import_stmt:
2431 res = validate_import_stmt(tree);
2432 break;
2433 case global_stmt:
2434 res = validate_global_stmt(tree);
2435 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002436 case exec_stmt:
2437 res = validate_exec_stmt(tree);
2438 break;
2439 case if_stmt:
2440 res = validate_if(tree);
2441 break;
2442 case while_stmt:
2443 res = validate_while(tree);
2444 break;
2445 case for_stmt:
2446 res = validate_for(tree);
2447 break;
2448 case try_stmt:
2449 res = validate_try(tree);
2450 break;
2451 case suite:
2452 res = validate_suite(tree);
2453 break;
2454 /*
2455 * Expression nodes.
2456 */
2457 case testlist:
2458 res = validate_testlist(tree);
2459 break;
2460 case test:
2461 res = validate_test(tree);
2462 break;
2463 case and_test:
2464 res = validate_and_test(tree);
2465 break;
2466 case not_test:
2467 res = validate_not_test(tree);
2468 break;
2469 case comparison:
2470 res = validate_comparison(tree);
2471 break;
2472 case exprlist:
2473 res = validate_exprlist(tree);
2474 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002475 case comp_op:
2476 res = validate_comp_op(tree);
2477 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002478 case expr:
2479 res = validate_expr(tree);
2480 break;
2481 case xor_expr:
2482 res = validate_xor_expr(tree);
2483 break;
2484 case and_expr:
2485 res = validate_and_expr(tree);
2486 break;
2487 case shift_expr:
2488 res = validate_shift_expr(tree);
2489 break;
2490 case arith_expr:
2491 res = validate_arith_expr(tree);
2492 break;
2493 case term:
2494 res = validate_term(tree);
2495 break;
2496 case factor:
2497 res = validate_factor(tree);
2498 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002499 case power:
2500 res = validate_power(tree);
2501 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002502 case atom:
2503 res = validate_atom(tree);
2504 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002505
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002506 default:
2507 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002508 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002509 res = 0;
2510 break;
2511 }
2512 tree = next;
2513 }
2514 return (res);
2515
2516} /* validate_node() */
2517
2518
Guido van Rossum47478871996-08-21 14:32:37 +00002519static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002520validate_expr_tree(tree)
2521 node *tree;
2522{
2523 int res = validate_eval_input(tree);
2524
2525 if (!res && !PyErr_Occurred())
2526 err_string("Could not validate expression tuple.");
2527
2528 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002529
2530} /* validate_expr_tree() */
2531
2532
Guido van Rossum3d602e31996-07-21 02:33:56 +00002533/* file_input:
2534 * (NEWLINE | stmt)* ENDMARKER
2535 */
Guido van Rossum47478871996-08-21 14:32:37 +00002536static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002537validate_file_input(tree)
2538 node *tree;
2539{
2540 int j = 0;
2541 int nch = NCH(tree) - 1;
2542 int res = ((nch >= 0)
2543 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002544
Guido van Rossum3d602e31996-07-21 02:33:56 +00002545 for ( ; res && (j < nch); ++j) {
2546 if (TYPE(CHILD(tree, j)) == stmt)
2547 res = validate_stmt(CHILD(tree, j));
2548 else
2549 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002550 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002551 /* This stays in to prevent any internal failues from getting to the
2552 * user. Hopefully, this won't be needed. If a user reports getting
2553 * this, we have some debugging to do.
2554 */
2555 if (!res && !PyErr_Occurred())
2556 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2557
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002558 return (res);
2559
Guido van Rossum2a288461996-08-21 21:55:43 +00002560} /* validate_file_input() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002561
2562
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002563/* Functions exported by this module. Most of this should probably
2564 * be converted into an AST object with methods, but that is better
2565 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002566 * We'd really have to write a wrapper around it all anyway to allow
2567 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002568 */
2569static PyMethodDef parser_functions[] = {
Guido van Rossum3d602e31996-07-21 02:33:56 +00002570 {"ast2tuple", parser_ast2tuple, 1,
2571 "Creates a tuple-tree representation of an AST."},
Guido van Rossum47478871996-08-21 14:32:37 +00002572 {"ast2list", parser_ast2list, 1,
2573 "Creates a list-tree representation of an AST."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002574 {"compileast", parser_compileast, 1,
2575 "Compiles an AST object into a code object."},
2576 {"expr", parser_expr, 1,
2577 "Creates an AST object from an expression."},
2578 {"isexpr", parser_isexpr, 1,
2579 "Determines if an AST object was created from an expression."},
2580 {"issuite", parser_issuite, 1,
2581 "Determines if an AST object was created from a suite."},
2582 {"suite", parser_suite, 1,
2583 "Creates an AST object from a suite."},
Guido van Rossum47478871996-08-21 14:32:37 +00002584 {"sequence2ast", parser_tuple2ast, 1,
2585 "Creates an AST object from a tree representation."},
Guido van Rossum3d602e31996-07-21 02:33:56 +00002586 {"tuple2ast", parser_tuple2ast, 1,
Guido van Rossum47478871996-08-21 14:32:37 +00002587 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002588
2589 {0, 0, 0}
2590 };
2591
2592
Guido van Rossum52f2c051993-11-10 12:53:24 +00002593void
Guido van Rossum3d602e31996-07-21 02:33:56 +00002594initparser()
2595 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002596 PyObject* module;
2597 PyObject* dict;
2598
2599 PyAST_Type.ob_type = &PyType_Type;
2600 module = Py_InitModule("parser", parser_functions);
2601 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002602
2603 parser_error = PyString_FromString("parser.ParserError");
2604
2605 if ((parser_error == 0)
2606 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2607 /*
2608 * This is serious.
2609 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002610 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002611 }
2612 /*
2613 * Nice to have, but don't cry if we fail.
2614 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002615 Py_INCREF(&PyAST_Type);
2616 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2617
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002618 PyDict_SetItemString(dict, "__copyright__",
2619 PyString_FromString(parser_copyright_string));
2620 PyDict_SetItemString(dict, "__doc__",
2621 PyString_FromString(parser_doc_string));
2622 PyDict_SetItemString(dict, "__version__",
2623 PyString_FromString(parser_version_string));
2624
2625} /* initparser() */
2626
2627
2628/*
Guido van Rossum3d602e31996-07-21 02:33:56 +00002629 * end of parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002630 */