blob: 33767b4dbf779d8197905b029d17b39ea67bcded [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
Fred Drake0dd75072000-02-21 18:19:06 +0000235 Py_TPFLAGS_DEFAULT, /* tp_flags */
Fred Drake69b9ae41997-05-23 04:04:17 +0000236
237 /* __doc__ */
238 "Intermediate representation of a Python parse tree."
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000239
240}; /* PyAST_Type */
241
242
243static int
244parser_compare_nodes(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000245 node *left;
246 node *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000247{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000248 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000249
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000250 if (TYPE(left) < TYPE(right))
251 return (-1);
252
253 if (TYPE(right) < TYPE(left))
254 return (1);
255
256 if (ISTERMINAL(TYPE(left)))
257 return (strcmp(STR(left), STR(right)));
258
259 if (NCH(left) < NCH(right))
260 return (-1);
261
262 if (NCH(right) < NCH(left))
263 return (1);
264
265 for (j = 0; j < NCH(left); ++j) {
266 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
267
Fred Drakeed3da231998-05-11 03:31:16 +0000268 if (v != 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000269 return (v);
270 }
271 return (0);
272
273} /* parser_compare_nodes() */
274
275
276/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
277 *
278 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
279 * This really just wraps a call to parser_compare_nodes() with some easy
280 * checks and protection code.
281 *
282 */
283static int
284parser_compare(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000285 PyAST_Object *left;
286 PyAST_Object *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000287{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000288 if (left == right)
289 return (0);
290
291 if ((left == 0) || (right == 0))
292 return (-1);
293
294 return (parser_compare_nodes(left->ast_node, right->ast_node));
295
296} /* parser_compare() */
297
298
299/* parser_newastobject(node* ast)
300 *
301 * Allocates a new Python object representing an AST. This is simply the
302 * 'wrapper' object that holds a node* and allows it to be passed around in
303 * Python code.
304 *
305 */
306static PyObject*
307parser_newastobject(ast, type)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000308 node *ast;
309 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000310{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000311 PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
312
313 if (o != 0) {
314 o->ast_node = ast;
315 o->ast_type = type;
316 }
Fred Drake268397f1998-04-29 14:16:32 +0000317 else {
318 PyNode_Free(ast);
319 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000320 return ((PyObject*)o);
321
322} /* parser_newastobject() */
323
324
325/* void parser_free(PyAST_Object* ast)
326 *
327 * This is called by a del statement that reduces the reference count to 0.
328 *
329 */
330static void
331parser_free(ast)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000332 PyAST_Object *ast;
Guido van Rossum47478871996-08-21 14:32:37 +0000333{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000334 PyNode_Free(ast->ast_node);
335 PyMem_DEL(ast);
336
337} /* parser_free() */
338
339
Fred Drake2a6875e1999-09-20 22:32:18 +0000340/* parser_ast2tuple(PyObject* self, PyObject* args, PyObject* kw)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000341 *
342 * This provides conversion from a node* to a tuple object that can be
343 * returned to the Python-level caller. The AST object is not modified.
344 *
345 */
346static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000347parser_ast2tuple(self, args, kw)
Fred Drake503d8d61998-04-13 18:45:18 +0000348 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000349 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000350 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000351{
Guido van Rossum47478871996-08-21 14:32:37 +0000352 PyObject *line_option = 0;
353 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000354 int ok;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000355
Fred Drake7a15ba51999-09-09 14:21:52 +0000356 static char *keywords[] = {"ast", "line_info", NULL};
357
Fred Drake268397f1998-04-29 14:16:32 +0000358 if (self == NULL) {
Fred Drake7a15ba51999-09-09 14:21:52 +0000359 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:ast2tuple", keywords,
360 &PyAST_Type, &self, &line_option);
Fred Drake268397f1998-04-29 14:16:32 +0000361 }
Fred Drake503d8d61998-04-13 18:45:18 +0000362 else
Fred Drake7a15ba51999-09-09 14:21:52 +0000363 ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:totuple", &keywords[1],
364 &line_option);
Fred Drake268397f1998-04-29 14:16:32 +0000365 if (ok != 0) {
Guido van Rossum47478871996-08-21 14:32:37 +0000366 int lineno = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000367 if (line_option != NULL) {
Fred Drake268397f1998-04-29 14:16:32 +0000368 lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000369 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000370 /*
371 * Convert AST into a tuple representation. Use Guido's function,
372 * since it's known to work already.
373 */
Fred Drake503d8d61998-04-13 18:45:18 +0000374 res = node2tuple(((PyAST_Object*)self)->ast_node,
Guido van Rossum47478871996-08-21 14:32:37 +0000375 PyTuple_New, PyTuple_SetItem, lineno);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000376 }
377 return (res);
378
379} /* parser_ast2tuple() */
380
381
Fred Drake2a6875e1999-09-20 22:32:18 +0000382/* parser_ast2list(PyObject* self, PyObject* args, PyObject* kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000383 *
Fred Drake2a6875e1999-09-20 22:32:18 +0000384 * This provides conversion from a node* to a list object that can be
Guido van Rossum47478871996-08-21 14:32:37 +0000385 * returned to the Python-level caller. The AST object is not modified.
386 *
387 */
388static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000389parser_ast2list(self, args, kw)
Fred Drake503d8d61998-04-13 18:45:18 +0000390 PyAST_Object *self;
Guido van Rossum47478871996-08-21 14:32:37 +0000391 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000392 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000393{
Guido van Rossum47478871996-08-21 14:32:37 +0000394 PyObject *line_option = 0;
395 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000396 int ok;
Guido van Rossum47478871996-08-21 14:32:37 +0000397
Fred Drake7a15ba51999-09-09 14:21:52 +0000398 static char *keywords[] = {"ast", "line_info", NULL};
399
Fred Drake503d8d61998-04-13 18:45:18 +0000400 if (self == NULL)
Fred Drake7a15ba51999-09-09 14:21:52 +0000401 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:ast2list", keywords,
402 &PyAST_Type, &self, &line_option);
Fred Drake503d8d61998-04-13 18:45:18 +0000403 else
Fred Drake7a15ba51999-09-09 14:21:52 +0000404 ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1],
405 &line_option);
Fred Drake503d8d61998-04-13 18:45:18 +0000406 if (ok) {
Guido van Rossum47478871996-08-21 14:32:37 +0000407 int lineno = 0;
408 if (line_option != 0) {
Fred Drake503d8d61998-04-13 18:45:18 +0000409 lineno = PyObject_IsTrue(line_option) ? 1 : 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000410 }
411 /*
412 * Convert AST into a tuple representation. Use Guido's function,
413 * since it's known to work already.
414 */
Fred Drake268397f1998-04-29 14:16:32 +0000415 res = node2tuple(self->ast_node,
Guido van Rossum47478871996-08-21 14:32:37 +0000416 PyList_New, PyList_SetItem, lineno);
417 }
418 return (res);
419
420} /* parser_ast2list() */
421
422
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000423/* parser_compileast(PyObject* self, PyObject* args)
424 *
425 * This function creates code objects from the parse tree represented by
426 * the passed-in data object. An optional file name is passed in as well.
427 *
428 */
429static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000430parser_compileast(self, args, kw)
Fred Drake503d8d61998-04-13 18:45:18 +0000431 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000432 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000433 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000434{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000435 PyObject* res = 0;
436 char* str = "<ast>";
Fred Drake503d8d61998-04-13 18:45:18 +0000437 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000438
Fred Drake7a15ba51999-09-09 14:21:52 +0000439 static char *keywords[] = {"ast", "filename", NULL};
440
Fred Drake503d8d61998-04-13 18:45:18 +0000441 if (self == NULL)
Fred Drake7a15ba51999-09-09 14:21:52 +0000442 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compileast", keywords,
443 &PyAST_Type, &self, &str);
Fred Drake503d8d61998-04-13 18:45:18 +0000444 else
Fred Drake7a15ba51999-09-09 14:21:52 +0000445 ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1],
446 &str);
Fred Drake503d8d61998-04-13 18:45:18 +0000447
448 if (ok)
449 res = (PyObject *)PyNode_Compile(self->ast_node, str);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000450
451 return (res);
452
453} /* parser_compileast() */
454
455
456/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
457 * PyObject* parser_issuite(PyObject* self, PyObject* args)
458 *
459 * Checks the passed-in AST object to determine if it is an expression or
460 * a statement suite, respectively. The return is a Python truth value.
461 *
462 */
463static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000464parser_isexpr(self, args, kw)
Fred Drake503d8d61998-04-13 18:45:18 +0000465 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000466 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000467 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000468{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000469 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000470 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000471
Fred Drake7a15ba51999-09-09 14:21:52 +0000472 static char *keywords[] = {"ast", NULL};
473
Fred Drake503d8d61998-04-13 18:45:18 +0000474 if (self == NULL)
Fred Drake7a15ba51999-09-09 14:21:52 +0000475 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
476 &PyAST_Type, &self);
Fred Drake503d8d61998-04-13 18:45:18 +0000477 else
Fred Drake7a15ba51999-09-09 14:21:52 +0000478 ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]);
Fred Drake503d8d61998-04-13 18:45:18 +0000479
480 if (ok) {
481 /* Check to see if the AST represents an expression or not. */
482 res = (self->ast_type == PyAST_EXPR) ? Py_True : Py_False;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000483 Py_INCREF(res);
484 }
485 return (res);
486
487} /* parser_isexpr() */
488
489
490static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000491parser_issuite(self, args, kw)
Fred Drake503d8d61998-04-13 18:45:18 +0000492 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000493 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000494 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000495{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000496 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000497 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000498
Fred Drake7a15ba51999-09-09 14:21:52 +0000499 static char *keywords[] = {"ast", NULL};
500
Fred Drake503d8d61998-04-13 18:45:18 +0000501 if (self == NULL)
Fred Drake7a15ba51999-09-09 14:21:52 +0000502 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
503 &PyAST_Type, &self);
Fred Drake503d8d61998-04-13 18:45:18 +0000504 else
Fred Drake7a15ba51999-09-09 14:21:52 +0000505 ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]);
Fred Drake503d8d61998-04-13 18:45:18 +0000506
507 if (ok) {
508 /* Check to see if the AST represents an expression or not. */
509 res = (self->ast_type == PyAST_EXPR) ? Py_False : Py_True;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000510 Py_INCREF(res);
511 }
512 return (res);
513
514} /* parser_issuite() */
515
516
Fred Drake7a15ba51999-09-09 14:21:52 +0000517#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS)
518
Fred Drake503d8d61998-04-13 18:45:18 +0000519static PyMethodDef
520parser_methods[] = {
Fred Drake7a15ba51999-09-09 14:21:52 +0000521 {"compile", (PyCFunction)parser_compileast, PUBLIC_METHOD_TYPE,
Fred Drake301b5be1998-04-21 22:31:45 +0000522 "Compile this AST object into a code object."},
Fred Drake7a15ba51999-09-09 14:21:52 +0000523 {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
Fred Drake301b5be1998-04-21 22:31:45 +0000524 "Determines if this AST object was created from an expression."},
Fred Drake7a15ba51999-09-09 14:21:52 +0000525 {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
Fred Drake301b5be1998-04-21 22:31:45 +0000526 "Determines if this AST object was created from a suite."},
Fred Drake7a15ba51999-09-09 14:21:52 +0000527 {"tolist", (PyCFunction)parser_ast2list, PUBLIC_METHOD_TYPE,
Fred Drake301b5be1998-04-21 22:31:45 +0000528 "Creates a list-tree representation of this AST."},
Fred Drake7a15ba51999-09-09 14:21:52 +0000529 {"totuple", (PyCFunction)parser_ast2tuple, PUBLIC_METHOD_TYPE,
Fred Drake301b5be1998-04-21 22:31:45 +0000530 "Creates a tuple-tree representation of this AST."},
Fred Drake503d8d61998-04-13 18:45:18 +0000531
Fred Drake268397f1998-04-29 14:16:32 +0000532 {NULL, NULL, 0, NULL}
Fred Drake503d8d61998-04-13 18:45:18 +0000533};
534
Fred Drake503d8d61998-04-13 18:45:18 +0000535
536static PyObject*
537parser_getattr(self, name)
538 PyObject *self;
539 char *name;
540{
Fred Drake503d8d61998-04-13 18:45:18 +0000541 return (Py_FindMethod(parser_methods, self, name));
542
543} /* parser_getattr() */
544
545
Guido van Rossum3d602e31996-07-21 02:33:56 +0000546/* err_string(char* message)
547 *
548 * Sets the error string for an exception of type ParserError.
549 *
550 */
551static void
552err_string(message)
553 char *message;
Guido van Rossum47478871996-08-21 14:32:37 +0000554{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000555 PyErr_SetString(parser_error, message);
556
557} /* err_string() */
558
559
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000560/* PyObject* parser_do_parse(PyObject* args, int type)
561 *
562 * Internal function to actually execute the parse and return the result if
563 * successful, or set an exception if not.
564 *
565 */
566static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000567parser_do_parse(args, kw, argspec, type)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000568 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000569 PyObject *kw;
570 char *argspec;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000571 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000572{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000573 char* string = 0;
574 PyObject* res = 0;
575
Fred Drake7a15ba51999-09-09 14:21:52 +0000576 static char *keywords[] = {"source", NULL};
577
578 if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000579 node* n = PyParser_SimpleParseString(string,
580 (type == PyAST_EXPR)
581 ? eval_input : file_input);
582
583 if (n != 0)
584 res = parser_newastobject(n, type);
585 else
Guido van Rossum3d602e31996-07-21 02:33:56 +0000586 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000587 }
588 return (res);
589
590} /* parser_do_parse() */
591
592
593/* PyObject* parser_expr(PyObject* self, PyObject* args)
594 * PyObject* parser_suite(PyObject* self, PyObject* args)
595 *
596 * External interfaces to the parser itself. Which is called determines if
597 * the parser attempts to recognize an expression ('eval' form) or statement
598 * suite ('exec' form). The real work is done by parser_do_parse() above.
599 *
600 */
601static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000602parser_expr(self, args, kw)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000603 PyObject *self;
604 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000605 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000606{
Fred Drake268397f1998-04-29 14:16:32 +0000607 NOTE(ARGUNUSED(self))
Fred Drake7a15ba51999-09-09 14:21:52 +0000608 return (parser_do_parse(args, kw, "s:expr", PyAST_EXPR));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000609
610} /* parser_expr() */
611
612
613static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000614parser_suite(self, args, kw)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000615 PyObject *self;
616 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000617 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000618{
Fred Drake268397f1998-04-29 14:16:32 +0000619 NOTE(ARGUNUSED(self))
Fred Drake7a15ba51999-09-09 14:21:52 +0000620 return (parser_do_parse(args, kw, "s:suite", PyAST_SUITE));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000621
622} /* parser_suite() */
623
624
625
626/* This is the messy part of the code. Conversion from a tuple to an AST
627 * object requires that the input tuple be valid without having to rely on
628 * catching an exception from the compiler. This is done to allow the
629 * compiler itself to remain fast, since most of its input will come from
630 * the parser directly, and therefore be known to be syntactically correct.
631 * This validation is done to ensure that we don't core dump the compile
632 * phase, returning an exception instead.
633 *
634 * Two aspects can be broken out in this code: creating a node tree from
635 * the tuple passed in, and verifying that it is indeed valid. It may be
636 * advantageous to expand the number of AST types to include funcdefs and
637 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
638 * here. They are not necessary, and not quite as useful in a raw form.
639 * For now, let's get expressions and suites working reliably.
640 */
641
642
Guido van Rossum2a288461996-08-21 21:55:43 +0000643staticforward node* build_node_tree Py_PROTO((PyObject *tuple));
644staticforward int validate_expr_tree Py_PROTO((node *tree));
645staticforward int validate_file_input Py_PROTO((node *tree));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000646
647
648/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
649 *
650 * This is the public function, called from the Python code. It receives a
651 * single tuple object from the caller, and creates an AST object if the
652 * tuple can be validated. It does this by checking the first code of the
653 * tuple, and, if acceptable, builds the internal representation. If this
654 * step succeeds, the internal representation is validated as fully as
655 * possible with the various validate_*() routines defined below.
656 *
657 * This function must be changed if support is to be added for PyAST_FRAGMENT
658 * AST objects.
659 *
660 */
661static PyObject*
Fred Drake7a15ba51999-09-09 14:21:52 +0000662parser_tuple2ast(self, args, kw)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000663 PyObject *self;
664 PyObject *args;
Fred Drake7a15ba51999-09-09 14:21:52 +0000665 PyObject *kw;
Guido van Rossum47478871996-08-21 14:32:37 +0000666{
Fred Drake268397f1998-04-29 14:16:32 +0000667 NOTE(ARGUNUSED(self))
Guido van Rossum47478871996-08-21 14:32:37 +0000668 PyObject *ast = 0;
669 PyObject *tuple = 0;
670 PyObject *temp = 0;
671 int ok;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000672 int start_sym = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000673
Fred Drake7a15ba51999-09-09 14:21:52 +0000674 static char *keywords[] = {"sequence", NULL};
675
676 if (!PyArg_ParseTupleAndKeywords(args, kw, "O:tuple2ast", keywords,
677 &tuple))
Guido van Rossum47478871996-08-21 14:32:37 +0000678 return (0);
679 if (!PySequence_Check(tuple)) {
680 PyErr_SetString(PyExc_ValueError,
681 "tuple2ast() requires a single sequence argument");
682 return (0);
683 }
684 /*
685 * This mess of tests is written this way so we can use the abstract
686 * object interface (AOI). Unfortunately, the AOI increments reference
687 * counts, which requires that we store a pointer to retrieved object
688 * so we can DECREF it after the check. But we really should accept
689 * lists as well as tuples at the very least.
690 */
691 ok = PyObject_Length(tuple) >= 2;
692 if (ok) {
693 temp = PySequence_GetItem(tuple, 0);
694 ok = (temp != NULL) && PyInt_Check(temp);
695 if (ok)
696 /* this is used after the initial checks: */
Fred Drake1a566ff1999-02-17 17:35:53 +0000697 start_sym = PyInt_AS_LONG(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000698 Py_XDECREF(temp);
699 }
700 if (ok) {
701 temp = PySequence_GetItem(tuple, 1);
702 ok = (temp != NULL) && PySequence_Check(temp);
703 Py_XDECREF(temp);
704 }
705 if (ok) {
706 temp = PySequence_GetItem(tuple, 1);
707 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
708 if (ok) {
709 PyObject *temp2 = PySequence_GetItem(temp, 0);
710 if (temp2 != NULL) {
711 ok = PyInt_Check(temp2);
712 Py_DECREF(temp2);
713 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000714 }
Guido van Rossum47478871996-08-21 14:32:37 +0000715 Py_XDECREF(temp);
716 }
717 /* If we've failed at some point, get out of here. */
718 if (!ok) {
719 err_string("malformed sequence for tuple2ast()");
720 return (0);
721 }
722 /*
723 * This might be a valid parse tree, but let's do a quick check
724 * before we jump the gun.
725 */
726 if (start_sym == eval_input) {
727 /* Might be an eval form. */
728 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000729
Guido van Rossum47478871996-08-21 14:32:37 +0000730 if ((expression != 0) && validate_expr_tree(expression))
731 ast = parser_newastobject(expression, PyAST_EXPR);
732 }
733 else if (start_sym == file_input) {
734 /* This looks like an exec form so far. */
735 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000736
Guido van Rossum47478871996-08-21 14:32:37 +0000737 if ((suite_tree != 0) && validate_file_input(suite_tree))
738 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000739 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000740 else
Guido van Rossum47478871996-08-21 14:32:37 +0000741 /* This is a fragment, and is not yet supported. Maybe they
742 * will be if I find a use for them.
743 */
744 err_string("Fragmentary parse trees not supported.");
745
746 /* Make sure we throw an exception on all errors. We should never
747 * get this, but we'd do well to be sure something is done.
748 */
749 if ((ast == 0) && !PyErr_Occurred())
750 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000751
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000752 return (ast);
753
754} /* parser_tuple2ast() */
755
756
757/* int check_terminal_tuple()
758 *
Guido van Rossum47478871996-08-21 14:32:37 +0000759 * Check a tuple to determine that it is indeed a valid terminal
760 * node. The node is known to be required as a terminal, so we throw
761 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000762 *
Guido van Rossum47478871996-08-21 14:32:37 +0000763 * The format of an acceptable terminal tuple is "(is[i])": the fact
764 * that elem is a tuple and the integer is a valid terminal symbol
765 * has been established before this function is called. We must
766 * check the length of the tuple and the type of the second element
767 * and optional third element. We do *NOT* check the actual text of
768 * the string element, which we could do in many cases. This is done
769 * by the validate_*() functions which operate on the internal
770 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000771 */
772static int
Guido van Rossum47478871996-08-21 14:32:37 +0000773check_terminal_tuple(elem)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000774 PyObject *elem;
Guido van Rossum47478871996-08-21 14:32:37 +0000775{
776 int len = PyObject_Length(elem);
777 int res = 1;
778 char* str = "Illegal terminal symbol; bad node length.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000779
Guido van Rossum47478871996-08-21 14:32:37 +0000780 if ((len == 2) || (len == 3)) {
781 PyObject *temp = PySequence_GetItem(elem, 1);
782 res = PyString_Check(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000783 str = "Illegal terminal symbol; expected a string.";
Guido van Rossum47478871996-08-21 14:32:37 +0000784 if (res && (len == 3)) {
785 PyObject* third = PySequence_GetItem(elem, 2);
786 res = PyInt_Check(third);
787 str = "Invalid third element of terminal node.";
788 Py_XDECREF(third);
789 }
790 Py_XDECREF(temp);
791 }
792 else {
793 res = 0;
794 }
795 if (!res) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000796 elem = Py_BuildValue("(os)", elem, str);
797 PyErr_SetObject(parser_error, elem);
798 }
799 return (res);
800
801} /* check_terminal_tuple() */
802
803
804/* node* build_node_children()
805 *
806 * Iterate across the children of the current non-terminal node and build
807 * their structures. If successful, return the root of this portion of
808 * the tree, otherwise, 0. Any required exception will be specified already,
809 * and no memory will have been deallocated.
810 *
811 */
812static node*
813build_node_children(tuple, root, line_num)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000814 PyObject *tuple;
815 node *root;
816 int *line_num;
Guido van Rossum47478871996-08-21 14:32:37 +0000817{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000818 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000819 int i;
820
821 for (i = 1; i < len; ++i) {
822 /* elem must always be a tuple, however simple */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000823 PyObject* elem = PySequence_GetItem(tuple, i);
Guido van Rossum47478871996-08-21 14:32:37 +0000824 int ok = elem != NULL;
825 long type = 0;
826 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000827
Guido van Rossum47478871996-08-21 14:32:37 +0000828 if (ok)
829 ok = PySequence_Check(elem);
830 if (ok) {
831 PyObject *temp = PySequence_GetItem(elem, 0);
832 if (temp == NULL)
833 ok = 0;
834 else {
835 ok = PyInt_Check(temp);
836 if (ok)
Fred Drake1a566ff1999-02-17 17:35:53 +0000837 type = PyInt_AS_LONG(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000838 Py_DECREF(temp);
839 }
840 }
841 if (!ok) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000842 PyErr_SetObject(parser_error,
843 Py_BuildValue("(os)", elem,
844 "Illegal node construct."));
Guido van Rossum47478871996-08-21 14:32:37 +0000845 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000846 return (0);
847 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000848 if (ISTERMINAL(type)) {
Guido van Rossum47478871996-08-21 14:32:37 +0000849 if (check_terminal_tuple(elem)) {
850 PyObject *temp = PySequence_GetItem(elem, 1);
851
Fred Draked49266e1997-10-09 16:29:31 +0000852 /* check_terminal_tuple() already verified it's a string */
853 strn = (char *)malloc(PyString_GET_SIZE(temp) + 1);
854 if (strn != NULL)
Fred Drake268397f1998-04-29 14:16:32 +0000855 (void) strcpy(strn, PyString_AS_STRING(temp));
Guido van Rossum47478871996-08-21 14:32:37 +0000856 Py_XDECREF(temp);
857
858 if (PyObject_Length(elem) == 3) {
859 PyObject* temp = PySequence_GetItem(elem, 2);
860 *line_num = PyInt_AsLong(temp);
861 Py_DECREF(temp);
862 }
863 }
864 else {
865 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000866 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000867 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000868 }
869 else if (!ISNONTERMINAL(type)) {
870 /*
871 * It has to be one or the other; this is an error.
872 * Throw an exception.
873 */
874 PyErr_SetObject(parser_error,
875 Py_BuildValue("(os)", elem,
876 "Unknown node type."));
Guido van Rossum47478871996-08-21 14:32:37 +0000877 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000878 return (0);
879 }
880 PyNode_AddChild(root, type, strn, *line_num);
881
882 if (ISNONTERMINAL(type)) {
883 node* new_child = CHILD(root, i - 1);
884
Guido van Rossum47478871996-08-21 14:32:37 +0000885 if (new_child != build_node_children(elem, new_child, line_num)) {
886 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000887 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000888 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000889 }
Guido van Rossum47478871996-08-21 14:32:37 +0000890 else if (type == NEWLINE) { /* It's true: we increment the */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000891 ++(*line_num); /* line number *after* the newline! */
Guido van Rossum47478871996-08-21 14:32:37 +0000892 }
893 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000894 }
895 return (root);
896
897} /* build_node_children() */
898
899
900static node*
901build_node_tree(tuple)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000902 PyObject *tuple;
Guido van Rossum47478871996-08-21 14:32:37 +0000903{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000904 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000905 PyObject *temp = PySequence_GetItem(tuple, 0);
906 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000907
Guido van Rossum47478871996-08-21 14:32:37 +0000908 if (temp != NULL)
909 num = PyInt_AsLong(temp);
910 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000911 if (ISTERMINAL(num)) {
912 /*
913 * The tuple is simple, but it doesn't start with a start symbol.
914 * Throw an exception now and be done with it.
915 */
916 tuple = Py_BuildValue("(os)", tuple,
Guido van Rossum3d602e31996-07-21 02:33:56 +0000917 "Illegal ast tuple; cannot start with terminal symbol.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000918 PyErr_SetObject(parser_error, tuple);
919 }
920 else if (ISNONTERMINAL(num)) {
921 /*
922 * Not efficient, but that can be handled later.
923 */
924 int line_num = 0;
925
926 res = PyNode_New(num);
927 if (res != build_node_children(tuple, res, &line_num)) {
928 PyNode_Free(res);
929 res = 0;
930 }
931 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000932 else
933 /* The tuple is illegal -- if the number is neither TERMINAL nor
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000934 * NONTERMINAL, we can't use it.
935 */
936 PyErr_SetObject(parser_error,
937 Py_BuildValue("(os)", tuple,
938 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000939
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000940 return (res);
941
942} /* build_node_tree() */
943
944
Guido van Rossum360a9341996-08-21 19:04:10 +0000945#ifdef HAVE_OLD_CPP
Guido van Rossum2a288461996-08-21 21:55:43 +0000946#define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000947#else
Guido van Rossum2a288461996-08-21 21:55:43 +0000948#define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000949#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000950
951
952/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000953 * Validation routines used within the validation section:
954 */
Guido van Rossum2a288461996-08-21 21:55:43 +0000955staticforward int validate_terminal Py_PROTO((node *terminal,
956 int type, char *string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000957
958#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
959#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
960#define validate_colon(ch) validate_terminal(ch, COLON, ":")
961#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
962#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
963#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Fred Drake268397f1998-04-29 14:16:32 +0000964#define validate_indent(ch) validate_terminal(ch, INDENT, (char*)NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000965#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Fred Drake268397f1998-04-29 14:16:32 +0000966#define validate_newline(ch) validate_terminal(ch, NEWLINE, (char*)NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000967#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
968#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
969#define validate_star(ch) validate_terminal(ch, STAR, "*")
970#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000971#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
Guido van Rossum47478871996-08-21 14:32:37 +0000972#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000973#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000974
Guido van Rossum3d602e31996-07-21 02:33:56 +0000975VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000976VALIDATER(class); VALIDATER(node);
977VALIDATER(parameters); VALIDATER(suite);
978VALIDATER(testlist); VALIDATER(varargslist);
979VALIDATER(fpdef); VALIDATER(fplist);
980VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000981VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000982VALIDATER(print_stmt); VALIDATER(del_stmt);
983VALIDATER(return_stmt);
984VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000985VALIDATER(global_stmt);
Guido van Rossum925e5471997-04-02 05:32:13 +0000986VALIDATER(assert_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000987VALIDATER(exec_stmt); VALIDATER(compound_stmt);
988VALIDATER(while); VALIDATER(for);
989VALIDATER(try); VALIDATER(except_clause);
990VALIDATER(test); VALIDATER(and_test);
991VALIDATER(not_test); VALIDATER(comparison);
992VALIDATER(comp_op); VALIDATER(expr);
993VALIDATER(xor_expr); VALIDATER(and_expr);
994VALIDATER(shift_expr); VALIDATER(arith_expr);
995VALIDATER(term); VALIDATER(factor);
996VALIDATER(atom); VALIDATER(lambdef);
997VALIDATER(trailer); VALIDATER(subscript);
Guido van Rossum47478871996-08-21 14:32:37 +0000998VALIDATER(subscriptlist); VALIDATER(sliceop);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000999VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001000VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001001
1002
1003#define is_even(n) (((n) & 1) == 0)
1004#define is_odd(n) (((n) & 1) == 1)
1005
1006
1007static int
1008validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001009 node *n;
1010 int t;
Guido van Rossum47478871996-08-21 14:32:37 +00001011{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001012 int res = (TYPE(n) == t);
1013
1014 if (!res) {
1015 char buffer[128];
Fred Drake268397f1998-04-29 14:16:32 +00001016 (void) sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001017 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001018 }
1019 return (res);
1020
1021} /* validate_ntype() */
1022
1023
1024static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001025validate_numnodes(n, num, name)
1026 node *n;
1027 int num;
1028 const char *const name;
Guido van Rossum47478871996-08-21 14:32:37 +00001029{
Guido van Rossum3d602e31996-07-21 02:33:56 +00001030 if (NCH(n) != num) {
1031 char buff[60];
Fred Drake268397f1998-04-29 14:16:32 +00001032 (void) sprintf(buff, "Illegal number of children for %s node.", name);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001033 err_string(buff);
1034 }
1035 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001036
Guido van Rossum3d602e31996-07-21 02:33:56 +00001037} /* validate_numnodes() */
1038
1039
1040static int
1041validate_terminal(terminal, type, string)
1042 node *terminal;
1043 int type;
1044 char *string;
Guido van Rossum47478871996-08-21 14:32:37 +00001045{
Guido van Rossum3d602e31996-07-21 02:33:56 +00001046 int res = (validate_ntype(terminal, type)
1047 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
1048
1049 if (!res && !PyErr_Occurred()) {
1050 char buffer[60];
Fred Drake268397f1998-04-29 14:16:32 +00001051 (void) sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001052 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001053 }
1054 return (res);
1055
1056} /* validate_terminal() */
1057
1058
Guido van Rossum47478871996-08-21 14:32:37 +00001059/* X (',' X) [',']
1060 */
1061static int
1062validate_repeating_list(tree, ntype, vfunc, name)
1063 node *tree;
1064 int ntype;
1065 int (*vfunc)();
1066 const char *const name;
1067{
1068 int nch = NCH(tree);
1069 int res = (nch && validate_ntype(tree, ntype)
1070 && vfunc(CHILD(tree, 0)));
1071
1072 if (!res && !PyErr_Occurred())
Fred Drake268397f1998-04-29 14:16:32 +00001073 (void) validate_numnodes(tree, 1, name);
Guido van Rossum47478871996-08-21 14:32:37 +00001074 else {
1075 if (is_even(nch))
1076 res = validate_comma(CHILD(tree, --nch));
1077 if (res && nch > 1) {
1078 int pos = 1;
1079 for ( ; res && pos < nch; pos += 2)
1080 res = (validate_comma(CHILD(tree, pos))
1081 && vfunc(CHILD(tree, pos + 1)));
1082 }
1083 }
1084 return (res);
1085
1086} /* validate_repeating_list() */
1087
1088
Guido van Rossum3d602e31996-07-21 02:33:56 +00001089/* VALIDATE(class)
1090 *
1091 * classdef:
1092 * 'class' NAME ['(' testlist ')'] ':' suite
1093 */
Guido van Rossum47478871996-08-21 14:32:37 +00001094static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001095validate_class(tree)
1096 node *tree;
1097{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001098 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001099 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001100
Guido van Rossum3d602e31996-07-21 02:33:56 +00001101 if (res) {
1102 res = (validate_name(CHILD(tree, 0), "class")
1103 && validate_ntype(CHILD(tree, 1), NAME)
1104 && validate_colon(CHILD(tree, nch - 2))
1105 && validate_suite(CHILD(tree, nch - 1)));
1106 }
1107 else
Fred Drake268397f1998-04-29 14:16:32 +00001108 (void) validate_numnodes(tree, 4, "class");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001109 if (res && (nch == 7)) {
1110 res = (validate_lparen(CHILD(tree, 2))
1111 && validate_testlist(CHILD(tree, 3))
1112 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001113 }
1114 return (res);
1115
1116} /* validate_class() */
1117
1118
Guido van Rossum3d602e31996-07-21 02:33:56 +00001119/* if_stmt:
1120 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1121 */
Guido van Rossum47478871996-08-21 14:32:37 +00001122static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001123validate_if(tree)
1124 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001125{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001126 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001127 int res = (validate_ntype(tree, if_stmt)
1128 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001129 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +00001130 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001131 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001132 && validate_suite(CHILD(tree, 3)));
1133
1134 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001135 /* ... 'else' ':' suite */
1136 res = (validate_name(CHILD(tree, nch - 3), "else")
1137 && validate_colon(CHILD(tree, nch - 2))
1138 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001139 nch -= 3;
1140 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001141 else if (!res && !PyErr_Occurred())
Fred Drake268397f1998-04-29 14:16:32 +00001142 (void) validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001143 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001144 /* Will catch the case for nch < 4 */
1145 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001146 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001147 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001148 int j = 4;
1149 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001150 res = (validate_name(CHILD(tree, j), "elif")
1151 && validate_colon(CHILD(tree, j + 2))
1152 && validate_test(CHILD(tree, j + 1))
1153 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001154 j += 4;
1155 }
1156 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001157 return (res);
1158
1159} /* validate_if() */
1160
1161
Guido van Rossum3d602e31996-07-21 02:33:56 +00001162/* parameters:
1163 * '(' [varargslist] ')'
1164 *
1165 */
Guido van Rossum47478871996-08-21 14:32:37 +00001166static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001167validate_parameters(tree)
1168 node *tree;
1169{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001170 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001171 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001172
Guido van Rossum3d602e31996-07-21 02:33:56 +00001173 if (res) {
1174 res = (validate_lparen(CHILD(tree, 0))
1175 && validate_rparen(CHILD(tree, nch - 1)));
1176 if (res && (nch == 3))
1177 res = validate_varargslist(CHILD(tree, 1));
1178 }
1179 else
Fred Drake268397f1998-04-29 14:16:32 +00001180 (void) validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001181
1182 return (res);
1183
1184} /* validate_parameters() */
1185
1186
Guido van Rossum3d602e31996-07-21 02:33:56 +00001187/* VALIDATE(suite)
1188 *
1189 * suite:
1190 * simple_stmt
1191 * | NEWLINE INDENT stmt+ DEDENT
1192 */
Guido van Rossum47478871996-08-21 14:32:37 +00001193static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001194validate_suite(tree)
1195 node *tree;
1196{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001197 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001198 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001199
Guido van Rossum3d602e31996-07-21 02:33:56 +00001200 if (res && (nch == 1))
1201 res = validate_simple_stmt(CHILD(tree, 0));
1202 else if (res) {
1203 /* NEWLINE INDENT stmt+ DEDENT */
1204 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001205 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001206 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001207 && validate_dedent(CHILD(tree, nch - 1)));
1208
Guido van Rossum3d602e31996-07-21 02:33:56 +00001209 if (res && (nch > 4)) {
1210 int i = 3;
1211 --nch; /* forget the DEDENT */
1212 for ( ; res && (i < nch); ++i)
1213 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001214 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001215 else if (nch < 4)
Fred Drake268397f1998-04-29 14:16:32 +00001216 res = validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001217 }
1218 return (res);
1219
1220} /* validate_suite() */
1221
1222
Guido van Rossum47478871996-08-21 14:32:37 +00001223static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001224validate_testlist(tree)
1225 node *tree;
1226{
Guido van Rossum47478871996-08-21 14:32:37 +00001227 return (validate_repeating_list(tree, testlist,
1228 validate_test, "testlist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001229
1230} /* validate_testlist() */
1231
1232
Guido van Rossum3d602e31996-07-21 02:33:56 +00001233/* VALIDATE(varargslist)
1234 *
1235 * varargslist:
1236 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1237 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1238 *
1239 * (fpdef ['=' test] ',')*
1240 * ('*' NAME [',' ('**'|'*' '*') NAME]
1241 * | ('**'|'*' '*') NAME)
1242 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1243 *
1244 */
Guido van Rossum47478871996-08-21 14:32:37 +00001245static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001246validate_varargslist(tree)
1247 node *tree;
1248{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001249 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001250 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001251
Guido van Rossum3d602e31996-07-21 02:33:56 +00001252 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1253 /* (fpdef ['=' test] ',')*
1254 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1255 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001256 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001257 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001258
Guido van Rossum3d602e31996-07-21 02:33:56 +00001259 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1260 res = validate_fpdef(CHILD(tree, pos));
1261 if (res) {
1262 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1263 res = validate_test(CHILD(tree, pos + 2));
1264 pos += 2;
1265 }
1266 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001267 pos += 2;
1268 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001269 }
1270 if (res) {
1271 remaining = nch - pos;
1272 res = ((remaining == 2) || (remaining == 3)
1273 || (remaining == 5) || (remaining == 6));
1274 if (!res)
Fred Drake268397f1998-04-29 14:16:32 +00001275 (void) validate_numnodes(tree, 2, "varargslist");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001276 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1277 return ((remaining == 2)
1278 && validate_ntype(CHILD(tree, pos+1), NAME));
1279 else {
1280 res = validate_star(CHILD(tree, pos++));
1281 --remaining;
1282 }
1283 }
1284 if (res) {
1285 if (remaining == 2) {
1286 res = (validate_star(CHILD(tree, pos))
1287 && validate_ntype(CHILD(tree, pos + 1), NAME));
1288 }
1289 else {
1290 res = validate_ntype(CHILD(tree, pos++), NAME);
1291 if (res && (remaining >= 4)) {
1292 res = validate_comma(CHILD(tree, pos));
1293 if (--remaining == 3)
Fred Drakee1607a81996-09-11 21:58:26 +00001294 res = (validate_star(CHILD(tree, pos + 1))
1295 && validate_star(CHILD(tree, pos + 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001296 else
Fred Drake268397f1998-04-29 14:16:32 +00001297 res = validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001298 }
1299 }
1300 }
1301 if (!res && !PyErr_Occurred())
1302 err_string("Incorrect validation of variable arguments list.");
1303 }
1304 else if (res) {
1305 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1306 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1307 --nch;
1308
1309 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1310 res = (is_odd(nch)
1311 && validate_fpdef(CHILD(tree, 0)));
1312
1313 if (res && (nch > 1)) {
1314 int pos = 1;
1315 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1316 res = validate_test(CHILD(tree, 2));
1317 pos += 2;
1318 }
1319 /* ... (',' fpdef ['=' test])* */
1320 for ( ; res && (pos < nch); pos += 2) {
1321 /* ',' fpdef */
1322 res = (validate_comma(CHILD(tree, pos))
1323 && validate_fpdef(CHILD(tree, pos + 1)));
1324 if (res
1325 && ((nch - pos) > 2)
1326 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1327 /* ['=' test] */
1328 res = validate_test(CHILD(tree, pos + 3));
1329 pos += 2;
1330 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001331 }
1332 }
1333 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001334 else
1335 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001336
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001337 return (res);
1338
1339} /* validate_varargslist() */
1340
1341
Guido van Rossum3d602e31996-07-21 02:33:56 +00001342/* VALIDATE(fpdef)
1343 *
1344 * fpdef:
1345 * NAME
1346 * | '(' fplist ')'
1347 */
Guido van Rossum47478871996-08-21 14:32:37 +00001348static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001349validate_fpdef(tree)
1350 node *tree;
1351{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001352 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001353 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001354
Guido van Rossum3d602e31996-07-21 02:33:56 +00001355 if (res) {
1356 if (nch == 1)
1357 res = validate_ntype(CHILD(tree, 0), NAME);
1358 else if (nch == 3)
1359 res = (validate_lparen(CHILD(tree, 0))
1360 && validate_fplist(CHILD(tree, 1))
1361 && validate_rparen(CHILD(tree, 2)));
1362 else
Fred Drake268397f1998-04-29 14:16:32 +00001363 res = validate_numnodes(tree, 1, "fpdef");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001364 }
1365 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001366
1367} /* validate_fpdef() */
1368
1369
Guido van Rossum47478871996-08-21 14:32:37 +00001370static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001371validate_fplist(tree)
1372 node *tree;
1373{
Guido van Rossum47478871996-08-21 14:32:37 +00001374 return (validate_repeating_list(tree, fplist,
1375 validate_fpdef, "fplist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001376
1377} /* validate_fplist() */
1378
1379
Guido van Rossum3d602e31996-07-21 02:33:56 +00001380/* simple_stmt | compound_stmt
1381 *
1382 */
Guido van Rossum47478871996-08-21 14:32:37 +00001383static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001384validate_stmt(tree)
1385 node *tree;
1386{
1387 int res = (validate_ntype(tree, stmt)
1388 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001389
Guido van Rossum3d602e31996-07-21 02:33:56 +00001390 if (res) {
1391 tree = CHILD(tree, 0);
1392
1393 if (TYPE(tree) == simple_stmt)
1394 res = validate_simple_stmt(tree);
1395 else
1396 res = validate_compound_stmt(tree);
1397 }
1398 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001399
1400} /* validate_stmt() */
1401
1402
Guido van Rossum3d602e31996-07-21 02:33:56 +00001403/* small_stmt (';' small_stmt)* [';'] NEWLINE
1404 *
1405 */
Guido van Rossum47478871996-08-21 14:32:37 +00001406static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001407validate_simple_stmt(tree)
1408 node *tree;
1409{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001410 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001411 int res = (validate_ntype(tree, simple_stmt)
1412 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001413 && validate_small_stmt(CHILD(tree, 0))
1414 && validate_newline(CHILD(tree, nch - 1)));
1415
Guido van Rossum3d602e31996-07-21 02:33:56 +00001416 if (nch < 2)
1417 res = validate_numnodes(tree, 2, "simple_stmt");
1418 --nch; /* forget the NEWLINE */
1419 if (res && is_even(nch))
1420 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001421 if (res && (nch > 2)) {
1422 int i;
1423
Guido van Rossum3d602e31996-07-21 02:33:56 +00001424 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001425 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001426 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001427 }
1428 return (res);
1429
1430} /* validate_simple_stmt() */
1431
1432
Guido van Rossum47478871996-08-21 14:32:37 +00001433static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001434validate_small_stmt(tree)
1435 node *tree;
1436{
1437 int nch = NCH(tree);
1438 int res = (validate_numnodes(tree, 1, "small_stmt")
1439 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1440 || (TYPE(CHILD(tree, 0)) == print_stmt)
1441 || (TYPE(CHILD(tree, 0)) == del_stmt)
1442 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1443 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1444 || (TYPE(CHILD(tree, 0)) == import_stmt)
1445 || (TYPE(CHILD(tree, 0)) == global_stmt)
Guido van Rossum925e5471997-04-02 05:32:13 +00001446 || (TYPE(CHILD(tree, 0)) == assert_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001447 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1448
1449 if (res)
1450 res = validate_node(CHILD(tree, 0));
1451 else if (nch == 1) {
1452 char buffer[60];
Fred Drake268397f1998-04-29 14:16:32 +00001453 (void) sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1454 TYPE(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001455 err_string(buffer);
1456 }
1457 return (res);
1458
1459} /* validate_small_stmt */
1460
1461
1462/* compound_stmt:
1463 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1464 */
Guido van Rossum47478871996-08-21 14:32:37 +00001465static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001466validate_compound_stmt(tree)
1467 node *tree;
1468{
1469 int res = (validate_ntype(tree, compound_stmt)
1470 && validate_numnodes(tree, 1, "compound_stmt"));
1471
1472 if (!res)
1473 return (0);
1474
1475 tree = CHILD(tree, 0);
1476 res = ((TYPE(tree) == if_stmt)
1477 || (TYPE(tree) == while_stmt)
1478 || (TYPE(tree) == for_stmt)
1479 || (TYPE(tree) == try_stmt)
1480 || (TYPE(tree) == funcdef)
1481 || (TYPE(tree) == classdef));
1482 if (res)
1483 res = validate_node(tree);
1484 else {
1485 char buffer[60];
Fred Drake268397f1998-04-29 14:16:32 +00001486 (void) sprintf(buffer, "Illegal compound statement type: %d.",
1487 TYPE(tree));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001488 err_string(buffer);
1489 }
1490 return (res);
1491
1492} /* validate_compound_stmt() */
1493
1494
Guido van Rossum47478871996-08-21 14:32:37 +00001495static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001496validate_expr_stmt(tree)
1497 node *tree;
1498{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001499 int j;
1500 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001501 int res = (validate_ntype(tree, expr_stmt)
1502 && is_odd(nch)
1503 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001504
Guido van Rossum3d602e31996-07-21 02:33:56 +00001505 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001506 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001507 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001508
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001509 return (res);
1510
1511} /* validate_expr_stmt() */
1512
1513
Guido van Rossum3d602e31996-07-21 02:33:56 +00001514/* print_stmt:
1515 *
1516 * 'print' (test ',')* [test]
1517 *
1518 */
Guido van Rossum47478871996-08-21 14:32:37 +00001519static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001520validate_print_stmt(tree)
1521 node *tree;
1522{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001523 int j;
1524 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001525 int res = (validate_ntype(tree, print_stmt)
1526 && (nch != 0)
1527 && validate_name(CHILD(tree, 0), "print"));
1528
1529 if (res && is_even(nch)) {
1530 res = validate_test(CHILD(tree, nch - 1));
1531 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001532 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001533 else if (!res && !PyErr_Occurred())
Fred Drake268397f1998-04-29 14:16:32 +00001534 (void) validate_numnodes(tree, 1, "print_stmt");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001535 for (j = 1; res && (j < nch); j += 2)
1536 res = (validate_test(CHILD(tree, j))
1537 && validate_ntype(CHILD(tree, j + 1), COMMA));
1538
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001539 return (res);
1540
1541} /* validate_print_stmt() */
1542
1543
Guido van Rossum47478871996-08-21 14:32:37 +00001544static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001545validate_del_stmt(tree)
1546 node *tree;
1547{
1548 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001549 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001550 && validate_exprlist(CHILD(tree, 1)));
1551
1552} /* validate_del_stmt() */
1553
1554
Guido van Rossum47478871996-08-21 14:32:37 +00001555static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001556validate_return_stmt(tree)
1557 node *tree;
1558{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001559 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001560 int res = (validate_ntype(tree, return_stmt)
1561 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001562 && validate_name(CHILD(tree, 0), "return"));
1563
Guido van Rossum3d602e31996-07-21 02:33:56 +00001564 if (res && (nch == 2))
1565 res = validate_testlist(CHILD(tree, 1));
1566
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001567 return (res);
1568
1569} /* validate_return_stmt() */
1570
1571
Guido van Rossum47478871996-08-21 14:32:37 +00001572static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001573validate_raise_stmt(tree)
1574 node *tree;
1575{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001576 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001577 int res = (validate_ntype(tree, raise_stmt)
Fred Drakec542bc71998-04-10 04:43:28 +00001578 && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001579
Guido van Rossum3d602e31996-07-21 02:33:56 +00001580 if (res) {
Fred Drakec542bc71998-04-10 04:43:28 +00001581 res = validate_name(CHILD(tree, 0), "raise");
1582 if (res && (nch >= 2))
1583 res = validate_test(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001584 if (res && nch > 2) {
1585 res = (validate_comma(CHILD(tree, 2))
1586 && validate_test(CHILD(tree, 3)));
1587 if (res && (nch > 4))
1588 res = (validate_comma(CHILD(tree, 4))
1589 && validate_test(CHILD(tree, 5)));
1590 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001591 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001592 else
Fred Drake268397f1998-04-29 14:16:32 +00001593 (void) validate_numnodes(tree, 2, "raise");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001594 if (res && (nch == 4))
1595 res = (validate_comma(CHILD(tree, 2))
1596 && validate_test(CHILD(tree, 3)));
1597
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001598 return (res);
1599
1600} /* validate_raise_stmt() */
1601
1602
Guido van Rossum3d602e31996-07-21 02:33:56 +00001603/* import_stmt:
1604 *
1605 * 'import' dotted_name (',' dotted_name)*
1606 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1607 */
Guido van Rossum47478871996-08-21 14:32:37 +00001608static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001609validate_import_stmt(tree)
1610 node *tree;
1611{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001612 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001613 int res = (validate_ntype(tree, import_stmt)
1614 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001615 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001616 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001617
1618 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001619 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001620
Guido van Rossum3d602e31996-07-21 02:33:56 +00001621 for (j = 2; res && (j < nch); j += 2)
1622 res = (validate_comma(CHILD(tree, j))
1623 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001624 }
1625 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001626 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001627 && validate_name(CHILD(tree, 2), "import"));
1628 if (nch == 4) {
1629 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001630 || (TYPE(CHILD(tree, 3)) == STAR));
1631 if (!res)
1632 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001633 }
1634 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001635 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001636 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001637 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001638 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001639 res = (validate_comma(CHILD(tree, j))
1640 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001641 }
1642 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001643 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001644 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001645
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001646 return (res);
1647
1648} /* validate_import_stmt() */
1649
1650
Guido van Rossum47478871996-08-21 14:32:37 +00001651static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001652validate_global_stmt(tree)
1653 node *tree;
1654{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001655 int j;
1656 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001657 int res = (validate_ntype(tree, global_stmt)
1658 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001659
Guido van Rossum3d602e31996-07-21 02:33:56 +00001660 if (res)
1661 res = (validate_name(CHILD(tree, 0), "global")
1662 && validate_ntype(CHILD(tree, 1), NAME));
1663 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001664 res = (validate_comma(CHILD(tree, j))
1665 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001666
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001667 return (res);
1668
1669} /* validate_global_stmt() */
1670
1671
Guido van Rossum3d602e31996-07-21 02:33:56 +00001672/* exec_stmt:
1673 *
1674 * 'exec' expr ['in' test [',' test]]
1675 */
Guido van Rossum47478871996-08-21 14:32:37 +00001676static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001677validate_exec_stmt(tree)
1678 node *tree;
1679{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001680 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001681 int res = (validate_ntype(tree, exec_stmt)
1682 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001683 && validate_name(CHILD(tree, 0), "exec")
1684 && validate_expr(CHILD(tree, 1)));
1685
Guido van Rossum3d602e31996-07-21 02:33:56 +00001686 if (!res && !PyErr_Occurred())
1687 err_string("Illegal exec statement.");
1688 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001689 res = (validate_name(CHILD(tree, 2), "in")
1690 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001691 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001692 res = (validate_comma(CHILD(tree, 4))
1693 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001694
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001695 return (res);
1696
1697} /* validate_exec_stmt() */
1698
1699
Guido van Rossum925e5471997-04-02 05:32:13 +00001700/* assert_stmt:
1701 *
1702 * 'assert' test [',' test]
1703 */
1704static int
1705validate_assert_stmt(tree)
1706 node *tree;
1707{
1708 int nch = NCH(tree);
1709 int res = (validate_ntype(tree, assert_stmt)
1710 && ((nch == 2) || (nch == 4))
1711 && (validate_name(CHILD(tree, 0), "__assert__") ||
1712 validate_name(CHILD(tree, 0), "assert"))
1713 && validate_test(CHILD(tree, 1)));
1714
1715 if (!res && !PyErr_Occurred())
1716 err_string("Illegal assert statement.");
1717 if (res && (nch > 2))
1718 res = (validate_comma(CHILD(tree, 2))
1719 && validate_test(CHILD(tree, 3)));
1720
1721 return (res);
1722
1723} /* validate_assert_stmt() */
1724
1725
Guido van Rossum47478871996-08-21 14:32:37 +00001726static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001727validate_while(tree)
1728 node *tree;
1729{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001730 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001731 int res = (validate_ntype(tree, while_stmt)
1732 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001733 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001734 && validate_test(CHILD(tree, 1))
1735 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001736 && validate_suite(CHILD(tree, 3)));
1737
Guido van Rossum3d602e31996-07-21 02:33:56 +00001738 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001739 res = (validate_name(CHILD(tree, 4), "else")
1740 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001741 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001742
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001743 return (res);
1744
1745} /* validate_while() */
1746
1747
Guido van Rossum47478871996-08-21 14:32:37 +00001748static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001749validate_for(tree)
1750 node *tree;
1751{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001752 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001753 int res = (validate_ntype(tree, for_stmt)
1754 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001755 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001756 && validate_exprlist(CHILD(tree, 1))
1757 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001758 && validate_testlist(CHILD(tree, 3))
1759 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001760 && validate_suite(CHILD(tree, 5)));
1761
Guido van Rossum3d602e31996-07-21 02:33:56 +00001762 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001763 res = (validate_name(CHILD(tree, 6), "else")
1764 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001765 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001766
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001767 return (res);
1768
1769} /* validate_for() */
1770
1771
Guido van Rossum3d602e31996-07-21 02:33:56 +00001772/* try_stmt:
1773 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1774 * | 'try' ':' suite 'finally' ':' suite
1775 *
1776 */
Guido van Rossum47478871996-08-21 14:32:37 +00001777static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001778validate_try(tree)
1779 node *tree;
1780{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001781 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001782 int pos = 3;
1783 int res = (validate_ntype(tree, try_stmt)
1784 && (nch >= 6) && ((nch % 3) == 0));
1785
1786 if (res)
1787 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001788 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001789 && validate_suite(CHILD(tree, 2))
1790 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001791 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001792 else {
1793 const char* name = "execpt";
1794 char buffer[60];
1795 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1796 name = STR(CHILD(tree, nch - 3));
Fred Drake268397f1998-04-29 14:16:32 +00001797 (void) sprintf(buffer,
1798 "Illegal number of children for try/%s node.", name);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001799 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001800 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001801 /* Skip past except_clause sections: */
1802 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1803 res = (validate_except_clause(CHILD(tree, pos))
1804 && validate_colon(CHILD(tree, pos + 1))
1805 && validate_suite(CHILD(tree, pos + 2)));
1806 pos += 3;
1807 }
1808 if (res && (pos < nch)) {
1809 res = validate_ntype(CHILD(tree, pos), NAME);
1810 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1811 res = (validate_numnodes(tree, 6, "try/finally")
1812 && validate_colon(CHILD(tree, 4))
1813 && validate_suite(CHILD(tree, 5)));
Guido van Rossum730806d1998-04-10 22:27:42 +00001814 else if (res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001815 if (nch == (pos + 3)) {
1816 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1817 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1818 if (!res)
1819 err_string("Illegal trailing triple in try statement.");
1820 }
Guido van Rossum730806d1998-04-10 22:27:42 +00001821 else if (nch == (pos + 6)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001822 res = (validate_name(CHILD(tree, pos), "except")
1823 && validate_colon(CHILD(tree, pos + 1))
1824 && validate_suite(CHILD(tree, pos + 2))
1825 && validate_name(CHILD(tree, pos + 3), "else"));
Guido van Rossum730806d1998-04-10 22:27:42 +00001826 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001827 else
1828 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossum730806d1998-04-10 22:27:42 +00001829 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001830 }
1831 return (res);
1832
1833} /* validate_try() */
1834
1835
Guido van Rossum47478871996-08-21 14:32:37 +00001836static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001837validate_except_clause(tree)
1838 node *tree;
1839{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001840 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001841 int res = (validate_ntype(tree, except_clause)
1842 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001843 && validate_name(CHILD(tree, 0), "except"));
1844
Guido van Rossum3d602e31996-07-21 02:33:56 +00001845 if (res && (nch > 1))
1846 res = validate_test(CHILD(tree, 1));
1847 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001848 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001849 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001850
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001851 return (res);
1852
1853} /* validate_except_clause() */
1854
1855
Guido van Rossum47478871996-08-21 14:32:37 +00001856static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001857validate_test(tree)
1858 node *tree;
1859{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001860 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001861 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001862
Guido van Rossum3d602e31996-07-21 02:33:56 +00001863 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001864 res = ((nch == 1)
1865 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001866 else if (res) {
1867 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001868 res = validate_and_test(CHILD(tree, 0));
1869 for (pos = 1; res && (pos < nch); pos += 2)
1870 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001871 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001872 }
1873 return (res);
1874
1875} /* validate_test() */
1876
1877
Guido van Rossum47478871996-08-21 14:32:37 +00001878static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001879validate_and_test(tree)
1880 node *tree;
1881{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001882 int pos;
1883 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001884 int res = (validate_ntype(tree, and_test)
1885 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001886 && validate_not_test(CHILD(tree, 0)));
1887
Guido van Rossum3d602e31996-07-21 02:33:56 +00001888 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001889 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001890 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001891
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001892 return (res);
1893
1894} /* validate_and_test() */
1895
1896
Guido van Rossum47478871996-08-21 14:32:37 +00001897static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001898validate_not_test(tree)
1899 node *tree;
1900{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001901 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001902 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001903
Guido van Rossum3d602e31996-07-21 02:33:56 +00001904 if (res) {
1905 if (nch == 2)
1906 res = (validate_name(CHILD(tree, 0), "not")
1907 && validate_not_test(CHILD(tree, 1)));
1908 else if (nch == 1)
1909 res = validate_comparison(CHILD(tree, 0));
1910 }
1911 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001912
1913} /* validate_not_test() */
1914
1915
Guido van Rossum47478871996-08-21 14:32:37 +00001916static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001917validate_comparison(tree)
1918 node *tree;
1919{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001920 int pos;
1921 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001922 int res = (validate_ntype(tree, comparison)
1923 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001924 && validate_expr(CHILD(tree, 0)));
1925
Guido van Rossum3d602e31996-07-21 02:33:56 +00001926 for (pos = 1; res && (pos < nch); pos += 2)
1927 res = (validate_comp_op(CHILD(tree, pos))
1928 && validate_expr(CHILD(tree, pos + 1)));
1929
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001930 return (res);
1931
1932} /* validate_comparison() */
1933
1934
Guido van Rossum47478871996-08-21 14:32:37 +00001935static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001936validate_comp_op(tree)
1937 node *tree;
1938{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001939 int res = 0;
1940 int nch = NCH(tree);
1941
Guido van Rossum3d602e31996-07-21 02:33:56 +00001942 if (!validate_ntype(tree, comp_op))
1943 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001944 if (nch == 1) {
1945 /*
1946 * Only child will be a terminal with a well-defined symbolic name
1947 * or a NAME with a string of either 'is' or 'in'
1948 */
1949 tree = CHILD(tree, 0);
1950 switch (TYPE(tree)) {
1951 case LESS:
1952 case GREATER:
1953 case EQEQUAL:
1954 case EQUAL:
1955 case LESSEQUAL:
1956 case GREATEREQUAL:
1957 case NOTEQUAL:
1958 res = 1;
1959 break;
1960 case NAME:
1961 res = ((strcmp(STR(tree), "in") == 0)
1962 || (strcmp(STR(tree), "is") == 0));
1963 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001964 char buff[128];
Fred Drake268397f1998-04-29 14:16:32 +00001965 (void) sprintf(buff, "Illegal operator: '%s'.", STR(tree));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001966 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001967 }
1968 break;
1969 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001970 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001971 break;
1972 }
1973 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001974 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001975 res = (validate_ntype(CHILD(tree, 0), NAME)
1976 && validate_ntype(CHILD(tree, 1), NAME)
1977 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1978 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1979 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1980 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001981 if (!res && !PyErr_Occurred())
1982 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001983 }
1984 return (res);
1985
1986} /* validate_comp_op() */
1987
1988
Guido van Rossum47478871996-08-21 14:32:37 +00001989static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001990validate_expr(tree)
1991 node *tree;
1992{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001993 int j;
1994 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001995 int res = (validate_ntype(tree, expr)
1996 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001997 && validate_xor_expr(CHILD(tree, 0)));
1998
Guido van Rossum3d602e31996-07-21 02:33:56 +00001999 for (j = 2; res && (j < nch); j += 2)
2000 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002001 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002002
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002003 return (res);
2004
2005} /* validate_expr() */
2006
2007
Guido van Rossum47478871996-08-21 14:32:37 +00002008static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002009validate_xor_expr(tree)
2010 node *tree;
2011{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002012 int j;
2013 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002014 int res = (validate_ntype(tree, xor_expr)
2015 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002016 && validate_and_expr(CHILD(tree, 0)));
2017
Guido van Rossum3d602e31996-07-21 02:33:56 +00002018 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002019 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002020 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002021
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002022 return (res);
2023
2024} /* validate_xor_expr() */
2025
2026
Guido van Rossum47478871996-08-21 14:32:37 +00002027static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002028validate_and_expr(tree)
2029 node *tree;
2030{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002031 int pos;
2032 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002033 int res = (validate_ntype(tree, and_expr)
2034 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002035 && validate_shift_expr(CHILD(tree, 0)));
2036
Guido van Rossum3d602e31996-07-21 02:33:56 +00002037 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002038 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002039 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002040
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002041 return (res);
2042
2043} /* validate_and_expr() */
2044
2045
2046static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002047validate_chain_two_ops(tree, termvalid, op1, op2)
2048 node *tree;
2049 int (*termvalid)();
2050 int op1;
2051 int op2;
2052 {
2053 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002054 int nch = NCH(tree);
2055 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002056 && (*termvalid)(CHILD(tree, 0)));
2057
Guido van Rossum3d602e31996-07-21 02:33:56 +00002058 for ( ; res && (pos < nch); pos += 2) {
2059 if (TYPE(CHILD(tree, pos)) != op1)
2060 res = validate_ntype(CHILD(tree, pos), op2);
2061 if (res)
2062 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002063 }
2064 return (res);
2065
2066} /* validate_chain_two_ops() */
2067
2068
Guido van Rossum47478871996-08-21 14:32:37 +00002069static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002070validate_shift_expr(tree)
2071 node *tree;
2072{
2073 return (validate_ntype(tree, shift_expr)
2074 && validate_chain_two_ops(tree, validate_arith_expr,
2075 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002076
2077} /* validate_shift_expr() */
2078
2079
Guido van Rossum47478871996-08-21 14:32:37 +00002080static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002081validate_arith_expr(tree)
2082 node *tree;
2083{
2084 return (validate_ntype(tree, arith_expr)
2085 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002086
2087} /* validate_arith_expr() */
2088
2089
Guido van Rossum47478871996-08-21 14:32:37 +00002090static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002091validate_term(tree)
2092 node *tree;
2093{
2094 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002095 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002096 int res = (validate_ntype(tree, term)
2097 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002098 && validate_factor(CHILD(tree, 0)));
2099
Guido van Rossum3d602e31996-07-21 02:33:56 +00002100 for ( ; res && (pos < nch); pos += 2)
2101 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002102 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002103 || (TYPE(CHILD(tree, pos)) == PERCENT))
2104 && validate_factor(CHILD(tree, pos + 1)));
2105
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002106 return (res);
2107
2108} /* validate_term() */
2109
2110
Guido van Rossum3d602e31996-07-21 02:33:56 +00002111/* factor:
2112 *
2113 * factor: ('+'|'-'|'~') factor | power
2114 */
Guido van Rossum47478871996-08-21 14:32:37 +00002115static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002116validate_factor(tree)
2117 node *tree;
2118{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002119 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002120 int res = (validate_ntype(tree, factor)
2121 && (((nch == 2)
2122 && ((TYPE(CHILD(tree, 0)) == PLUS)
2123 || (TYPE(CHILD(tree, 0)) == MINUS)
2124 || (TYPE(CHILD(tree, 0)) == TILDE))
2125 && validate_factor(CHILD(tree, 1)))
2126 || ((nch == 1)
2127 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002128 return (res);
2129
2130} /* validate_factor() */
2131
2132
Guido van Rossum3d602e31996-07-21 02:33:56 +00002133/* power:
2134 *
2135 * power: atom trailer* ('**' factor)*
2136 */
Guido van Rossum47478871996-08-21 14:32:37 +00002137static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002138validate_power(tree)
2139 node *tree;
2140{
2141 int pos = 1;
2142 int nch = NCH(tree);
2143 int res = (validate_ntype(tree, power) && (nch >= 1)
2144 && validate_atom(CHILD(tree, 0)));
2145
2146 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2147 res = validate_trailer(CHILD(tree, pos++));
2148 if (res && (pos < nch)) {
2149 if (!is_even(nch - pos)) {
2150 err_string("Illegal number of nodes for 'power'.");
2151 return (0);
2152 }
2153 for ( ; res && (pos < (nch - 1)); pos += 2)
2154 res = (validate_doublestar(CHILD(tree, pos))
2155 && validate_factor(CHILD(tree, pos + 1)));
2156 }
2157 return (res);
2158
2159} /* validate_power() */
2160
2161
Guido van Rossum47478871996-08-21 14:32:37 +00002162static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002163validate_atom(tree)
2164 node *tree;
2165{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002166 int pos;
2167 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002168 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002169
2170 if (res) {
2171 switch (TYPE(CHILD(tree, 0))) {
2172 case LPAR:
2173 res = ((nch <= 3)
2174 && (validate_rparen(CHILD(tree, nch - 1))));
2175
Guido van Rossum3d602e31996-07-21 02:33:56 +00002176 if (res && (nch == 3))
2177 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002178 break;
2179 case LSQB:
2180 res = ((nch <= 3)
2181 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2182
Guido van Rossum3d602e31996-07-21 02:33:56 +00002183 if (res && (nch == 3))
2184 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002185 break;
2186 case LBRACE:
2187 res = ((nch <= 3)
2188 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2189
Guido van Rossum3d602e31996-07-21 02:33:56 +00002190 if (res && (nch == 3))
2191 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002192 break;
2193 case BACKQUOTE:
2194 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002195 && validate_testlist(CHILD(tree, 1))
2196 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2197 break;
2198 case NAME:
2199 case NUMBER:
2200 res = (nch == 1);
2201 break;
2202 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002203 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002204 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002205 break;
2206 default:
2207 res = 0;
2208 break;
2209 }
2210 }
2211 return (res);
2212
2213} /* validate_atom() */
2214
2215
Guido van Rossum3d602e31996-07-21 02:33:56 +00002216/* funcdef:
2217 * 'def' NAME parameters ':' suite
2218 *
2219 */
Guido van Rossum47478871996-08-21 14:32:37 +00002220static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002221validate_funcdef(tree)
2222 node *tree;
2223{
2224 return (validate_ntype(tree, funcdef)
2225 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002226 && validate_name(CHILD(tree, 0), "def")
2227 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002228 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002229 && validate_parameters(CHILD(tree, 2))
2230 && validate_suite(CHILD(tree, 4)));
2231
2232} /* validate_funcdef() */
2233
2234
Guido van Rossum47478871996-08-21 14:32:37 +00002235static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002236validate_lambdef(tree)
2237 node *tree;
2238{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002239 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002240 int res = (validate_ntype(tree, lambdef)
2241 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002242 && validate_name(CHILD(tree, 0), "lambda")
2243 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002244 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002245
Guido van Rossum3d602e31996-07-21 02:33:56 +00002246 if (res && (nch == 4))
2247 res = validate_varargslist(CHILD(tree, 1));
2248 else if (!res && !PyErr_Occurred())
Fred Drake268397f1998-04-29 14:16:32 +00002249 (void) validate_numnodes(tree, 3, "lambdef");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002250
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002251 return (res);
2252
2253} /* validate_lambdef() */
2254
2255
Guido van Rossum3d602e31996-07-21 02:33:56 +00002256/* arglist:
2257 *
2258 * argument (',' argument)* [',']
2259 */
Guido van Rossum47478871996-08-21 14:32:37 +00002260static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002261validate_arglist(tree)
2262 node *tree;
2263{
Guido van Rossum47478871996-08-21 14:32:37 +00002264 return (validate_repeating_list(tree, arglist,
2265 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002266
2267} /* validate_arglist() */
2268
2269
2270
2271/* argument:
2272 *
2273 * [test '='] test
2274 */
Guido van Rossum47478871996-08-21 14:32:37 +00002275static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002276validate_argument(tree)
2277 node *tree;
2278{
2279 int nch = NCH(tree);
2280 int res = (validate_ntype(tree, argument)
2281 && ((nch == 1) || (nch == 3))
2282 && validate_test(CHILD(tree, 0)));
2283
2284 if (res && (nch == 3))
2285 res = (validate_equal(CHILD(tree, 1))
2286 && validate_test(CHILD(tree, 2)));
2287
2288 return (res);
2289
2290} /* validate_argument() */
2291
2292
2293
2294/* trailer:
2295 *
Guido van Rossum47478871996-08-21 14:32:37 +00002296 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002297 */
Guido van Rossum47478871996-08-21 14:32:37 +00002298static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002299validate_trailer(tree)
2300 node *tree;
2301{
2302 int nch = NCH(tree);
2303 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002304
2305 if (res) {
2306 switch (TYPE(CHILD(tree, 0))) {
2307 case LPAR:
2308 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002309 if (res && (nch == 3))
2310 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002311 break;
2312 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002313 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002314 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002315 && validate_ntype(CHILD(tree, 2), RSQB));
2316 break;
2317 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002318 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002319 && validate_ntype(CHILD(tree, 1), NAME));
2320 break;
2321 default:
2322 res = 0;
2323 break;
2324 }
2325 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002326 else
Fred Drake268397f1998-04-29 14:16:32 +00002327 (void) validate_numnodes(tree, 2, "trailer");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002328
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002329 return (res);
2330
2331} /* validate_trailer() */
2332
2333
Guido van Rossum47478871996-08-21 14:32:37 +00002334/* subscriptlist:
2335 *
2336 * subscript (',' subscript)* [',']
2337 */
2338static int
2339validate_subscriptlist(tree)
2340 node *tree;
2341{
2342 return (validate_repeating_list(tree, subscriptlist,
2343 validate_subscript, "subscriptlist"));
2344
2345} /* validate_subscriptlist() */
2346
2347
Guido van Rossum3d602e31996-07-21 02:33:56 +00002348/* subscript:
2349 *
Guido van Rossum47478871996-08-21 14:32:37 +00002350 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002351 */
Guido van Rossum47478871996-08-21 14:32:37 +00002352static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002353validate_subscript(tree)
2354 node *tree;
2355{
Guido van Rossum47478871996-08-21 14:32:37 +00002356 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002357 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002358 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002359
Guido van Rossum47478871996-08-21 14:32:37 +00002360 if (!res) {
2361 if (!PyErr_Occurred())
2362 err_string("invalid number of arguments for subscript node");
2363 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002364 }
Guido van Rossum47478871996-08-21 14:32:37 +00002365 if (TYPE(CHILD(tree, 0)) == DOT)
2366 /* take care of ('.' '.' '.') possibility */
2367 return (validate_numnodes(tree, 3, "subscript")
2368 && validate_dot(CHILD(tree, 0))
2369 && validate_dot(CHILD(tree, 1))
2370 && validate_dot(CHILD(tree, 2)));
2371 if (nch == 1) {
2372 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002373 res = validate_test(CHILD(tree, 0));
2374 else
Guido van Rossum47478871996-08-21 14:32:37 +00002375 res = validate_colon(CHILD(tree, 0));
2376 return (res);
2377 }
2378 /* Must be [test] ':' [test] [sliceop],
2379 * but at least one of the optional components will
2380 * be present, but we don't know which yet.
2381 */
2382 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2383 res = validate_test(CHILD(tree, 0));
2384 offset = 1;
2385 }
2386 if (res)
2387 res = validate_colon(CHILD(tree, offset));
2388 if (res) {
2389 int rem = nch - ++offset;
2390 if (rem) {
2391 if (TYPE(CHILD(tree, offset)) == test) {
2392 res = validate_test(CHILD(tree, offset));
2393 ++offset;
2394 --rem;
2395 }
2396 if (res && rem)
2397 res = validate_sliceop(CHILD(tree, offset));
2398 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002399 }
2400 return (res);
2401
2402} /* validate_subscript() */
2403
2404
Guido van Rossum47478871996-08-21 14:32:37 +00002405static int
2406validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002407 node *tree;
2408{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002409 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002410 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2411 && validate_ntype(tree, sliceop);
2412 if (!res && !PyErr_Occurred()) {
Fred Drake268397f1998-04-29 14:16:32 +00002413 res = validate_numnodes(tree, 1, "sliceop");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002414 }
Guido van Rossum47478871996-08-21 14:32:37 +00002415 if (res)
2416 res = validate_colon(CHILD(tree, 0));
2417 if (res && (nch == 2))
2418 res = validate_test(CHILD(tree, 1));
2419
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002420 return (res);
2421
Guido van Rossum47478871996-08-21 14:32:37 +00002422} /* validate_sliceop() */
2423
2424
2425static int
2426validate_exprlist(tree)
2427 node *tree;
2428{
2429 return (validate_repeating_list(tree, exprlist,
2430 validate_expr, "exprlist"));
2431
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002432} /* validate_exprlist() */
2433
2434
Guido van Rossum47478871996-08-21 14:32:37 +00002435static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002436validate_dictmaker(tree)
2437 node *tree;
2438{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002439 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002440 int res = (validate_ntype(tree, dictmaker)
2441 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002442 && validate_test(CHILD(tree, 0))
2443 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002444 && validate_test(CHILD(tree, 2)));
2445
Guido van Rossum3d602e31996-07-21 02:33:56 +00002446 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002447 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002448 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002449 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002450
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002451 if (res && (nch > 3)) {
2452 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002453 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002454 while (res && (pos < nch)) {
2455 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002456 && validate_test(CHILD(tree, pos + 1))
2457 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002458 && validate_test(CHILD(tree, pos + 3)));
2459 pos += 4;
2460 }
2461 }
2462 return (res);
2463
2464} /* validate_dictmaker() */
2465
2466
Guido van Rossum47478871996-08-21 14:32:37 +00002467static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002468validate_eval_input(tree)
2469 node *tree;
2470{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002471 int pos;
2472 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002473 int res = (validate_ntype(tree, eval_input)
2474 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002475 && validate_testlist(CHILD(tree, 0))
2476 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2477
Guido van Rossum3d602e31996-07-21 02:33:56 +00002478 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002479 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002480
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002481 return (res);
2482
2483} /* validate_eval_input() */
2484
2485
Guido van Rossum47478871996-08-21 14:32:37 +00002486static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002487validate_node(tree)
2488 node *tree;
2489{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002490 int nch = 0; /* num. children on current node */
2491 int res = 1; /* result value */
2492 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002493
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002494 while (res & (tree != 0)) {
2495 nch = NCH(tree);
2496 next = 0;
2497 switch (TYPE(tree)) {
2498 /*
2499 * Definition nodes.
2500 */
2501 case funcdef:
2502 res = validate_funcdef(tree);
2503 break;
2504 case classdef:
2505 res = validate_class(tree);
2506 break;
2507 /*
2508 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002509 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002510 */
2511 case stmt:
2512 res = validate_stmt(tree);
2513 break;
2514 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002515 /*
2516 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum925e5471997-04-02 05:32:13 +00002517 * | import_stmt | global_stmt | exec_stmt | assert_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002518 */
2519 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002520 break;
2521 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002522 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002523 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2524 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2525 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002526 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2527 if (res)
2528 next = CHILD(tree, 0);
2529 else if (nch == 1)
2530 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002531 break;
2532 /*
2533 * Compound statements.
2534 */
2535 case simple_stmt:
2536 res = validate_simple_stmt(tree);
2537 break;
2538 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002539 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002540 break;
2541 /*
2542 * Fundemental statements.
2543 */
2544 case expr_stmt:
2545 res = validate_expr_stmt(tree);
2546 break;
2547 case print_stmt:
2548 res = validate_print_stmt(tree);
2549 break;
2550 case del_stmt:
2551 res = validate_del_stmt(tree);
2552 break;
2553 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002554 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002555 && validate_name(CHILD(tree, 0), "pass"));
2556 break;
2557 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002558 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002559 && validate_name(CHILD(tree, 0), "break"));
2560 break;
2561 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002562 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002563 && validate_name(CHILD(tree, 0), "continue"));
2564 break;
2565 case return_stmt:
2566 res = validate_return_stmt(tree);
2567 break;
2568 case raise_stmt:
2569 res = validate_raise_stmt(tree);
2570 break;
2571 case import_stmt:
2572 res = validate_import_stmt(tree);
2573 break;
2574 case global_stmt:
2575 res = validate_global_stmt(tree);
2576 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002577 case exec_stmt:
2578 res = validate_exec_stmt(tree);
2579 break;
Guido van Rossum925e5471997-04-02 05:32:13 +00002580 case assert_stmt:
2581 res = validate_assert_stmt(tree);
2582 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002583 case if_stmt:
2584 res = validate_if(tree);
2585 break;
2586 case while_stmt:
2587 res = validate_while(tree);
2588 break;
2589 case for_stmt:
2590 res = validate_for(tree);
2591 break;
2592 case try_stmt:
2593 res = validate_try(tree);
2594 break;
2595 case suite:
2596 res = validate_suite(tree);
2597 break;
2598 /*
2599 * Expression nodes.
2600 */
2601 case testlist:
2602 res = validate_testlist(tree);
2603 break;
2604 case test:
2605 res = validate_test(tree);
2606 break;
2607 case and_test:
2608 res = validate_and_test(tree);
2609 break;
2610 case not_test:
2611 res = validate_not_test(tree);
2612 break;
2613 case comparison:
2614 res = validate_comparison(tree);
2615 break;
2616 case exprlist:
2617 res = validate_exprlist(tree);
2618 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002619 case comp_op:
2620 res = validate_comp_op(tree);
2621 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002622 case expr:
2623 res = validate_expr(tree);
2624 break;
2625 case xor_expr:
2626 res = validate_xor_expr(tree);
2627 break;
2628 case and_expr:
2629 res = validate_and_expr(tree);
2630 break;
2631 case shift_expr:
2632 res = validate_shift_expr(tree);
2633 break;
2634 case arith_expr:
2635 res = validate_arith_expr(tree);
2636 break;
2637 case term:
2638 res = validate_term(tree);
2639 break;
2640 case factor:
2641 res = validate_factor(tree);
2642 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002643 case power:
2644 res = validate_power(tree);
2645 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002646 case atom:
2647 res = validate_atom(tree);
2648 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002649
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002650 default:
2651 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002652 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002653 res = 0;
2654 break;
2655 }
2656 tree = next;
2657 }
2658 return (res);
2659
2660} /* validate_node() */
2661
2662
Guido van Rossum47478871996-08-21 14:32:37 +00002663static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002664validate_expr_tree(tree)
2665 node *tree;
2666{
2667 int res = validate_eval_input(tree);
2668
2669 if (!res && !PyErr_Occurred())
2670 err_string("Could not validate expression tuple.");
2671
2672 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002673
2674} /* validate_expr_tree() */
2675
2676
Guido van Rossum3d602e31996-07-21 02:33:56 +00002677/* file_input:
2678 * (NEWLINE | stmt)* ENDMARKER
2679 */
Guido van Rossum47478871996-08-21 14:32:37 +00002680static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002681validate_file_input(tree)
2682 node *tree;
2683{
2684 int j = 0;
2685 int nch = NCH(tree) - 1;
2686 int res = ((nch >= 0)
2687 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002688
Guido van Rossum3d602e31996-07-21 02:33:56 +00002689 for ( ; res && (j < nch); ++j) {
2690 if (TYPE(CHILD(tree, j)) == stmt)
2691 res = validate_stmt(CHILD(tree, j));
2692 else
2693 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002694 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002695 /* This stays in to prevent any internal failues from getting to the
2696 * user. Hopefully, this won't be needed. If a user reports getting
2697 * this, we have some debugging to do.
2698 */
2699 if (!res && !PyErr_Occurred())
2700 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2701
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002702 return (res);
2703
Guido van Rossum2a288461996-08-21 21:55:43 +00002704} /* validate_file_input() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002705
2706
Fred Drake43f8f9b1998-04-13 16:25:46 +00002707static PyObject*
2708pickle_constructor = NULL;
2709
2710
2711static PyObject*
2712parser__pickler(self, args)
2713 PyObject *self;
2714 PyObject *args;
2715{
Fred Drake268397f1998-04-29 14:16:32 +00002716 NOTE(ARGUNUSED(self))
Fred Drake43f8f9b1998-04-13 16:25:46 +00002717 PyObject *result = NULL;
2718 PyObject *ast = NULL;
Fred Drake2a6875e1999-09-20 22:32:18 +00002719 PyObject *empty_dict = NULL;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002720
2721 if (PyArg_ParseTuple(args, "O!:_pickler", &PyAST_Type, &ast)) {
2722 PyObject *newargs;
2723 PyObject *tuple;
2724
Fred Drake2a6875e1999-09-20 22:32:18 +00002725 if ((empty_dict = PyDict_New()) == NULL)
2726 goto finally;
2727 if ((newargs = Py_BuildValue("Oi", ast, 1)) == NULL)
Fred Drake43f8f9b1998-04-13 16:25:46 +00002728 goto finally;
Fred Drake2a6875e1999-09-20 22:32:18 +00002729 tuple = parser_ast2tuple((PyAST_Object*)NULL, newargs, empty_dict);
Fred Drake43f8f9b1998-04-13 16:25:46 +00002730 if (tuple != NULL) {
2731 result = Py_BuildValue("O(O)", pickle_constructor, tuple);
2732 Py_DECREF(tuple);
2733 }
Fred Drake2a6875e1999-09-20 22:32:18 +00002734 Py_DECREF(empty_dict);
Fred Drake7f875ef1998-08-04 15:58:10 +00002735 Py_DECREF(newargs);
Fred Drake43f8f9b1998-04-13 16:25:46 +00002736 }
2737 finally:
Fred Drake2a6875e1999-09-20 22:32:18 +00002738 Py_XDECREF(empty_dict);
2739
Fred Drake43f8f9b1998-04-13 16:25:46 +00002740 return (result);
2741
2742} /* parser__pickler() */
2743
2744
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002745/* Functions exported by this module. Most of this should probably
2746 * be converted into an AST object with methods, but that is better
2747 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002748 * We'd really have to write a wrapper around it all anyway to allow
2749 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002750 */
2751static PyMethodDef parser_functions[] = {
Fred Drake7a15ba51999-09-09 14:21:52 +00002752 {"ast2tuple", (PyCFunction)parser_ast2tuple, PUBLIC_METHOD_TYPE,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002753 "Creates a tuple-tree representation of an AST."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002754 {"ast2list", (PyCFunction)parser_ast2list, PUBLIC_METHOD_TYPE,
Guido van Rossum47478871996-08-21 14:32:37 +00002755 "Creates a list-tree representation of an AST."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002756 {"compileast", (PyCFunction)parser_compileast, PUBLIC_METHOD_TYPE,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002757 "Compiles an AST object into a code object."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002758 {"expr", (PyCFunction)parser_expr, PUBLIC_METHOD_TYPE,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002759 "Creates an AST object from an expression."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002760 {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002761 "Determines if an AST object was created from an expression."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002762 {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002763 "Determines if an AST object was created from a suite."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002764 {"suite", (PyCFunction)parser_suite, PUBLIC_METHOD_TYPE,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002765 "Creates an AST object from a suite."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002766 {"sequence2ast", (PyCFunction)parser_tuple2ast, PUBLIC_METHOD_TYPE,
Guido van Rossum47478871996-08-21 14:32:37 +00002767 "Creates an AST object from a tree representation."},
Fred Drake7a15ba51999-09-09 14:21:52 +00002768 {"tuple2ast", (PyCFunction)parser_tuple2ast, PUBLIC_METHOD_TYPE,
Guido van Rossum47478871996-08-21 14:32:37 +00002769 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002770
Fred Drake43f8f9b1998-04-13 16:25:46 +00002771 /* private stuff: support pickle module */
Fred Drake301b5be1998-04-21 22:31:45 +00002772 {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS,
Fred Drake43f8f9b1998-04-13 16:25:46 +00002773 "Returns the pickle magic to allow ast objects to be pickled."},
2774
Fred Drake268397f1998-04-29 14:16:32 +00002775 {NULL, NULL, 0, NULL}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002776 };
2777
2778
Guido van Rossum3886bb61998-12-04 18:50:17 +00002779DL_EXPORT(void)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002780initparser()
2781 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002782 PyObject* module;
2783 PyObject* dict;
2784
2785 PyAST_Type.ob_type = &PyType_Type;
2786 module = Py_InitModule("parser", parser_functions);
2787 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002788
Fred Drake7a15ba51999-09-09 14:21:52 +00002789 if (parser_error == 0)
2790 parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
2791 else
2792 puts("parser module initialized more than once!");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002793
2794 if ((parser_error == 0)
2795 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2796 /*
2797 * This is serious.
2798 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002799 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002800 }
2801 /*
2802 * Nice to have, but don't cry if we fail.
2803 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002804 Py_INCREF(&PyAST_Type);
2805 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2806
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002807 PyDict_SetItemString(dict, "__copyright__",
2808 PyString_FromString(parser_copyright_string));
2809 PyDict_SetItemString(dict, "__doc__",
2810 PyString_FromString(parser_doc_string));
2811 PyDict_SetItemString(dict, "__version__",
2812 PyString_FromString(parser_version_string));
2813
Fred Drake43f8f9b1998-04-13 16:25:46 +00002814 /* register to support pickling */
2815 module = PyImport_ImportModule("copy_reg");
2816 if (module != NULL) {
Fred Drake301b5be1998-04-21 22:31:45 +00002817 PyObject *func, *pickler;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002818
2819 func = PyObject_GetAttrString(module, "pickle");
2820 pickle_constructor = PyDict_GetItemString(dict, "sequence2ast");
2821 pickler = PyDict_GetItemString(dict, "_pickler");
2822 Py_XINCREF(pickle_constructor);
2823 if ((func != NULL) && (pickle_constructor != NULL)
2824 && (pickler != NULL)) {
2825 PyObject *res;
2826
2827 res = PyObject_CallFunction(
2828 func, "OOO", &PyAST_Type, pickler, pickle_constructor);
2829 Py_XDECREF(res);
2830 }
2831 Py_XDECREF(func);
2832 Py_DECREF(module);
2833 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002834} /* initparser() */