blob: 8e9ca7e60e179b0a3c060e69184394e2938a9c25 [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.
Fred Drake268397f1998-04-29 14:16:32 +000020 *
21 * I've added some annotations that help with the lint code-checking
22 * program, but they're not complete by a long shot. The real errors
23 * that lint detects are gone, but there are still warnings with
24 * Py_[X]DECREF() and Py_[X]INCREF() macros. The lint annotations
25 * look like "NOTE(...)".
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000026 */
27
28#include "Python.h" /* general Python API */
29#include "graminit.h" /* symbols defined in the grammar */
30#include "node.h" /* internal parser structure */
31#include "token.h" /* token definitions */
32 /* ISTERMINAL() / ISNONTERMINAL() */
Guido van Rossum3d602e31996-07-21 02:33:56 +000033#include "compile.h" /* PyNode_Compile() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000034
Fred Drake268397f1998-04-29 14:16:32 +000035#ifdef lint
36#include <note.h>
37#else
38#define NOTE(x)
39#endif
40
Guido van Rossum19efc5f1998-04-28 16:10:19 +000041#ifdef macintosh
42char *strdup Py_PROTO((char *));
43#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000044
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000045/* String constants used to initialize module attributes.
46 *
47 */
48static char*
49parser_copyright_string
Guido van Rossum2a288461996-08-21 21:55:43 +000050= "Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
51University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
52Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\
53Centrum, Amsterdam, The Netherlands.";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000054
55
56static char*
57parser_doc_string
58= "This is an interface to Python's internal parser.";
59
60static char*
Guido van Rossum47478871996-08-21 14:32:37 +000061parser_version_string = "0.4";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000062
63
Guido van Rossum2a288461996-08-21 21:55:43 +000064typedef PyObject* (*SeqMaker) Py_PROTO((int length));
Fred Drake268397f1998-04-29 14:16:32 +000065typedef int (*SeqInserter) Py_PROTO((PyObject* sequence,
66 int index,
67 PyObject* element));
Guido van Rossum47478871996-08-21 14:32:37 +000068
Guido van Rossum3d602e31996-07-21 02:33:56 +000069/* The function below is copyrigthed by Stichting Mathematisch Centrum. The
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000070 * original copyright statement is included below, and continues to apply
71 * in full to the function immediately following. All other material is
72 * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
73 * Institute and State University. Changes were made to comply with the
Guido van Rossum2a288461996-08-21 21:55:43 +000074 * new naming conventions. Added arguments to provide support for creating
75 * lists as well as tuples, and optionally including the line numbers.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000076 */
77
Guido van Rossum52f2c051993-11-10 12:53:24 +000078/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +000079Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
80The Netherlands.
Guido van Rossum52f2c051993-11-10 12:53:24 +000081
82 All Rights Reserved
83
Guido van Rossum3d602e31996-07-21 02:33:56 +000084Permission to use, copy, modify, and distribute this software and its
85documentation for any purpose and without fee is hereby granted,
Guido van Rossum52f2c051993-11-10 12:53:24 +000086provided that the above copyright notice appear in all copies and that
Guido van Rossum3d602e31996-07-21 02:33:56 +000087both that copyright notice and this permission notice appear in
Guido van Rossum52f2c051993-11-10 12:53:24 +000088supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000089Centrum or CWI or Corporation for National Research Initiatives or
90CNRI not be used in advertising or publicity pertaining to
91distribution of the software without specific, written prior
92permission.
Guido van Rossum52f2c051993-11-10 12:53:24 +000093
Guido van Rossumd266eb41996-10-25 14:44:06 +000094While CWI is the initial source for this software, a modified version
95is made available by the Corporation for National Research Initiatives
96(CNRI) at the Internet address ftp://ftp.python.org.
97
98STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
99REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
100MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
101CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
102DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
103PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
104TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
105PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum52f2c051993-11-10 12:53:24 +0000106
107******************************************************************/
108
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000109static PyObject*
Guido van Rossum47478871996-08-21 14:32:37 +0000110node2tuple(n, mkseq, addelem, lineno)
111 node *n; /* node to convert */
112 SeqMaker mkseq; /* create sequence */
113 SeqInserter addelem; /* func. to add elem. in seq. */
114 int lineno; /* include line numbers? */
115{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000116 if (n == NULL) {
117 Py_INCREF(Py_None);
Fred Drake268397f1998-04-29 14:16:32 +0000118 return (Py_None);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000119 }
120 if (ISNONTERMINAL(TYPE(n))) {
121 int i;
Fred Drake268397f1998-04-29 14:16:32 +0000122 PyObject *v;
123 PyObject *w;
124
Guido van Rossum47478871996-08-21 14:32:37 +0000125 v = mkseq(1 + NCH(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000126 if (v == NULL)
Fred Drake268397f1998-04-29 14:16:32 +0000127 return (v);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000128 w = PyInt_FromLong(TYPE(n));
129 if (w == NULL) {
130 Py_DECREF(v);
Fred Drake268397f1998-04-29 14:16:32 +0000131 return ((PyObject*) NULL);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000132 }
Fred Drake268397f1998-04-29 14:16:32 +0000133 (void) addelem(v, 0, w);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000134 for (i = 0; i < NCH(n); i++) {
Guido van Rossum47478871996-08-21 14:32:37 +0000135 w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000136 if (w == NULL) {
137 Py_DECREF(v);
Fred Drake268397f1998-04-29 14:16:32 +0000138 return ((PyObject*) NULL);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000139 }
Fred Drake268397f1998-04-29 14:16:32 +0000140 (void) addelem(v, i+1, w);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000141 }
Guido van Rossum47478871996-08-21 14:32:37 +0000142 return (v);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000143 }
144 else if (ISTERMINAL(TYPE(n))) {
Guido van Rossum47478871996-08-21 14:32:37 +0000145 PyObject *result = mkseq(2 + lineno);
146 if (result != NULL) {
Fred Drake268397f1998-04-29 14:16:32 +0000147 (void) addelem(result, 0, PyInt_FromLong(TYPE(n)));
148 (void) addelem(result, 1, PyString_FromString(STR(n)));
Guido van Rossum47478871996-08-21 14:32:37 +0000149 if (lineno == 1)
Fred Drake268397f1998-04-29 14:16:32 +0000150 (void) addelem(result, 2, PyInt_FromLong(n->n_lineno));
Guido van Rossum47478871996-08-21 14:32:37 +0000151 }
152 return (result);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000153 }
154 else {
155 PyErr_SetString(PyExc_SystemError,
156 "unrecognized parse tree node type");
Fred Drake268397f1998-04-29 14:16:32 +0000157 return ((PyObject*) NULL);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000158 }
Guido van Rossum47478871996-08-21 14:32:37 +0000159} /* node2tuple() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000160/*
161 * End of material copyrighted by Stichting Mathematisch Centrum.
162 */
Guido van Rossum52f2c051993-11-10 12:53:24 +0000163
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000164
165
166/* There are two types of intermediate objects we're interested in:
167 * 'eval' and 'exec' types. These constants can be used in the ast_type
168 * field of the object type to identify which any given object represents.
169 * These should probably go in an external header to allow other extensions
170 * to use them, but then, we really should be using C++ too. ;-)
171 *
Guido van Rossum3d602e31996-07-21 02:33:56 +0000172 * The PyAST_FRAGMENT type is not currently supported. Maybe not useful?
173 * Haven't decided yet.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000174 */
175
176#define PyAST_EXPR 1
177#define PyAST_SUITE 2
178#define PyAST_FRAGMENT 3
179
180
181/* These are the internal objects and definitions required to implement the
182 * AST type. Most of the internal names are more reminiscent of the 'old'
183 * naming style, but the code uses the new naming convention.
184 */
185
186static PyObject*
187parser_error = 0;
188
189
190typedef struct _PyAST_Object {
191
192 PyObject_HEAD /* standard object header */
193 node* ast_node; /* the node* returned by the parser */
194 int ast_type; /* EXPR or SUITE ? */
195
196} PyAST_Object;
197
198
Fred Drake268397f1998-04-29 14:16:32 +0000199staticforward void
200parser_free Py_PROTO((PyAST_Object *ast));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000201
Fred Drake268397f1998-04-29 14:16:32 +0000202staticforward int
203parser_compare Py_PROTO((PyAST_Object *left, PyAST_Object *right));
204
205staticforward PyObject *
206parser_getattr Py_PROTO((PyObject *self, char *name));
Fred Drake503d8d61998-04-13 18:45:18 +0000207
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000208
Fred Drake268397f1998-04-29 14:16:32 +0000209static
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000210PyTypeObject PyAST_Type = {
211
Guido van Rossum3c8c5981998-05-29 02:58:20 +0000212 PyObject_HEAD_INIT(NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000213 0,
214 "ast", /* tp_name */
Fred Drake268397f1998-04-29 14:16:32 +0000215 (int) sizeof(PyAST_Object), /* tp_basicsize */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000216 0, /* tp_itemsize */
217 (destructor)parser_free, /* tp_dealloc */
218 0, /* tp_print */
Fred Drake503d8d61998-04-13 18:45:18 +0000219 parser_getattr, /* tp_getattr */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000220 0, /* tp_setattr */
221 (cmpfunc)parser_compare, /* tp_compare */
222 0, /* tp_repr */
223 0, /* tp_as_number */
224 0, /* tp_as_sequence */
225 0, /* tp_as_mapping */
226 0, /* tp_hash */
227 0, /* tp_call */
Fred Drake69b9ae41997-05-23 04:04:17 +0000228 0, /* tp_str */
229 0, /* tp_getattro */
230 0, /* tp_setattro */
231
232 /* Functions to access object as input/output buffer */
233 0, /* tp_as_buffer */
234
235 /* Space for future expansion */
236 0, /* tp_xxx4 */
237
238 /* __doc__ */
239 "Intermediate representation of a Python parse tree."
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000240
241}; /* PyAST_Type */
242
243
244static int
245parser_compare_nodes(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000246 node *left;
247 node *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000248{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000249 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000250
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000251 if (TYPE(left) < TYPE(right))
252 return (-1);
253
254 if (TYPE(right) < TYPE(left))
255 return (1);
256
257 if (ISTERMINAL(TYPE(left)))
258 return (strcmp(STR(left), STR(right)));
259
260 if (NCH(left) < NCH(right))
261 return (-1);
262
263 if (NCH(right) < NCH(left))
264 return (1);
265
266 for (j = 0; j < NCH(left); ++j) {
267 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
268
Fred Drakeed3da231998-05-11 03:31:16 +0000269 if (v != 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000270 return (v);
271 }
272 return (0);
273
274} /* parser_compare_nodes() */
275
276
277/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
278 *
279 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
280 * This really just wraps a call to parser_compare_nodes() with some easy
281 * checks and protection code.
282 *
283 */
284static int
285parser_compare(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000286 PyAST_Object *left;
287 PyAST_Object *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000288{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000289 if (left == right)
290 return (0);
291
292 if ((left == 0) || (right == 0))
293 return (-1);
294
295 return (parser_compare_nodes(left->ast_node, right->ast_node));
296
297} /* parser_compare() */
298
299
300/* parser_newastobject(node* ast)
301 *
302 * Allocates a new Python object representing an AST. This is simply the
303 * 'wrapper' object that holds a node* and allows it to be passed around in
304 * Python code.
305 *
306 */
307static PyObject*
308parser_newastobject(ast, type)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000309 node *ast;
310 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000311{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000312 PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
313
314 if (o != 0) {
315 o->ast_node = ast;
316 o->ast_type = type;
317 }
Fred Drake268397f1998-04-29 14:16:32 +0000318 else {
319 PyNode_Free(ast);
320 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000321 return ((PyObject*)o);
322
323} /* parser_newastobject() */
324
325
326/* void parser_free(PyAST_Object* ast)
327 *
328 * This is called by a del statement that reduces the reference count to 0.
329 *
330 */
331static void
332parser_free(ast)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000333 PyAST_Object *ast;
Guido van Rossum47478871996-08-21 14:32:37 +0000334{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000335 PyNode_Free(ast->ast_node);
336 PyMem_DEL(ast);
337
338} /* parser_free() */
339
340
Fred Drake2a6875e1999-09-20 22:32:18 +0000341/* parser_ast2tuple(PyObject* self, PyObject* args, PyObject* kw)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000342 *
343 * This provides conversion from a node* to a tuple object that can be
344 * returned to the Python-level caller. The AST object is not modified.
345 *
346 */
347static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000348parser_ast2tuple(self, args, kw)
Fred Drake503d8d61998-04-13 18:45:18 +0000349 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000350 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000351 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000352{
Guido van Rossum47478871996-08-21 14:32:37 +0000353 PyObject *line_option = 0;
354 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000355 int ok;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000356
Fred Drake7a15ba51999-09-09 14:21:52 +0000357 static char *keywords[] = {"ast", "line_info", NULL};
358
Fred Drake268397f1998-04-29 14:16:32 +0000359 if (self == NULL) {
Fred Drake7a15ba51999-09-09 14:21:52 +0000360 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:ast2tuple", keywords,
361 &PyAST_Type, &self, &line_option);
Fred Drake268397f1998-04-29 14:16:32 +0000362 }
Fred Drake503d8d61998-04-13 18:45:18 +0000363 else
Fred Drake7a15ba51999-09-09 14:21:52 +0000364 ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:totuple", &keywords[1],
365 &line_option);
Fred Drake268397f1998-04-29 14:16:32 +0000366 if (ok != 0) {
Guido van Rossum47478871996-08-21 14:32:37 +0000367 int lineno = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000368 if (line_option != NULL) {
Fred Drake268397f1998-04-29 14:16:32 +0000369 lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000370 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000371 /*
372 * Convert AST into a tuple representation. Use Guido's function,
373 * since it's known to work already.
374 */
Fred Drake503d8d61998-04-13 18:45:18 +0000375 res = node2tuple(((PyAST_Object*)self)->ast_node,
Guido van Rossum47478871996-08-21 14:32:37 +0000376 PyTuple_New, PyTuple_SetItem, lineno);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000377 }
378 return (res);
379
380} /* parser_ast2tuple() */
381
382
Fred Drake2a6875e1999-09-20 22:32:18 +0000383/* parser_ast2list(PyObject* self, PyObject* args, PyObject* kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000384 *
Fred Drake2a6875e1999-09-20 22:32:18 +0000385 * This provides conversion from a node* to a list object that can be
Guido van Rossum47478871996-08-21 14:32:37 +0000386 * returned to the Python-level caller. The AST object is not modified.
387 *
388 */
389static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000390parser_ast2list(self, args, kw)
Fred Drake503d8d61998-04-13 18:45:18 +0000391 PyAST_Object *self;
Guido van Rossum47478871996-08-21 14:32:37 +0000392 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000393 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000394{
Guido van Rossum47478871996-08-21 14:32:37 +0000395 PyObject *line_option = 0;
396 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000397 int ok;
Guido van Rossum47478871996-08-21 14:32:37 +0000398
Fred Drake7a15ba51999-09-09 14:21:52 +0000399 static char *keywords[] = {"ast", "line_info", NULL};
400
Fred Drake503d8d61998-04-13 18:45:18 +0000401 if (self == NULL)
Fred Drake7a15ba51999-09-09 14:21:52 +0000402 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:ast2list", keywords,
403 &PyAST_Type, &self, &line_option);
Fred Drake503d8d61998-04-13 18:45:18 +0000404 else
Fred Drake7a15ba51999-09-09 14:21:52 +0000405 ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1],
406 &line_option);
Fred Drake503d8d61998-04-13 18:45:18 +0000407 if (ok) {
Guido van Rossum47478871996-08-21 14:32:37 +0000408 int lineno = 0;
409 if (line_option != 0) {
Fred Drake503d8d61998-04-13 18:45:18 +0000410 lineno = PyObject_IsTrue(line_option) ? 1 : 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000411 }
412 /*
413 * Convert AST into a tuple representation. Use Guido's function,
414 * since it's known to work already.
415 */
Fred Drake268397f1998-04-29 14:16:32 +0000416 res = node2tuple(self->ast_node,
Guido van Rossum47478871996-08-21 14:32:37 +0000417 PyList_New, PyList_SetItem, lineno);
418 }
419 return (res);
420
421} /* parser_ast2list() */
422
423
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000424/* parser_compileast(PyObject* self, PyObject* args)
425 *
426 * This function creates code objects from the parse tree represented by
427 * the passed-in data object. An optional file name is passed in as well.
428 *
429 */
430static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000431parser_compileast(self, args, kw)
Fred Drake503d8d61998-04-13 18:45:18 +0000432 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000433 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000434 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000435{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000436 PyObject* res = 0;
437 char* str = "<ast>";
Fred Drake503d8d61998-04-13 18:45:18 +0000438 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000439
Fred Drake7a15ba51999-09-09 14:21:52 +0000440 static char *keywords[] = {"ast", "filename", NULL};
441
Fred Drake503d8d61998-04-13 18:45:18 +0000442 if (self == NULL)
Fred Drake7a15ba51999-09-09 14:21:52 +0000443 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compileast", keywords,
444 &PyAST_Type, &self, &str);
Fred Drake503d8d61998-04-13 18:45:18 +0000445 else
Fred Drake7a15ba51999-09-09 14:21:52 +0000446 ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1],
447 &str);
Fred Drake503d8d61998-04-13 18:45:18 +0000448
449 if (ok)
450 res = (PyObject *)PyNode_Compile(self->ast_node, str);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000451
452 return (res);
453
454} /* parser_compileast() */
455
456
457/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
458 * PyObject* parser_issuite(PyObject* self, PyObject* args)
459 *
460 * Checks the passed-in AST object to determine if it is an expression or
461 * a statement suite, respectively. The return is a Python truth value.
462 *
463 */
464static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000465parser_isexpr(self, args, kw)
Fred Drake503d8d61998-04-13 18:45:18 +0000466 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000467 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000468 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000469{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000470 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000471 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000472
Fred Drake7a15ba51999-09-09 14:21:52 +0000473 static char *keywords[] = {"ast", NULL};
474
Fred Drake503d8d61998-04-13 18:45:18 +0000475 if (self == NULL)
Fred Drake7a15ba51999-09-09 14:21:52 +0000476 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
477 &PyAST_Type, &self);
Fred Drake503d8d61998-04-13 18:45:18 +0000478 else
Fred Drake7a15ba51999-09-09 14:21:52 +0000479 ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]);
Fred Drake503d8d61998-04-13 18:45:18 +0000480
481 if (ok) {
482 /* Check to see if the AST represents an expression or not. */
483 res = (self->ast_type == PyAST_EXPR) ? Py_True : Py_False;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000484 Py_INCREF(res);
485 }
486 return (res);
487
488} /* parser_isexpr() */
489
490
491static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000492parser_issuite(self, args, kw)
Fred Drake503d8d61998-04-13 18:45:18 +0000493 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000494 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000495 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000496{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000497 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000498 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000499
Fred Drake7a15ba51999-09-09 14:21:52 +0000500 static char *keywords[] = {"ast", NULL};
501
Fred Drake503d8d61998-04-13 18:45:18 +0000502 if (self == NULL)
Fred Drake7a15ba51999-09-09 14:21:52 +0000503 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
504 &PyAST_Type, &self);
Fred Drake503d8d61998-04-13 18:45:18 +0000505 else
Fred Drake7a15ba51999-09-09 14:21:52 +0000506 ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]);
Fred Drake503d8d61998-04-13 18:45:18 +0000507
508 if (ok) {
509 /* Check to see if the AST represents an expression or not. */
510 res = (self->ast_type == PyAST_EXPR) ? Py_False : Py_True;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000511 Py_INCREF(res);
512 }
513 return (res);
514
515} /* parser_issuite() */
516
517
Fred Drake7a15ba51999-09-09 14:21:52 +0000518#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS)
519
Fred Drake503d8d61998-04-13 18:45:18 +0000520static PyMethodDef
521parser_methods[] = {
Fred Drake7a15ba51999-09-09 14:21:52 +0000522 {"compile", (PyCFunction)parser_compileast, PUBLIC_METHOD_TYPE,
Fred Drake301b5be1998-04-21 22:31:45 +0000523 "Compile this AST object into a code object."},
Fred Drake7a15ba51999-09-09 14:21:52 +0000524 {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
Fred Drake301b5be1998-04-21 22:31:45 +0000525 "Determines if this AST object was created from an expression."},
Fred Drake7a15ba51999-09-09 14:21:52 +0000526 {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
Fred Drake301b5be1998-04-21 22:31:45 +0000527 "Determines if this AST object was created from a suite."},
Fred Drake7a15ba51999-09-09 14:21:52 +0000528 {"tolist", (PyCFunction)parser_ast2list, PUBLIC_METHOD_TYPE,
Fred Drake301b5be1998-04-21 22:31:45 +0000529 "Creates a list-tree representation of this AST."},
Fred Drake7a15ba51999-09-09 14:21:52 +0000530 {"totuple", (PyCFunction)parser_ast2tuple, PUBLIC_METHOD_TYPE,
Fred Drake301b5be1998-04-21 22:31:45 +0000531 "Creates a tuple-tree representation of this AST."},
Fred Drake503d8d61998-04-13 18:45:18 +0000532
Fred Drake268397f1998-04-29 14:16:32 +0000533 {NULL, NULL, 0, NULL}
Fred Drake503d8d61998-04-13 18:45:18 +0000534};
535
Fred Drake503d8d61998-04-13 18:45:18 +0000536
537static PyObject*
538parser_getattr(self, name)
539 PyObject *self;
540 char *name;
541{
Fred Drake503d8d61998-04-13 18:45:18 +0000542 return (Py_FindMethod(parser_methods, self, name));
543
544} /* parser_getattr() */
545
546
Guido van Rossum3d602e31996-07-21 02:33:56 +0000547/* err_string(char* message)
548 *
549 * Sets the error string for an exception of type ParserError.
550 *
551 */
552static void
553err_string(message)
554 char *message;
Guido van Rossum47478871996-08-21 14:32:37 +0000555{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000556 PyErr_SetString(parser_error, message);
557
558} /* err_string() */
559
560
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000561/* PyObject* parser_do_parse(PyObject* args, int type)
562 *
563 * Internal function to actually execute the parse and return the result if
564 * successful, or set an exception if not.
565 *
566 */
567static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000568parser_do_parse(args, kw, argspec, type)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000569 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000570 PyObject *kw;
571 char *argspec;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000572 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000573{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000574 char* string = 0;
575 PyObject* res = 0;
576
Fred Drake7a15ba51999-09-09 14:21:52 +0000577 static char *keywords[] = {"source", NULL};
578
579 if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000580 node* n = PyParser_SimpleParseString(string,
581 (type == PyAST_EXPR)
582 ? eval_input : file_input);
583
584 if (n != 0)
585 res = parser_newastobject(n, type);
586 else
Guido van Rossum3d602e31996-07-21 02:33:56 +0000587 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000588 }
589 return (res);
590
591} /* parser_do_parse() */
592
593
594/* PyObject* parser_expr(PyObject* self, PyObject* args)
595 * PyObject* parser_suite(PyObject* self, PyObject* args)
596 *
597 * External interfaces to the parser itself. Which is called determines if
598 * the parser attempts to recognize an expression ('eval' form) or statement
599 * suite ('exec' form). The real work is done by parser_do_parse() above.
600 *
601 */
602static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000603parser_expr(self, args, kw)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000604 PyObject *self;
605 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000606 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000607{
Fred Drake268397f1998-04-29 14:16:32 +0000608 NOTE(ARGUNUSED(self))
Fred Drake7a15ba51999-09-09 14:21:52 +0000609 return (parser_do_parse(args, kw, "s:expr", PyAST_EXPR));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000610
611} /* parser_expr() */
612
613
614static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000615parser_suite(self, args, kw)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000616 PyObject *self;
617 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000618 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000619{
Fred Drake268397f1998-04-29 14:16:32 +0000620 NOTE(ARGUNUSED(self))
Fred Drake7a15ba51999-09-09 14:21:52 +0000621 return (parser_do_parse(args, kw, "s:suite", PyAST_SUITE));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000622
623} /* parser_suite() */
624
625
626
627/* This is the messy part of the code. Conversion from a tuple to an AST
628 * object requires that the input tuple be valid without having to rely on
629 * catching an exception from the compiler. This is done to allow the
630 * compiler itself to remain fast, since most of its input will come from
631 * the parser directly, and therefore be known to be syntactically correct.
632 * This validation is done to ensure that we don't core dump the compile
633 * phase, returning an exception instead.
634 *
635 * Two aspects can be broken out in this code: creating a node tree from
636 * the tuple passed in, and verifying that it is indeed valid. It may be
637 * advantageous to expand the number of AST types to include funcdefs and
638 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
639 * here. They are not necessary, and not quite as useful in a raw form.
640 * For now, let's get expressions and suites working reliably.
641 */
642
643
Guido van Rossum2a288461996-08-21 21:55:43 +0000644staticforward node* build_node_tree Py_PROTO((PyObject *tuple));
645staticforward int validate_expr_tree Py_PROTO((node *tree));
646staticforward int validate_file_input Py_PROTO((node *tree));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000647
648
649/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
650 *
651 * This is the public function, called from the Python code. It receives a
652 * single tuple object from the caller, and creates an AST object if the
653 * tuple can be validated. It does this by checking the first code of the
654 * tuple, and, if acceptable, builds the internal representation. If this
655 * step succeeds, the internal representation is validated as fully as
656 * possible with the various validate_*() routines defined below.
657 *
658 * This function must be changed if support is to be added for PyAST_FRAGMENT
659 * AST objects.
660 *
661 */
662static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000663parser_tuple2ast(self, args, kw)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000664 PyObject *self;
665 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000666 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000667{
Fred Drake268397f1998-04-29 14:16:32 +0000668 NOTE(ARGUNUSED(self))
Guido van Rossum47478871996-08-21 14:32:37 +0000669 PyObject *ast = 0;
670 PyObject *tuple = 0;
671 PyObject *temp = 0;
672 int ok;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000673 int start_sym = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000674
Fred Drake7a15ba51999-09-09 14:21:52 +0000675 static char *keywords[] = {"sequence", NULL};
676
677 if (!PyArg_ParseTupleAndKeywords(args, kw, "O:tuple2ast", keywords,
678 &tuple))
Guido van Rossum47478871996-08-21 14:32:37 +0000679 return (0);
680 if (!PySequence_Check(tuple)) {
681 PyErr_SetString(PyExc_ValueError,
682 "tuple2ast() requires a single sequence argument");
683 return (0);
684 }
685 /*
686 * This mess of tests is written this way so we can use the abstract
687 * object interface (AOI). Unfortunately, the AOI increments reference
688 * counts, which requires that we store a pointer to retrieved object
689 * so we can DECREF it after the check. But we really should accept
690 * lists as well as tuples at the very least.
691 */
692 ok = PyObject_Length(tuple) >= 2;
693 if (ok) {
694 temp = PySequence_GetItem(tuple, 0);
695 ok = (temp != NULL) && PyInt_Check(temp);
696 if (ok)
697 /* this is used after the initial checks: */
Fred Drake1a566ff1999-02-17 17:35:53 +0000698 start_sym = PyInt_AS_LONG(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000699 Py_XDECREF(temp);
700 }
701 if (ok) {
702 temp = PySequence_GetItem(tuple, 1);
703 ok = (temp != NULL) && PySequence_Check(temp);
704 Py_XDECREF(temp);
705 }
706 if (ok) {
707 temp = PySequence_GetItem(tuple, 1);
708 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
709 if (ok) {
710 PyObject *temp2 = PySequence_GetItem(temp, 0);
711 if (temp2 != NULL) {
712 ok = PyInt_Check(temp2);
713 Py_DECREF(temp2);
714 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000715 }
Guido van Rossum47478871996-08-21 14:32:37 +0000716 Py_XDECREF(temp);
717 }
718 /* If we've failed at some point, get out of here. */
719 if (!ok) {
720 err_string("malformed sequence for tuple2ast()");
721 return (0);
722 }
723 /*
724 * This might be a valid parse tree, but let's do a quick check
725 * before we jump the gun.
726 */
727 if (start_sym == eval_input) {
728 /* Might be an eval form. */
729 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000730
Guido van Rossum47478871996-08-21 14:32:37 +0000731 if ((expression != 0) && validate_expr_tree(expression))
732 ast = parser_newastobject(expression, PyAST_EXPR);
733 }
734 else if (start_sym == file_input) {
735 /* This looks like an exec form so far. */
736 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000737
Guido van Rossum47478871996-08-21 14:32:37 +0000738 if ((suite_tree != 0) && validate_file_input(suite_tree))
739 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000740 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000741 else
Guido van Rossum47478871996-08-21 14:32:37 +0000742 /* This is a fragment, and is not yet supported. Maybe they
743 * will be if I find a use for them.
744 */
745 err_string("Fragmentary parse trees not supported.");
746
747 /* Make sure we throw an exception on all errors. We should never
748 * get this, but we'd do well to be sure something is done.
749 */
750 if ((ast == 0) && !PyErr_Occurred())
751 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000752
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000753 return (ast);
754
755} /* parser_tuple2ast() */
756
757
758/* int check_terminal_tuple()
759 *
Guido van Rossum47478871996-08-21 14:32:37 +0000760 * Check a tuple to determine that it is indeed a valid terminal
761 * node. The node is known to be required as a terminal, so we throw
762 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000763 *
Guido van Rossum47478871996-08-21 14:32:37 +0000764 * The format of an acceptable terminal tuple is "(is[i])": the fact
765 * that elem is a tuple and the integer is a valid terminal symbol
766 * has been established before this function is called. We must
767 * check the length of the tuple and the type of the second element
768 * and optional third element. We do *NOT* check the actual text of
769 * the string element, which we could do in many cases. This is done
770 * by the validate_*() functions which operate on the internal
771 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000772 */
773static int
Guido van Rossum47478871996-08-21 14:32:37 +0000774check_terminal_tuple(elem)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000775 PyObject *elem;
Guido van Rossum47478871996-08-21 14:32:37 +0000776{
777 int len = PyObject_Length(elem);
778 int res = 1;
779 char* str = "Illegal terminal symbol; bad node length.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000780
Guido van Rossum47478871996-08-21 14:32:37 +0000781 if ((len == 2) || (len == 3)) {
782 PyObject *temp = PySequence_GetItem(elem, 1);
783 res = PyString_Check(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000784 str = "Illegal terminal symbol; expected a string.";
Guido van Rossum47478871996-08-21 14:32:37 +0000785 if (res && (len == 3)) {
786 PyObject* third = PySequence_GetItem(elem, 2);
787 res = PyInt_Check(third);
788 str = "Invalid third element of terminal node.";
789 Py_XDECREF(third);
790 }
791 Py_XDECREF(temp);
792 }
793 else {
794 res = 0;
795 }
796 if (!res) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000797 elem = Py_BuildValue("(os)", elem, str);
798 PyErr_SetObject(parser_error, elem);
799 }
800 return (res);
801
802} /* check_terminal_tuple() */
803
804
805/* node* build_node_children()
806 *
807 * Iterate across the children of the current non-terminal node and build
808 * their structures. If successful, return the root of this portion of
809 * the tree, otherwise, 0. Any required exception will be specified already,
810 * and no memory will have been deallocated.
811 *
812 */
813static node*
814build_node_children(tuple, root, line_num)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000815 PyObject *tuple;
816 node *root;
817 int *line_num;
Guido van Rossum47478871996-08-21 14:32:37 +0000818{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000819 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000820 int i;
821
822 for (i = 1; i < len; ++i) {
823 /* elem must always be a tuple, however simple */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000824 PyObject* elem = PySequence_GetItem(tuple, i);
Guido van Rossum47478871996-08-21 14:32:37 +0000825 int ok = elem != NULL;
826 long type = 0;
827 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000828
Guido van Rossum47478871996-08-21 14:32:37 +0000829 if (ok)
830 ok = PySequence_Check(elem);
831 if (ok) {
832 PyObject *temp = PySequence_GetItem(elem, 0);
833 if (temp == NULL)
834 ok = 0;
835 else {
836 ok = PyInt_Check(temp);
837 if (ok)
Fred Drake1a566ff1999-02-17 17:35:53 +0000838 type = PyInt_AS_LONG(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000839 Py_DECREF(temp);
840 }
841 }
842 if (!ok) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000843 PyErr_SetObject(parser_error,
844 Py_BuildValue("(os)", elem,
845 "Illegal node construct."));
Guido van Rossum47478871996-08-21 14:32:37 +0000846 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000847 return (0);
848 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000849 if (ISTERMINAL(type)) {
Guido van Rossum47478871996-08-21 14:32:37 +0000850 if (check_terminal_tuple(elem)) {
851 PyObject *temp = PySequence_GetItem(elem, 1);
852
Fred Draked49266e1997-10-09 16:29:31 +0000853 /* check_terminal_tuple() already verified it's a string */
854 strn = (char *)malloc(PyString_GET_SIZE(temp) + 1);
855 if (strn != NULL)
Fred Drake268397f1998-04-29 14:16:32 +0000856 (void) strcpy(strn, PyString_AS_STRING(temp));
Guido van Rossum47478871996-08-21 14:32:37 +0000857 Py_XDECREF(temp);
858
859 if (PyObject_Length(elem) == 3) {
860 PyObject* temp = PySequence_GetItem(elem, 2);
861 *line_num = PyInt_AsLong(temp);
862 Py_DECREF(temp);
863 }
864 }
865 else {
866 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000867 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000868 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000869 }
870 else if (!ISNONTERMINAL(type)) {
871 /*
872 * It has to be one or the other; this is an error.
873 * Throw an exception.
874 */
875 PyErr_SetObject(parser_error,
876 Py_BuildValue("(os)", elem,
877 "Unknown node type."));
Guido van Rossum47478871996-08-21 14:32:37 +0000878 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000879 return (0);
880 }
881 PyNode_AddChild(root, type, strn, *line_num);
882
883 if (ISNONTERMINAL(type)) {
884 node* new_child = CHILD(root, i - 1);
885
Guido van Rossum47478871996-08-21 14:32:37 +0000886 if (new_child != build_node_children(elem, new_child, line_num)) {
887 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000888 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000889 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000890 }
Guido van Rossum47478871996-08-21 14:32:37 +0000891 else if (type == NEWLINE) { /* It's true: we increment the */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000892 ++(*line_num); /* line number *after* the newline! */
Guido van Rossum47478871996-08-21 14:32:37 +0000893 }
894 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000895 }
896 return (root);
897
898} /* build_node_children() */
899
900
901static node*
902build_node_tree(tuple)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000903 PyObject *tuple;
Guido van Rossum47478871996-08-21 14:32:37 +0000904{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000905 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000906 PyObject *temp = PySequence_GetItem(tuple, 0);
907 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000908
Guido van Rossum47478871996-08-21 14:32:37 +0000909 if (temp != NULL)
910 num = PyInt_AsLong(temp);
911 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000912 if (ISTERMINAL(num)) {
913 /*
914 * The tuple is simple, but it doesn't start with a start symbol.
915 * Throw an exception now and be done with it.
916 */
917 tuple = Py_BuildValue("(os)", tuple,
Guido van Rossum3d602e31996-07-21 02:33:56 +0000918 "Illegal ast tuple; cannot start with terminal symbol.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000919 PyErr_SetObject(parser_error, tuple);
920 }
921 else if (ISNONTERMINAL(num)) {
922 /*
923 * Not efficient, but that can be handled later.
924 */
925 int line_num = 0;
926
927 res = PyNode_New(num);
928 if (res != build_node_children(tuple, res, &line_num)) {
929 PyNode_Free(res);
930 res = 0;
931 }
932 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000933 else
934 /* The tuple is illegal -- if the number is neither TERMINAL nor
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000935 * NONTERMINAL, we can't use it.
936 */
937 PyErr_SetObject(parser_error,
938 Py_BuildValue("(os)", tuple,
939 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000940
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000941 return (res);
942
943} /* build_node_tree() */
944
945
Guido van Rossum360a9341996-08-21 19:04:10 +0000946#ifdef HAVE_OLD_CPP
Guido van Rossum2a288461996-08-21 21:55:43 +0000947#define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000948#else
Guido van Rossum2a288461996-08-21 21:55:43 +0000949#define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000950#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000951
952
953/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000954 * Validation routines used within the validation section:
955 */
Guido van Rossum2a288461996-08-21 21:55:43 +0000956staticforward int validate_terminal Py_PROTO((node *terminal,
957 int type, char *string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000958
959#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
960#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
961#define validate_colon(ch) validate_terminal(ch, COLON, ":")
962#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
963#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
964#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Fred Drake268397f1998-04-29 14:16:32 +0000965#define validate_indent(ch) validate_terminal(ch, INDENT, (char*)NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000966#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Fred Drake268397f1998-04-29 14:16:32 +0000967#define validate_newline(ch) validate_terminal(ch, NEWLINE, (char*)NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000968#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
969#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
970#define validate_star(ch) validate_terminal(ch, STAR, "*")
971#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000972#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
Guido van Rossum47478871996-08-21 14:32:37 +0000973#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000974#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000975
Guido van Rossum3d602e31996-07-21 02:33:56 +0000976VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000977VALIDATER(class); VALIDATER(node);
978VALIDATER(parameters); VALIDATER(suite);
979VALIDATER(testlist); VALIDATER(varargslist);
980VALIDATER(fpdef); VALIDATER(fplist);
981VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000982VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000983VALIDATER(print_stmt); VALIDATER(del_stmt);
984VALIDATER(return_stmt);
985VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000986VALIDATER(global_stmt);
Guido van Rossum925e5471997-04-02 05:32:13 +0000987VALIDATER(assert_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000988VALIDATER(exec_stmt); VALIDATER(compound_stmt);
989VALIDATER(while); VALIDATER(for);
990VALIDATER(try); VALIDATER(except_clause);
991VALIDATER(test); VALIDATER(and_test);
992VALIDATER(not_test); VALIDATER(comparison);
993VALIDATER(comp_op); VALIDATER(expr);
994VALIDATER(xor_expr); VALIDATER(and_expr);
995VALIDATER(shift_expr); VALIDATER(arith_expr);
996VALIDATER(term); VALIDATER(factor);
997VALIDATER(atom); VALIDATER(lambdef);
998VALIDATER(trailer); VALIDATER(subscript);
Guido van Rossum47478871996-08-21 14:32:37 +0000999VALIDATER(subscriptlist); VALIDATER(sliceop);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001000VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001001VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001002
1003
1004#define is_even(n) (((n) & 1) == 0)
1005#define is_odd(n) (((n) & 1) == 1)
1006
1007
1008static int
1009validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001010 node *n;
1011 int t;
Guido van Rossum47478871996-08-21 14:32:37 +00001012{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001013 int res = (TYPE(n) == t);
1014
1015 if (!res) {
1016 char buffer[128];
Fred Drake268397f1998-04-29 14:16:32 +00001017 (void) sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001018 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001019 }
1020 return (res);
1021
1022} /* validate_ntype() */
1023
1024
1025static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001026validate_numnodes(n, num, name)
1027 node *n;
1028 int num;
1029 const char *const name;
Guido van Rossum47478871996-08-21 14:32:37 +00001030{
Guido van Rossum3d602e31996-07-21 02:33:56 +00001031 if (NCH(n) != num) {
1032 char buff[60];
Fred Drake268397f1998-04-29 14:16:32 +00001033 (void) sprintf(buff, "Illegal number of children for %s node.", name);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001034 err_string(buff);
1035 }
1036 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001037
Guido van Rossum3d602e31996-07-21 02:33:56 +00001038} /* validate_numnodes() */
1039
1040
1041static int
1042validate_terminal(terminal, type, string)
1043 node *terminal;
1044 int type;
1045 char *string;
Guido van Rossum47478871996-08-21 14:32:37 +00001046{
Guido van Rossum3d602e31996-07-21 02:33:56 +00001047 int res = (validate_ntype(terminal, type)
1048 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
1049
1050 if (!res && !PyErr_Occurred()) {
1051 char buffer[60];
Fred Drake268397f1998-04-29 14:16:32 +00001052 (void) sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001053 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001054 }
1055 return (res);
1056
1057} /* validate_terminal() */
1058
1059
Guido van Rossum47478871996-08-21 14:32:37 +00001060/* X (',' X) [',']
1061 */
1062static int
1063validate_repeating_list(tree, ntype, vfunc, name)
1064 node *tree;
1065 int ntype;
1066 int (*vfunc)();
1067 const char *const name;
1068{
1069 int nch = NCH(tree);
1070 int res = (nch && validate_ntype(tree, ntype)
1071 && vfunc(CHILD(tree, 0)));
1072
1073 if (!res && !PyErr_Occurred())
Fred Drake268397f1998-04-29 14:16:32 +00001074 (void) validate_numnodes(tree, 1, name);
Guido van Rossum47478871996-08-21 14:32:37 +00001075 else {
1076 if (is_even(nch))
1077 res = validate_comma(CHILD(tree, --nch));
1078 if (res && nch > 1) {
1079 int pos = 1;
1080 for ( ; res && pos < nch; pos += 2)
1081 res = (validate_comma(CHILD(tree, pos))
1082 && vfunc(CHILD(tree, pos + 1)));
1083 }
1084 }
1085 return (res);
1086
1087} /* validate_repeating_list() */
1088
1089
Guido van Rossum3d602e31996-07-21 02:33:56 +00001090/* VALIDATE(class)
1091 *
1092 * classdef:
1093 * 'class' NAME ['(' testlist ')'] ':' suite
1094 */
Guido van Rossum47478871996-08-21 14:32:37 +00001095static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001096validate_class(tree)
1097 node *tree;
1098{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001099 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001100 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001101
Guido van Rossum3d602e31996-07-21 02:33:56 +00001102 if (res) {
1103 res = (validate_name(CHILD(tree, 0), "class")
1104 && validate_ntype(CHILD(tree, 1), NAME)
1105 && validate_colon(CHILD(tree, nch - 2))
1106 && validate_suite(CHILD(tree, nch - 1)));
1107 }
1108 else
Fred Drake268397f1998-04-29 14:16:32 +00001109 (void) validate_numnodes(tree, 4, "class");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001110 if (res && (nch == 7)) {
1111 res = (validate_lparen(CHILD(tree, 2))
1112 && validate_testlist(CHILD(tree, 3))
1113 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001114 }
1115 return (res);
1116
1117} /* validate_class() */
1118
1119
Guido van Rossum3d602e31996-07-21 02:33:56 +00001120/* if_stmt:
1121 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1122 */
Guido van Rossum47478871996-08-21 14:32:37 +00001123static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001124validate_if(tree)
1125 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001126{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001127 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001128 int res = (validate_ntype(tree, if_stmt)
1129 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001130 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +00001131 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001132 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001133 && validate_suite(CHILD(tree, 3)));
1134
1135 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001136 /* ... 'else' ':' suite */
1137 res = (validate_name(CHILD(tree, nch - 3), "else")
1138 && validate_colon(CHILD(tree, nch - 2))
1139 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001140 nch -= 3;
1141 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001142 else if (!res && !PyErr_Occurred())
Fred Drake268397f1998-04-29 14:16:32 +00001143 (void) validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001144 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001145 /* Will catch the case for nch < 4 */
1146 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001147 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001148 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001149 int j = 4;
1150 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001151 res = (validate_name(CHILD(tree, j), "elif")
1152 && validate_colon(CHILD(tree, j + 2))
1153 && validate_test(CHILD(tree, j + 1))
1154 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001155 j += 4;
1156 }
1157 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001158 return (res);
1159
1160} /* validate_if() */
1161
1162
Guido van Rossum3d602e31996-07-21 02:33:56 +00001163/* parameters:
1164 * '(' [varargslist] ')'
1165 *
1166 */
Guido van Rossum47478871996-08-21 14:32:37 +00001167static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001168validate_parameters(tree)
1169 node *tree;
1170{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001171 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001172 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001173
Guido van Rossum3d602e31996-07-21 02:33:56 +00001174 if (res) {
1175 res = (validate_lparen(CHILD(tree, 0))
1176 && validate_rparen(CHILD(tree, nch - 1)));
1177 if (res && (nch == 3))
1178 res = validate_varargslist(CHILD(tree, 1));
1179 }
1180 else
Fred Drake268397f1998-04-29 14:16:32 +00001181 (void) validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001182
1183 return (res);
1184
1185} /* validate_parameters() */
1186
1187
Guido van Rossum3d602e31996-07-21 02:33:56 +00001188/* VALIDATE(suite)
1189 *
1190 * suite:
1191 * simple_stmt
1192 * | NEWLINE INDENT stmt+ DEDENT
1193 */
Guido van Rossum47478871996-08-21 14:32:37 +00001194static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001195validate_suite(tree)
1196 node *tree;
1197{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001198 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001199 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001200
Guido van Rossum3d602e31996-07-21 02:33:56 +00001201 if (res && (nch == 1))
1202 res = validate_simple_stmt(CHILD(tree, 0));
1203 else if (res) {
1204 /* NEWLINE INDENT stmt+ DEDENT */
1205 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001206 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001207 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001208 && validate_dedent(CHILD(tree, nch - 1)));
1209
Guido van Rossum3d602e31996-07-21 02:33:56 +00001210 if (res && (nch > 4)) {
1211 int i = 3;
1212 --nch; /* forget the DEDENT */
1213 for ( ; res && (i < nch); ++i)
1214 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001215 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001216 else if (nch < 4)
Fred Drake268397f1998-04-29 14:16:32 +00001217 res = validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001218 }
1219 return (res);
1220
1221} /* validate_suite() */
1222
1223
Guido van Rossum47478871996-08-21 14:32:37 +00001224static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001225validate_testlist(tree)
1226 node *tree;
1227{
Guido van Rossum47478871996-08-21 14:32:37 +00001228 return (validate_repeating_list(tree, testlist,
1229 validate_test, "testlist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001230
1231} /* validate_testlist() */
1232
1233
Guido van Rossum3d602e31996-07-21 02:33:56 +00001234/* VALIDATE(varargslist)
1235 *
1236 * varargslist:
1237 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1238 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1239 *
1240 * (fpdef ['=' test] ',')*
1241 * ('*' NAME [',' ('**'|'*' '*') NAME]
1242 * | ('**'|'*' '*') NAME)
1243 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1244 *
1245 */
Guido van Rossum47478871996-08-21 14:32:37 +00001246static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001247validate_varargslist(tree)
1248 node *tree;
1249{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001250 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001251 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001252
Guido van Rossum3d602e31996-07-21 02:33:56 +00001253 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1254 /* (fpdef ['=' test] ',')*
1255 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1256 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001257 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001258 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001259
Guido van Rossum3d602e31996-07-21 02:33:56 +00001260 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1261 res = validate_fpdef(CHILD(tree, pos));
1262 if (res) {
1263 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1264 res = validate_test(CHILD(tree, pos + 2));
1265 pos += 2;
1266 }
1267 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001268 pos += 2;
1269 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001270 }
1271 if (res) {
1272 remaining = nch - pos;
1273 res = ((remaining == 2) || (remaining == 3)
1274 || (remaining == 5) || (remaining == 6));
1275 if (!res)
Fred Drake268397f1998-04-29 14:16:32 +00001276 (void) validate_numnodes(tree, 2, "varargslist");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001277 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1278 return ((remaining == 2)
1279 && validate_ntype(CHILD(tree, pos+1), NAME));
1280 else {
1281 res = validate_star(CHILD(tree, pos++));
1282 --remaining;
1283 }
1284 }
1285 if (res) {
1286 if (remaining == 2) {
1287 res = (validate_star(CHILD(tree, pos))
1288 && validate_ntype(CHILD(tree, pos + 1), NAME));
1289 }
1290 else {
1291 res = validate_ntype(CHILD(tree, pos++), NAME);
1292 if (res && (remaining >= 4)) {
1293 res = validate_comma(CHILD(tree, pos));
1294 if (--remaining == 3)
Fred Drakee1607a81996-09-11 21:58:26 +00001295 res = (validate_star(CHILD(tree, pos + 1))
1296 && validate_star(CHILD(tree, pos + 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001297 else
Fred Drake268397f1998-04-29 14:16:32 +00001298 res = validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001299 }
1300 }
1301 }
1302 if (!res && !PyErr_Occurred())
1303 err_string("Incorrect validation of variable arguments list.");
1304 }
1305 else if (res) {
1306 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1307 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1308 --nch;
1309
1310 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1311 res = (is_odd(nch)
1312 && validate_fpdef(CHILD(tree, 0)));
1313
1314 if (res && (nch > 1)) {
1315 int pos = 1;
1316 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1317 res = validate_test(CHILD(tree, 2));
1318 pos += 2;
1319 }
1320 /* ... (',' fpdef ['=' test])* */
1321 for ( ; res && (pos < nch); pos += 2) {
1322 /* ',' fpdef */
1323 res = (validate_comma(CHILD(tree, pos))
1324 && validate_fpdef(CHILD(tree, pos + 1)));
1325 if (res
1326 && ((nch - pos) > 2)
1327 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1328 /* ['=' test] */
1329 res = validate_test(CHILD(tree, pos + 3));
1330 pos += 2;
1331 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001332 }
1333 }
1334 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001335 else
1336 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001337
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001338 return (res);
1339
1340} /* validate_varargslist() */
1341
1342
Guido van Rossum3d602e31996-07-21 02:33:56 +00001343/* VALIDATE(fpdef)
1344 *
1345 * fpdef:
1346 * NAME
1347 * | '(' fplist ')'
1348 */
Guido van Rossum47478871996-08-21 14:32:37 +00001349static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001350validate_fpdef(tree)
1351 node *tree;
1352{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001353 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001354 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001355
Guido van Rossum3d602e31996-07-21 02:33:56 +00001356 if (res) {
1357 if (nch == 1)
1358 res = validate_ntype(CHILD(tree, 0), NAME);
1359 else if (nch == 3)
1360 res = (validate_lparen(CHILD(tree, 0))
1361 && validate_fplist(CHILD(tree, 1))
1362 && validate_rparen(CHILD(tree, 2)));
1363 else
Fred Drake268397f1998-04-29 14:16:32 +00001364 res = validate_numnodes(tree, 1, "fpdef");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001365 }
1366 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001367
1368} /* validate_fpdef() */
1369
1370
Guido van Rossum47478871996-08-21 14:32:37 +00001371static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001372validate_fplist(tree)
1373 node *tree;
1374{
Guido van Rossum47478871996-08-21 14:32:37 +00001375 return (validate_repeating_list(tree, fplist,
1376 validate_fpdef, "fplist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001377
1378} /* validate_fplist() */
1379
1380
Guido van Rossum3d602e31996-07-21 02:33:56 +00001381/* simple_stmt | compound_stmt
1382 *
1383 */
Guido van Rossum47478871996-08-21 14:32:37 +00001384static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001385validate_stmt(tree)
1386 node *tree;
1387{
1388 int res = (validate_ntype(tree, stmt)
1389 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001390
Guido van Rossum3d602e31996-07-21 02:33:56 +00001391 if (res) {
1392 tree = CHILD(tree, 0);
1393
1394 if (TYPE(tree) == simple_stmt)
1395 res = validate_simple_stmt(tree);
1396 else
1397 res = validate_compound_stmt(tree);
1398 }
1399 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001400
1401} /* validate_stmt() */
1402
1403
Guido van Rossum3d602e31996-07-21 02:33:56 +00001404/* small_stmt (';' small_stmt)* [';'] NEWLINE
1405 *
1406 */
Guido van Rossum47478871996-08-21 14:32:37 +00001407static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001408validate_simple_stmt(tree)
1409 node *tree;
1410{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001411 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001412 int res = (validate_ntype(tree, simple_stmt)
1413 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001414 && validate_small_stmt(CHILD(tree, 0))
1415 && validate_newline(CHILD(tree, nch - 1)));
1416
Guido van Rossum3d602e31996-07-21 02:33:56 +00001417 if (nch < 2)
1418 res = validate_numnodes(tree, 2, "simple_stmt");
1419 --nch; /* forget the NEWLINE */
1420 if (res && is_even(nch))
1421 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001422 if (res && (nch > 2)) {
1423 int i;
1424
Guido van Rossum3d602e31996-07-21 02:33:56 +00001425 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001426 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001427 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001428 }
1429 return (res);
1430
1431} /* validate_simple_stmt() */
1432
1433
Guido van Rossum47478871996-08-21 14:32:37 +00001434static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001435validate_small_stmt(tree)
1436 node *tree;
1437{
1438 int nch = NCH(tree);
1439 int res = (validate_numnodes(tree, 1, "small_stmt")
1440 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1441 || (TYPE(CHILD(tree, 0)) == print_stmt)
1442 || (TYPE(CHILD(tree, 0)) == del_stmt)
1443 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1444 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1445 || (TYPE(CHILD(tree, 0)) == import_stmt)
1446 || (TYPE(CHILD(tree, 0)) == global_stmt)
Guido van Rossum925e5471997-04-02 05:32:13 +00001447 || (TYPE(CHILD(tree, 0)) == assert_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001448 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1449
1450 if (res)
1451 res = validate_node(CHILD(tree, 0));
1452 else if (nch == 1) {
1453 char buffer[60];
Fred Drake268397f1998-04-29 14:16:32 +00001454 (void) sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1455 TYPE(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001456 err_string(buffer);
1457 }
1458 return (res);
1459
1460} /* validate_small_stmt */
1461
1462
1463/* compound_stmt:
1464 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1465 */
Guido van Rossum47478871996-08-21 14:32:37 +00001466static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001467validate_compound_stmt(tree)
1468 node *tree;
1469{
1470 int res = (validate_ntype(tree, compound_stmt)
1471 && validate_numnodes(tree, 1, "compound_stmt"));
1472
1473 if (!res)
1474 return (0);
1475
1476 tree = CHILD(tree, 0);
1477 res = ((TYPE(tree) == if_stmt)
1478 || (TYPE(tree) == while_stmt)
1479 || (TYPE(tree) == for_stmt)
1480 || (TYPE(tree) == try_stmt)
1481 || (TYPE(tree) == funcdef)
1482 || (TYPE(tree) == classdef));
1483 if (res)
1484 res = validate_node(tree);
1485 else {
1486 char buffer[60];
Fred Drake268397f1998-04-29 14:16:32 +00001487 (void) sprintf(buffer, "Illegal compound statement type: %d.",
1488 TYPE(tree));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001489 err_string(buffer);
1490 }
1491 return (res);
1492
1493} /* validate_compound_stmt() */
1494
1495
Guido van Rossum47478871996-08-21 14:32:37 +00001496static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001497validate_expr_stmt(tree)
1498 node *tree;
1499{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001500 int j;
1501 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001502 int res = (validate_ntype(tree, expr_stmt)
1503 && is_odd(nch)
1504 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001505
Guido van Rossum3d602e31996-07-21 02:33:56 +00001506 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001507 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001508 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001509
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001510 return (res);
1511
1512} /* validate_expr_stmt() */
1513
1514
Guido van Rossum3d602e31996-07-21 02:33:56 +00001515/* print_stmt:
1516 *
1517 * 'print' (test ',')* [test]
1518 *
1519 */
Guido van Rossum47478871996-08-21 14:32:37 +00001520static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001521validate_print_stmt(tree)
1522 node *tree;
1523{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001524 int j;
1525 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001526 int res = (validate_ntype(tree, print_stmt)
1527 && (nch != 0)
1528 && validate_name(CHILD(tree, 0), "print"));
1529
1530 if (res && is_even(nch)) {
1531 res = validate_test(CHILD(tree, nch - 1));
1532 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001533 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001534 else if (!res && !PyErr_Occurred())
Fred Drake268397f1998-04-29 14:16:32 +00001535 (void) validate_numnodes(tree, 1, "print_stmt");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001536 for (j = 1; res && (j < nch); j += 2)
1537 res = (validate_test(CHILD(tree, j))
1538 && validate_ntype(CHILD(tree, j + 1), COMMA));
1539
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001540 return (res);
1541
1542} /* validate_print_stmt() */
1543
1544
Guido van Rossum47478871996-08-21 14:32:37 +00001545static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001546validate_del_stmt(tree)
1547 node *tree;
1548{
1549 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001550 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001551 && validate_exprlist(CHILD(tree, 1)));
1552
1553} /* validate_del_stmt() */
1554
1555
Guido van Rossum47478871996-08-21 14:32:37 +00001556static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001557validate_return_stmt(tree)
1558 node *tree;
1559{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001560 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001561 int res = (validate_ntype(tree, return_stmt)
1562 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001563 && validate_name(CHILD(tree, 0), "return"));
1564
Guido van Rossum3d602e31996-07-21 02:33:56 +00001565 if (res && (nch == 2))
1566 res = validate_testlist(CHILD(tree, 1));
1567
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001568 return (res);
1569
1570} /* validate_return_stmt() */
1571
1572
Guido van Rossum47478871996-08-21 14:32:37 +00001573static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001574validate_raise_stmt(tree)
1575 node *tree;
1576{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001577 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001578 int res = (validate_ntype(tree, raise_stmt)
Fred Drakec542bc71998-04-10 04:43:28 +00001579 && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001580
Guido van Rossum3d602e31996-07-21 02:33:56 +00001581 if (res) {
Fred Drakec542bc71998-04-10 04:43:28 +00001582 res = validate_name(CHILD(tree, 0), "raise");
1583 if (res && (nch >= 2))
1584 res = validate_test(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001585 if (res && nch > 2) {
1586 res = (validate_comma(CHILD(tree, 2))
1587 && validate_test(CHILD(tree, 3)));
1588 if (res && (nch > 4))
1589 res = (validate_comma(CHILD(tree, 4))
1590 && validate_test(CHILD(tree, 5)));
1591 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001592 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001593 else
Fred Drake268397f1998-04-29 14:16:32 +00001594 (void) validate_numnodes(tree, 2, "raise");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001595 if (res && (nch == 4))
1596 res = (validate_comma(CHILD(tree, 2))
1597 && validate_test(CHILD(tree, 3)));
1598
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001599 return (res);
1600
1601} /* validate_raise_stmt() */
1602
1603
Guido van Rossum3d602e31996-07-21 02:33:56 +00001604/* import_stmt:
1605 *
1606 * 'import' dotted_name (',' dotted_name)*
1607 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1608 */
Guido van Rossum47478871996-08-21 14:32:37 +00001609static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001610validate_import_stmt(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, import_stmt)
1615 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001616 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001617 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001618
1619 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001620 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001621
Guido van Rossum3d602e31996-07-21 02:33:56 +00001622 for (j = 2; res && (j < nch); j += 2)
1623 res = (validate_comma(CHILD(tree, j))
1624 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001625 }
1626 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001627 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001628 && validate_name(CHILD(tree, 2), "import"));
1629 if (nch == 4) {
1630 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001631 || (TYPE(CHILD(tree, 3)) == STAR));
1632 if (!res)
1633 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001634 }
1635 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001636 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001637 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001638 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001639 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001640 res = (validate_comma(CHILD(tree, j))
1641 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001642 }
1643 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001644 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001645 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001646
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001647 return (res);
1648
1649} /* validate_import_stmt() */
1650
1651
Guido van Rossum47478871996-08-21 14:32:37 +00001652static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001653validate_global_stmt(tree)
1654 node *tree;
1655{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001656 int j;
1657 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001658 int res = (validate_ntype(tree, global_stmt)
1659 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001660
Guido van Rossum3d602e31996-07-21 02:33:56 +00001661 if (res)
1662 res = (validate_name(CHILD(tree, 0), "global")
1663 && validate_ntype(CHILD(tree, 1), NAME));
1664 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001665 res = (validate_comma(CHILD(tree, j))
1666 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001667
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001668 return (res);
1669
1670} /* validate_global_stmt() */
1671
1672
Guido van Rossum3d602e31996-07-21 02:33:56 +00001673/* exec_stmt:
1674 *
1675 * 'exec' expr ['in' test [',' test]]
1676 */
Guido van Rossum47478871996-08-21 14:32:37 +00001677static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001678validate_exec_stmt(tree)
1679 node *tree;
1680{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001681 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001682 int res = (validate_ntype(tree, exec_stmt)
1683 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001684 && validate_name(CHILD(tree, 0), "exec")
1685 && validate_expr(CHILD(tree, 1)));
1686
Guido van Rossum3d602e31996-07-21 02:33:56 +00001687 if (!res && !PyErr_Occurred())
1688 err_string("Illegal exec statement.");
1689 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001690 res = (validate_name(CHILD(tree, 2), "in")
1691 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001692 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001693 res = (validate_comma(CHILD(tree, 4))
1694 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001695
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001696 return (res);
1697
1698} /* validate_exec_stmt() */
1699
1700
Guido van Rossum925e5471997-04-02 05:32:13 +00001701/* assert_stmt:
1702 *
1703 * 'assert' test [',' test]
1704 */
1705static int
1706validate_assert_stmt(tree)
1707 node *tree;
1708{
1709 int nch = NCH(tree);
1710 int res = (validate_ntype(tree, assert_stmt)
1711 && ((nch == 2) || (nch == 4))
1712 && (validate_name(CHILD(tree, 0), "__assert__") ||
1713 validate_name(CHILD(tree, 0), "assert"))
1714 && validate_test(CHILD(tree, 1)));
1715
1716 if (!res && !PyErr_Occurred())
1717 err_string("Illegal assert statement.");
1718 if (res && (nch > 2))
1719 res = (validate_comma(CHILD(tree, 2))
1720 && validate_test(CHILD(tree, 3)));
1721
1722 return (res);
1723
1724} /* validate_assert_stmt() */
1725
1726
Guido van Rossum47478871996-08-21 14:32:37 +00001727static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001728validate_while(tree)
1729 node *tree;
1730{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001731 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001732 int res = (validate_ntype(tree, while_stmt)
1733 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001734 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001735 && validate_test(CHILD(tree, 1))
1736 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001737 && validate_suite(CHILD(tree, 3)));
1738
Guido van Rossum3d602e31996-07-21 02:33:56 +00001739 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001740 res = (validate_name(CHILD(tree, 4), "else")
1741 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001742 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001743
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001744 return (res);
1745
1746} /* validate_while() */
1747
1748
Guido van Rossum47478871996-08-21 14:32:37 +00001749static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001750validate_for(tree)
1751 node *tree;
1752{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001753 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001754 int res = (validate_ntype(tree, for_stmt)
1755 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001756 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001757 && validate_exprlist(CHILD(tree, 1))
1758 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001759 && validate_testlist(CHILD(tree, 3))
1760 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001761 && validate_suite(CHILD(tree, 5)));
1762
Guido van Rossum3d602e31996-07-21 02:33:56 +00001763 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001764 res = (validate_name(CHILD(tree, 6), "else")
1765 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001766 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001767
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001768 return (res);
1769
1770} /* validate_for() */
1771
1772
Guido van Rossum3d602e31996-07-21 02:33:56 +00001773/* try_stmt:
1774 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1775 * | 'try' ':' suite 'finally' ':' suite
1776 *
1777 */
Guido van Rossum47478871996-08-21 14:32:37 +00001778static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001779validate_try(tree)
1780 node *tree;
1781{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001782 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001783 int pos = 3;
1784 int res = (validate_ntype(tree, try_stmt)
1785 && (nch >= 6) && ((nch % 3) == 0));
1786
1787 if (res)
1788 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001789 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001790 && validate_suite(CHILD(tree, 2))
1791 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001792 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001793 else {
1794 const char* name = "execpt";
1795 char buffer[60];
1796 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1797 name = STR(CHILD(tree, nch - 3));
Fred Drake268397f1998-04-29 14:16:32 +00001798 (void) sprintf(buffer,
1799 "Illegal number of children for try/%s node.", name);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001800 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001801 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001802 /* Skip past except_clause sections: */
1803 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1804 res = (validate_except_clause(CHILD(tree, pos))
1805 && validate_colon(CHILD(tree, pos + 1))
1806 && validate_suite(CHILD(tree, pos + 2)));
1807 pos += 3;
1808 }
1809 if (res && (pos < nch)) {
1810 res = validate_ntype(CHILD(tree, pos), NAME);
1811 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1812 res = (validate_numnodes(tree, 6, "try/finally")
1813 && validate_colon(CHILD(tree, 4))
1814 && validate_suite(CHILD(tree, 5)));
Guido van Rossum730806d1998-04-10 22:27:42 +00001815 else if (res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001816 if (nch == (pos + 3)) {
1817 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1818 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1819 if (!res)
1820 err_string("Illegal trailing triple in try statement.");
1821 }
Guido van Rossum730806d1998-04-10 22:27:42 +00001822 else if (nch == (pos + 6)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001823 res = (validate_name(CHILD(tree, pos), "except")
1824 && validate_colon(CHILD(tree, pos + 1))
1825 && validate_suite(CHILD(tree, pos + 2))
1826 && validate_name(CHILD(tree, pos + 3), "else"));
Guido van Rossum730806d1998-04-10 22:27:42 +00001827 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001828 else
1829 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossum730806d1998-04-10 22:27:42 +00001830 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001831 }
1832 return (res);
1833
1834} /* validate_try() */
1835
1836
Guido van Rossum47478871996-08-21 14:32:37 +00001837static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001838validate_except_clause(tree)
1839 node *tree;
1840{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001841 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001842 int res = (validate_ntype(tree, except_clause)
1843 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001844 && validate_name(CHILD(tree, 0), "except"));
1845
Guido van Rossum3d602e31996-07-21 02:33:56 +00001846 if (res && (nch > 1))
1847 res = validate_test(CHILD(tree, 1));
1848 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001849 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001850 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001851
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001852 return (res);
1853
1854} /* validate_except_clause() */
1855
1856
Guido van Rossum47478871996-08-21 14:32:37 +00001857static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001858validate_test(tree)
1859 node *tree;
1860{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001861 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001862 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001863
Guido van Rossum3d602e31996-07-21 02:33:56 +00001864 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001865 res = ((nch == 1)
1866 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001867 else if (res) {
1868 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001869 res = validate_and_test(CHILD(tree, 0));
1870 for (pos = 1; res && (pos < nch); pos += 2)
1871 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001872 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001873 }
1874 return (res);
1875
1876} /* validate_test() */
1877
1878
Guido van Rossum47478871996-08-21 14:32:37 +00001879static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001880validate_and_test(tree)
1881 node *tree;
1882{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001883 int pos;
1884 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001885 int res = (validate_ntype(tree, and_test)
1886 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001887 && validate_not_test(CHILD(tree, 0)));
1888
Guido van Rossum3d602e31996-07-21 02:33:56 +00001889 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001890 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001891 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001892
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001893 return (res);
1894
1895} /* validate_and_test() */
1896
1897
Guido van Rossum47478871996-08-21 14:32:37 +00001898static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001899validate_not_test(tree)
1900 node *tree;
1901{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001902 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001903 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001904
Guido van Rossum3d602e31996-07-21 02:33:56 +00001905 if (res) {
1906 if (nch == 2)
1907 res = (validate_name(CHILD(tree, 0), "not")
1908 && validate_not_test(CHILD(tree, 1)));
1909 else if (nch == 1)
1910 res = validate_comparison(CHILD(tree, 0));
1911 }
1912 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001913
1914} /* validate_not_test() */
1915
1916
Guido van Rossum47478871996-08-21 14:32:37 +00001917static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001918validate_comparison(tree)
1919 node *tree;
1920{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001921 int pos;
1922 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001923 int res = (validate_ntype(tree, comparison)
1924 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001925 && validate_expr(CHILD(tree, 0)));
1926
Guido van Rossum3d602e31996-07-21 02:33:56 +00001927 for (pos = 1; res && (pos < nch); pos += 2)
1928 res = (validate_comp_op(CHILD(tree, pos))
1929 && validate_expr(CHILD(tree, pos + 1)));
1930
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001931 return (res);
1932
1933} /* validate_comparison() */
1934
1935
Guido van Rossum47478871996-08-21 14:32:37 +00001936static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001937validate_comp_op(tree)
1938 node *tree;
1939{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001940 int res = 0;
1941 int nch = NCH(tree);
1942
Guido van Rossum3d602e31996-07-21 02:33:56 +00001943 if (!validate_ntype(tree, comp_op))
1944 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001945 if (nch == 1) {
1946 /*
1947 * Only child will be a terminal with a well-defined symbolic name
1948 * or a NAME with a string of either 'is' or 'in'
1949 */
1950 tree = CHILD(tree, 0);
1951 switch (TYPE(tree)) {
1952 case LESS:
1953 case GREATER:
1954 case EQEQUAL:
1955 case EQUAL:
1956 case LESSEQUAL:
1957 case GREATEREQUAL:
1958 case NOTEQUAL:
1959 res = 1;
1960 break;
1961 case NAME:
1962 res = ((strcmp(STR(tree), "in") == 0)
1963 || (strcmp(STR(tree), "is") == 0));
1964 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001965 char buff[128];
Fred Drake268397f1998-04-29 14:16:32 +00001966 (void) sprintf(buff, "Illegal operator: '%s'.", STR(tree));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001967 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001968 }
1969 break;
1970 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001971 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001972 break;
1973 }
1974 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001975 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001976 res = (validate_ntype(CHILD(tree, 0), NAME)
1977 && validate_ntype(CHILD(tree, 1), NAME)
1978 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1979 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1980 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1981 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001982 if (!res && !PyErr_Occurred())
1983 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001984 }
1985 return (res);
1986
1987} /* validate_comp_op() */
1988
1989
Guido van Rossum47478871996-08-21 14:32:37 +00001990static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001991validate_expr(tree)
1992 node *tree;
1993{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001994 int j;
1995 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001996 int res = (validate_ntype(tree, expr)
1997 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001998 && validate_xor_expr(CHILD(tree, 0)));
1999
Guido van Rossum3d602e31996-07-21 02:33:56 +00002000 for (j = 2; res && (j < nch); j += 2)
2001 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002002 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002003
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002004 return (res);
2005
2006} /* validate_expr() */
2007
2008
Guido van Rossum47478871996-08-21 14:32:37 +00002009static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002010validate_xor_expr(tree)
2011 node *tree;
2012{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002013 int j;
2014 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002015 int res = (validate_ntype(tree, xor_expr)
2016 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002017 && validate_and_expr(CHILD(tree, 0)));
2018
Guido van Rossum3d602e31996-07-21 02:33:56 +00002019 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002020 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002021 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002022
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002023 return (res);
2024
2025} /* validate_xor_expr() */
2026
2027
Guido van Rossum47478871996-08-21 14:32:37 +00002028static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002029validate_and_expr(tree)
2030 node *tree;
2031{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002032 int pos;
2033 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002034 int res = (validate_ntype(tree, and_expr)
2035 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002036 && validate_shift_expr(CHILD(tree, 0)));
2037
Guido van Rossum3d602e31996-07-21 02:33:56 +00002038 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002039 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002040 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002041
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002042 return (res);
2043
2044} /* validate_and_expr() */
2045
2046
2047static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002048validate_chain_two_ops(tree, termvalid, op1, op2)
2049 node *tree;
2050 int (*termvalid)();
2051 int op1;
2052 int op2;
2053 {
2054 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002055 int nch = NCH(tree);
2056 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002057 && (*termvalid)(CHILD(tree, 0)));
2058
Guido van Rossum3d602e31996-07-21 02:33:56 +00002059 for ( ; res && (pos < nch); pos += 2) {
2060 if (TYPE(CHILD(tree, pos)) != op1)
2061 res = validate_ntype(CHILD(tree, pos), op2);
2062 if (res)
2063 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002064 }
2065 return (res);
2066
2067} /* validate_chain_two_ops() */
2068
2069
Guido van Rossum47478871996-08-21 14:32:37 +00002070static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002071validate_shift_expr(tree)
2072 node *tree;
2073{
2074 return (validate_ntype(tree, shift_expr)
2075 && validate_chain_two_ops(tree, validate_arith_expr,
2076 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002077
2078} /* validate_shift_expr() */
2079
2080
Guido van Rossum47478871996-08-21 14:32:37 +00002081static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002082validate_arith_expr(tree)
2083 node *tree;
2084{
2085 return (validate_ntype(tree, arith_expr)
2086 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002087
2088} /* validate_arith_expr() */
2089
2090
Guido van Rossum47478871996-08-21 14:32:37 +00002091static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002092validate_term(tree)
2093 node *tree;
2094{
2095 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002096 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002097 int res = (validate_ntype(tree, term)
2098 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002099 && validate_factor(CHILD(tree, 0)));
2100
Guido van Rossum3d602e31996-07-21 02:33:56 +00002101 for ( ; res && (pos < nch); pos += 2)
2102 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002103 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002104 || (TYPE(CHILD(tree, pos)) == PERCENT))
2105 && validate_factor(CHILD(tree, pos + 1)));
2106
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002107 return (res);
2108
2109} /* validate_term() */
2110
2111
Guido van Rossum3d602e31996-07-21 02:33:56 +00002112/* factor:
2113 *
2114 * factor: ('+'|'-'|'~') factor | power
2115 */
Guido van Rossum47478871996-08-21 14:32:37 +00002116static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002117validate_factor(tree)
2118 node *tree;
2119{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002120 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002121 int res = (validate_ntype(tree, factor)
2122 && (((nch == 2)
2123 && ((TYPE(CHILD(tree, 0)) == PLUS)
2124 || (TYPE(CHILD(tree, 0)) == MINUS)
2125 || (TYPE(CHILD(tree, 0)) == TILDE))
2126 && validate_factor(CHILD(tree, 1)))
2127 || ((nch == 1)
2128 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002129 return (res);
2130
2131} /* validate_factor() */
2132
2133
Guido van Rossum3d602e31996-07-21 02:33:56 +00002134/* power:
2135 *
2136 * power: atom trailer* ('**' factor)*
2137 */
Guido van Rossum47478871996-08-21 14:32:37 +00002138static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002139validate_power(tree)
2140 node *tree;
2141{
2142 int pos = 1;
2143 int nch = NCH(tree);
2144 int res = (validate_ntype(tree, power) && (nch >= 1)
2145 && validate_atom(CHILD(tree, 0)));
2146
2147 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2148 res = validate_trailer(CHILD(tree, pos++));
2149 if (res && (pos < nch)) {
2150 if (!is_even(nch - pos)) {
2151 err_string("Illegal number of nodes for 'power'.");
2152 return (0);
2153 }
2154 for ( ; res && (pos < (nch - 1)); pos += 2)
2155 res = (validate_doublestar(CHILD(tree, pos))
2156 && validate_factor(CHILD(tree, pos + 1)));
2157 }
2158 return (res);
2159
2160} /* validate_power() */
2161
2162
Guido van Rossum47478871996-08-21 14:32:37 +00002163static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002164validate_atom(tree)
2165 node *tree;
2166{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002167 int pos;
2168 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002169 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002170
2171 if (res) {
2172 switch (TYPE(CHILD(tree, 0))) {
2173 case LPAR:
2174 res = ((nch <= 3)
2175 && (validate_rparen(CHILD(tree, nch - 1))));
2176
Guido van Rossum3d602e31996-07-21 02:33:56 +00002177 if (res && (nch == 3))
2178 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002179 break;
2180 case LSQB:
2181 res = ((nch <= 3)
2182 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2183
Guido van Rossum3d602e31996-07-21 02:33:56 +00002184 if (res && (nch == 3))
2185 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002186 break;
2187 case LBRACE:
2188 res = ((nch <= 3)
2189 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2190
Guido van Rossum3d602e31996-07-21 02:33:56 +00002191 if (res && (nch == 3))
2192 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002193 break;
2194 case BACKQUOTE:
2195 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002196 && validate_testlist(CHILD(tree, 1))
2197 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2198 break;
2199 case NAME:
2200 case NUMBER:
2201 res = (nch == 1);
2202 break;
2203 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002204 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002205 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002206 break;
2207 default:
2208 res = 0;
2209 break;
2210 }
2211 }
2212 return (res);
2213
2214} /* validate_atom() */
2215
2216
Guido van Rossum3d602e31996-07-21 02:33:56 +00002217/* funcdef:
2218 * 'def' NAME parameters ':' suite
2219 *
2220 */
Guido van Rossum47478871996-08-21 14:32:37 +00002221static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002222validate_funcdef(tree)
2223 node *tree;
2224{
2225 return (validate_ntype(tree, funcdef)
2226 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002227 && validate_name(CHILD(tree, 0), "def")
2228 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002229 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002230 && validate_parameters(CHILD(tree, 2))
2231 && validate_suite(CHILD(tree, 4)));
2232
2233} /* validate_funcdef() */
2234
2235
Guido van Rossum47478871996-08-21 14:32:37 +00002236static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002237validate_lambdef(tree)
2238 node *tree;
2239{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002240 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002241 int res = (validate_ntype(tree, lambdef)
2242 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002243 && validate_name(CHILD(tree, 0), "lambda")
2244 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002245 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002246
Guido van Rossum3d602e31996-07-21 02:33:56 +00002247 if (res && (nch == 4))
2248 res = validate_varargslist(CHILD(tree, 1));
2249 else if (!res && !PyErr_Occurred())
Fred Drake268397f1998-04-29 14:16:32 +00002250 (void) validate_numnodes(tree, 3, "lambdef");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002251
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002252 return (res);
2253
2254} /* validate_lambdef() */
2255
2256
Guido van Rossum3d602e31996-07-21 02:33:56 +00002257/* arglist:
2258 *
2259 * argument (',' argument)* [',']
2260 */
Guido van Rossum47478871996-08-21 14:32:37 +00002261static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002262validate_arglist(tree)
2263 node *tree;
2264{
Guido van Rossum47478871996-08-21 14:32:37 +00002265 return (validate_repeating_list(tree, arglist,
2266 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002267
2268} /* validate_arglist() */
2269
2270
2271
2272/* argument:
2273 *
2274 * [test '='] test
2275 */
Guido van Rossum47478871996-08-21 14:32:37 +00002276static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002277validate_argument(tree)
2278 node *tree;
2279{
2280 int nch = NCH(tree);
2281 int res = (validate_ntype(tree, argument)
2282 && ((nch == 1) || (nch == 3))
2283 && validate_test(CHILD(tree, 0)));
2284
2285 if (res && (nch == 3))
2286 res = (validate_equal(CHILD(tree, 1))
2287 && validate_test(CHILD(tree, 2)));
2288
2289 return (res);
2290
2291} /* validate_argument() */
2292
2293
2294
2295/* trailer:
2296 *
Guido van Rossum47478871996-08-21 14:32:37 +00002297 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002298 */
Guido van Rossum47478871996-08-21 14:32:37 +00002299static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002300validate_trailer(tree)
2301 node *tree;
2302{
2303 int nch = NCH(tree);
2304 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002305
2306 if (res) {
2307 switch (TYPE(CHILD(tree, 0))) {
2308 case LPAR:
2309 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002310 if (res && (nch == 3))
2311 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002312 break;
2313 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002314 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002315 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002316 && validate_ntype(CHILD(tree, 2), RSQB));
2317 break;
2318 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002319 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002320 && validate_ntype(CHILD(tree, 1), NAME));
2321 break;
2322 default:
2323 res = 0;
2324 break;
2325 }
2326 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002327 else
Fred Drake268397f1998-04-29 14:16:32 +00002328 (void) validate_numnodes(tree, 2, "trailer");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002329
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002330 return (res);
2331
2332} /* validate_trailer() */
2333
2334
Guido van Rossum47478871996-08-21 14:32:37 +00002335/* subscriptlist:
2336 *
2337 * subscript (',' subscript)* [',']
2338 */
2339static int
2340validate_subscriptlist(tree)
2341 node *tree;
2342{
2343 return (validate_repeating_list(tree, subscriptlist,
2344 validate_subscript, "subscriptlist"));
2345
2346} /* validate_subscriptlist() */
2347
2348
Guido van Rossum3d602e31996-07-21 02:33:56 +00002349/* subscript:
2350 *
Guido van Rossum47478871996-08-21 14:32:37 +00002351 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002352 */
Guido van Rossum47478871996-08-21 14:32:37 +00002353static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002354validate_subscript(tree)
2355 node *tree;
2356{
Guido van Rossum47478871996-08-21 14:32:37 +00002357 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002358 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002359 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002360
Guido van Rossum47478871996-08-21 14:32:37 +00002361 if (!res) {
2362 if (!PyErr_Occurred())
2363 err_string("invalid number of arguments for subscript node");
2364 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002365 }
Guido van Rossum47478871996-08-21 14:32:37 +00002366 if (TYPE(CHILD(tree, 0)) == DOT)
2367 /* take care of ('.' '.' '.') possibility */
2368 return (validate_numnodes(tree, 3, "subscript")
2369 && validate_dot(CHILD(tree, 0))
2370 && validate_dot(CHILD(tree, 1))
2371 && validate_dot(CHILD(tree, 2)));
2372 if (nch == 1) {
2373 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002374 res = validate_test(CHILD(tree, 0));
2375 else
Guido van Rossum47478871996-08-21 14:32:37 +00002376 res = validate_colon(CHILD(tree, 0));
2377 return (res);
2378 }
2379 /* Must be [test] ':' [test] [sliceop],
2380 * but at least one of the optional components will
2381 * be present, but we don't know which yet.
2382 */
2383 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2384 res = validate_test(CHILD(tree, 0));
2385 offset = 1;
2386 }
2387 if (res)
2388 res = validate_colon(CHILD(tree, offset));
2389 if (res) {
2390 int rem = nch - ++offset;
2391 if (rem) {
2392 if (TYPE(CHILD(tree, offset)) == test) {
2393 res = validate_test(CHILD(tree, offset));
2394 ++offset;
2395 --rem;
2396 }
2397 if (res && rem)
2398 res = validate_sliceop(CHILD(tree, offset));
2399 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002400 }
2401 return (res);
2402
2403} /* validate_subscript() */
2404
2405
Guido van Rossum47478871996-08-21 14:32:37 +00002406static int
2407validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002408 node *tree;
2409{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002410 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002411 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2412 && validate_ntype(tree, sliceop);
2413 if (!res && !PyErr_Occurred()) {
Fred Drake268397f1998-04-29 14:16:32 +00002414 res = validate_numnodes(tree, 1, "sliceop");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002415 }
Guido van Rossum47478871996-08-21 14:32:37 +00002416 if (res)
2417 res = validate_colon(CHILD(tree, 0));
2418 if (res && (nch == 2))
2419 res = validate_test(CHILD(tree, 1));
2420
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002421 return (res);
2422
Guido van Rossum47478871996-08-21 14:32:37 +00002423} /* validate_sliceop() */
2424
2425
2426static int
2427validate_exprlist(tree)
2428 node *tree;
2429{
2430 return (validate_repeating_list(tree, exprlist,
2431 validate_expr, "exprlist"));
2432
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002433} /* validate_exprlist() */
2434
2435
Guido van Rossum47478871996-08-21 14:32:37 +00002436static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002437validate_dictmaker(tree)
2438 node *tree;
2439{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002440 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002441 int res = (validate_ntype(tree, dictmaker)
2442 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002443 && validate_test(CHILD(tree, 0))
2444 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002445 && validate_test(CHILD(tree, 2)));
2446
Guido van Rossum3d602e31996-07-21 02:33:56 +00002447 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002448 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002449 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002450 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002451
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002452 if (res && (nch > 3)) {
2453 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002454 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002455 while (res && (pos < nch)) {
2456 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002457 && validate_test(CHILD(tree, pos + 1))
2458 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002459 && validate_test(CHILD(tree, pos + 3)));
2460 pos += 4;
2461 }
2462 }
2463 return (res);
2464
2465} /* validate_dictmaker() */
2466
2467
Guido van Rossum47478871996-08-21 14:32:37 +00002468static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002469validate_eval_input(tree)
2470 node *tree;
2471{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002472 int pos;
2473 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002474 int res = (validate_ntype(tree, eval_input)
2475 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002476 && validate_testlist(CHILD(tree, 0))
2477 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2478
Guido van Rossum3d602e31996-07-21 02:33:56 +00002479 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002480 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002481
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002482 return (res);
2483
2484} /* validate_eval_input() */
2485
2486
Guido van Rossum47478871996-08-21 14:32:37 +00002487static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002488validate_node(tree)
2489 node *tree;
2490{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002491 int nch = 0; /* num. children on current node */
2492 int res = 1; /* result value */
2493 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002494
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002495 while (res & (tree != 0)) {
2496 nch = NCH(tree);
2497 next = 0;
2498 switch (TYPE(tree)) {
2499 /*
2500 * Definition nodes.
2501 */
2502 case funcdef:
2503 res = validate_funcdef(tree);
2504 break;
2505 case classdef:
2506 res = validate_class(tree);
2507 break;
2508 /*
2509 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002510 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002511 */
2512 case stmt:
2513 res = validate_stmt(tree);
2514 break;
2515 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002516 /*
2517 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum925e5471997-04-02 05:32:13 +00002518 * | import_stmt | global_stmt | exec_stmt | assert_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002519 */
2520 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002521 break;
2522 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002523 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002524 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2525 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2526 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002527 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2528 if (res)
2529 next = CHILD(tree, 0);
2530 else if (nch == 1)
2531 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002532 break;
2533 /*
2534 * Compound statements.
2535 */
2536 case simple_stmt:
2537 res = validate_simple_stmt(tree);
2538 break;
2539 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002540 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002541 break;
2542 /*
2543 * Fundemental statements.
2544 */
2545 case expr_stmt:
2546 res = validate_expr_stmt(tree);
2547 break;
2548 case print_stmt:
2549 res = validate_print_stmt(tree);
2550 break;
2551 case del_stmt:
2552 res = validate_del_stmt(tree);
2553 break;
2554 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002555 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002556 && validate_name(CHILD(tree, 0), "pass"));
2557 break;
2558 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002559 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002560 && validate_name(CHILD(tree, 0), "break"));
2561 break;
2562 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002563 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002564 && validate_name(CHILD(tree, 0), "continue"));
2565 break;
2566 case return_stmt:
2567 res = validate_return_stmt(tree);
2568 break;
2569 case raise_stmt:
2570 res = validate_raise_stmt(tree);
2571 break;
2572 case import_stmt:
2573 res = validate_import_stmt(tree);
2574 break;
2575 case global_stmt:
2576 res = validate_global_stmt(tree);
2577 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002578 case exec_stmt:
2579 res = validate_exec_stmt(tree);
2580 break;
Guido van Rossum925e5471997-04-02 05:32:13 +00002581 case assert_stmt:
2582 res = validate_assert_stmt(tree);
2583 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002584 case if_stmt:
2585 res = validate_if(tree);
2586 break;
2587 case while_stmt:
2588 res = validate_while(tree);
2589 break;
2590 case for_stmt:
2591 res = validate_for(tree);
2592 break;
2593 case try_stmt:
2594 res = validate_try(tree);
2595 break;
2596 case suite:
2597 res = validate_suite(tree);
2598 break;
2599 /*
2600 * Expression nodes.
2601 */
2602 case testlist:
2603 res = validate_testlist(tree);
2604 break;
2605 case test:
2606 res = validate_test(tree);
2607 break;
2608 case and_test:
2609 res = validate_and_test(tree);
2610 break;
2611 case not_test:
2612 res = validate_not_test(tree);
2613 break;
2614 case comparison:
2615 res = validate_comparison(tree);
2616 break;
2617 case exprlist:
2618 res = validate_exprlist(tree);
2619 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002620 case comp_op:
2621 res = validate_comp_op(tree);
2622 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002623 case expr:
2624 res = validate_expr(tree);
2625 break;
2626 case xor_expr:
2627 res = validate_xor_expr(tree);
2628 break;
2629 case and_expr:
2630 res = validate_and_expr(tree);
2631 break;
2632 case shift_expr:
2633 res = validate_shift_expr(tree);
2634 break;
2635 case arith_expr:
2636 res = validate_arith_expr(tree);
2637 break;
2638 case term:
2639 res = validate_term(tree);
2640 break;
2641 case factor:
2642 res = validate_factor(tree);
2643 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002644 case power:
2645 res = validate_power(tree);
2646 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002647 case atom:
2648 res = validate_atom(tree);
2649 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002650
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002651 default:
2652 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002653 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002654 res = 0;
2655 break;
2656 }
2657 tree = next;
2658 }
2659 return (res);
2660
2661} /* validate_node() */
2662
2663
Guido van Rossum47478871996-08-21 14:32:37 +00002664static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002665validate_expr_tree(tree)
2666 node *tree;
2667{
2668 int res = validate_eval_input(tree);
2669
2670 if (!res && !PyErr_Occurred())
2671 err_string("Could not validate expression tuple.");
2672
2673 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002674
2675} /* validate_expr_tree() */
2676
2677
Guido van Rossum3d602e31996-07-21 02:33:56 +00002678/* file_input:
2679 * (NEWLINE | stmt)* ENDMARKER
2680 */
Guido van Rossum47478871996-08-21 14:32:37 +00002681static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002682validate_file_input(tree)
2683 node *tree;
2684{
2685 int j = 0;
2686 int nch = NCH(tree) - 1;
2687 int res = ((nch >= 0)
2688 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002689
Guido van Rossum3d602e31996-07-21 02:33:56 +00002690 for ( ; res && (j < nch); ++j) {
2691 if (TYPE(CHILD(tree, j)) == stmt)
2692 res = validate_stmt(CHILD(tree, j));
2693 else
2694 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002695 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002696 /* This stays in to prevent any internal failues from getting to the
2697 * user. Hopefully, this won't be needed. If a user reports getting
2698 * this, we have some debugging to do.
2699 */
2700 if (!res && !PyErr_Occurred())
2701 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2702
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002703 return (res);
2704
Guido van Rossum2a288461996-08-21 21:55:43 +00002705} /* validate_file_input() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002706
2707
Fred Drake43f8f9b1998-04-13 16:25:46 +00002708static PyObject*
2709pickle_constructor = NULL;
2710
2711
2712static PyObject*
2713parser__pickler(self, args)
2714 PyObject *self;
2715 PyObject *args;
2716{
Fred Drake268397f1998-04-29 14:16:32 +00002717 NOTE(ARGUNUSED(self))
Fred Drake43f8f9b1998-04-13 16:25:46 +00002718 PyObject *result = NULL;
2719 PyObject *ast = NULL;
Fred Drake2a6875e1999-09-20 22:32:18 +00002720 PyObject *empty_dict = NULL;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002721
2722 if (PyArg_ParseTuple(args, "O!:_pickler", &PyAST_Type, &ast)) {
2723 PyObject *newargs;
2724 PyObject *tuple;
2725
Fred Drake2a6875e1999-09-20 22:32:18 +00002726 if ((empty_dict = PyDict_New()) == NULL)
2727 goto finally;
2728 if ((newargs = Py_BuildValue("Oi", ast, 1)) == NULL)
Fred Drake43f8f9b1998-04-13 16:25:46 +00002729 goto finally;
Fred Drake2a6875e1999-09-20 22:32:18 +00002730 tuple = parser_ast2tuple((PyAST_Object*)NULL, newargs, empty_dict);
Fred Drake43f8f9b1998-04-13 16:25:46 +00002731 if (tuple != NULL) {
2732 result = Py_BuildValue("O(O)", pickle_constructor, tuple);
2733 Py_DECREF(tuple);
2734 }
Fred Drake2a6875e1999-09-20 22:32:18 +00002735 Py_DECREF(empty_dict);
Fred Drake7f875ef1998-08-04 15:58:10 +00002736 Py_DECREF(newargs);
Fred Drake43f8f9b1998-04-13 16:25:46 +00002737 }
2738 finally:
Fred Drake2a6875e1999-09-20 22:32:18 +00002739 Py_XDECREF(empty_dict);
2740
Fred Drake43f8f9b1998-04-13 16:25:46 +00002741 return (result);
2742
2743} /* parser__pickler() */
2744
2745
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002746/* Functions exported by this module. Most of this should probably
2747 * be converted into an AST object with methods, but that is better
2748 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002749 * We'd really have to write a wrapper around it all anyway to allow
2750 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002751 */
2752static PyMethodDef parser_functions[] = {
Fred Drake7a15ba51999-09-09 14:21:52 +00002753 {"ast2tuple", (PyCFunction)parser_ast2tuple, PUBLIC_METHOD_TYPE,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002754 "Creates a tuple-tree representation of an AST."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002755 {"ast2list", (PyCFunction)parser_ast2list, PUBLIC_METHOD_TYPE,
Guido van Rossum47478871996-08-21 14:32:37 +00002756 "Creates a list-tree representation of an AST."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002757 {"compileast", (PyCFunction)parser_compileast, PUBLIC_METHOD_TYPE,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002758 "Compiles an AST object into a code object."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002759 {"expr", (PyCFunction)parser_expr, PUBLIC_METHOD_TYPE,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002760 "Creates an AST object from an expression."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002761 {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002762 "Determines if an AST object was created from an expression."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002763 {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002764 "Determines if an AST object was created from a suite."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002765 {"suite", (PyCFunction)parser_suite, PUBLIC_METHOD_TYPE,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002766 "Creates an AST object from a suite."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002767 {"sequence2ast", (PyCFunction)parser_tuple2ast, PUBLIC_METHOD_TYPE,
Guido van Rossum47478871996-08-21 14:32:37 +00002768 "Creates an AST object from a tree representation."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002769 {"tuple2ast", (PyCFunction)parser_tuple2ast, PUBLIC_METHOD_TYPE,
Guido van Rossum47478871996-08-21 14:32:37 +00002770 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002771
Fred Drake43f8f9b1998-04-13 16:25:46 +00002772 /* private stuff: support pickle module */
Fred Drake301b5be1998-04-21 22:31:45 +00002773 {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS,
Fred Drake43f8f9b1998-04-13 16:25:46 +00002774 "Returns the pickle magic to allow ast objects to be pickled."},
2775
Fred Drake268397f1998-04-29 14:16:32 +00002776 {NULL, NULL, 0, NULL}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002777 };
2778
2779
Guido van Rossum3886bb61998-12-04 18:50:17 +00002780DL_EXPORT(void)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002781initparser()
2782 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002783 PyObject* module;
2784 PyObject* dict;
2785
2786 PyAST_Type.ob_type = &PyType_Type;
2787 module = Py_InitModule("parser", parser_functions);
2788 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002789
Fred Drake7a15ba51999-09-09 14:21:52 +00002790 if (parser_error == 0)
2791 parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
2792 else
2793 puts("parser module initialized more than once!");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002794
2795 if ((parser_error == 0)
2796 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2797 /*
2798 * This is serious.
2799 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002800 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002801 }
2802 /*
2803 * Nice to have, but don't cry if we fail.
2804 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002805 Py_INCREF(&PyAST_Type);
2806 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2807
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002808 PyDict_SetItemString(dict, "__copyright__",
2809 PyString_FromString(parser_copyright_string));
2810 PyDict_SetItemString(dict, "__doc__",
2811 PyString_FromString(parser_doc_string));
2812 PyDict_SetItemString(dict, "__version__",
2813 PyString_FromString(parser_version_string));
2814
Fred Drake43f8f9b1998-04-13 16:25:46 +00002815 /* register to support pickling */
2816 module = PyImport_ImportModule("copy_reg");
2817 if (module != NULL) {
Fred Drake301b5be1998-04-21 22:31:45 +00002818 PyObject *func, *pickler;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002819
2820 func = PyObject_GetAttrString(module, "pickle");
2821 pickle_constructor = PyDict_GetItemString(dict, "sequence2ast");
2822 pickler = PyDict_GetItemString(dict, "_pickler");
2823 Py_XINCREF(pickle_constructor);
2824 if ((func != NULL) && (pickle_constructor != NULL)
2825 && (pickler != NULL)) {
2826 PyObject *res;
2827
2828 res = PyObject_CallFunction(
2829 func, "OOO", &PyAST_Type, pickler, pickle_constructor);
2830 Py_XDECREF(res);
2831 }
2832 Py_XDECREF(func);
2833 Py_DECREF(module);
2834 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002835} /* initparser() */