blob: 6dd3be354203fdad5355d1e1de539e772dcb07c4 [file] [log] [blame]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001/* parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002 *
Guido van Rossum47478871996-08-21 14:32:37 +00003 * Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic
4 * Institute and State University, Blacksburg, Virginia, USA.
5 * Portions copyright 1991-1995 by Stichting Mathematisch Centrum,
6 * Amsterdam, The Netherlands. Copying is permitted under the terms
7 * associated with the main Python distribution, with the additional
8 * restriction that this additional notice be included and maintained
9 * on all distributed copies.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000010 *
Guido van Rossum47478871996-08-21 14:32:37 +000011 * This module serves to replace the original parser module written
12 * by Guido. The functionality is not matched precisely, but the
13 * original may be implemented on top of this. This is desirable
14 * since the source of the text to be parsed is now divorced from
15 * this interface.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000016 *
Guido van Rossum47478871996-08-21 14:32:37 +000017 * Unlike the prior interface, the ability to give a parse tree
18 * produced by Python code as a tuple to the compiler is enabled by
19 * this module. See the documentation for more details.
Fred Drake268397f1998-04-29 14:16:32 +000020 *
21 * I've added some annotations that help with the lint code-checking
22 * program, but they're not complete by a long shot. The real errors
23 * that lint detects are gone, but there are still warnings with
24 * Py_[X]DECREF() and Py_[X]INCREF() macros. The lint annotations
25 * look like "NOTE(...)".
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000026 */
27
28#include "Python.h" /* general Python API */
29#include "graminit.h" /* symbols defined in the grammar */
30#include "node.h" /* internal parser structure */
31#include "token.h" /* token definitions */
32 /* ISTERMINAL() / ISNONTERMINAL() */
Guido van Rossum3d602e31996-07-21 02:33:56 +000033#include "compile.h" /* PyNode_Compile() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000034
Fred Drake268397f1998-04-29 14:16:32 +000035#ifdef lint
36#include <note.h>
37#else
38#define NOTE(x)
39#endif
40
Guido van Rossum19efc5f1998-04-28 16:10:19 +000041#ifdef macintosh
42char *strdup Py_PROTO((char *));
43#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000044
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000045/* String constants used to initialize module attributes.
46 *
47 */
48static char*
49parser_copyright_string
Guido van Rossum2a288461996-08-21 21:55:43 +000050= "Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
51University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
52Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\
53Centrum, Amsterdam, The Netherlands.";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000054
55
56static char*
57parser_doc_string
58= "This is an interface to Python's internal parser.";
59
60static char*
Guido van Rossum47478871996-08-21 14:32:37 +000061parser_version_string = "0.4";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000062
63
Guido van Rossum2a288461996-08-21 21:55:43 +000064typedef PyObject* (*SeqMaker) Py_PROTO((int length));
Fred Drake268397f1998-04-29 14:16:32 +000065typedef int (*SeqInserter) Py_PROTO((PyObject* sequence,
66 int index,
67 PyObject* element));
Guido van Rossum47478871996-08-21 14:32:37 +000068
Guido van Rossum3d602e31996-07-21 02:33:56 +000069/* The function below is copyrigthed by Stichting Mathematisch Centrum. The
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000070 * original copyright statement is included below, and continues to apply
71 * in full to the function immediately following. All other material is
72 * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
73 * Institute and State University. Changes were made to comply with the
Guido van Rossum2a288461996-08-21 21:55:43 +000074 * new naming conventions. Added arguments to provide support for creating
75 * lists as well as tuples, and optionally including the line numbers.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000076 */
77
Guido van Rossum52f2c051993-11-10 12:53:24 +000078/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +000079Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
80The Netherlands.
Guido van Rossum52f2c051993-11-10 12:53:24 +000081
82 All Rights Reserved
83
Guido van Rossum3d602e31996-07-21 02:33:56 +000084Permission to use, copy, modify, and distribute this software and its
85documentation for any purpose and without fee is hereby granted,
Guido van Rossum52f2c051993-11-10 12:53:24 +000086provided that the above copyright notice appear in all copies and that
Guido van Rossum3d602e31996-07-21 02:33:56 +000087both that copyright notice and this permission notice appear in
Guido van Rossum52f2c051993-11-10 12:53:24 +000088supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000089Centrum or CWI or Corporation for National Research Initiatives or
90CNRI not be used in advertising or publicity pertaining to
91distribution of the software without specific, written prior
92permission.
Guido van Rossum52f2c051993-11-10 12:53:24 +000093
Guido van Rossumd266eb41996-10-25 14:44:06 +000094While CWI is the initial source for this software, a modified version
95is made available by the Corporation for National Research Initiatives
96(CNRI) at the Internet address ftp://ftp.python.org.
97
98STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
99REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
100MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
101CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
102DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
103PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
104TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
105PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum52f2c051993-11-10 12:53:24 +0000106
107******************************************************************/
108
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000109static PyObject*
Guido van Rossum47478871996-08-21 14:32:37 +0000110node2tuple(n, mkseq, addelem, lineno)
111 node *n; /* node to convert */
112 SeqMaker mkseq; /* create sequence */
113 SeqInserter addelem; /* func. to add elem. in seq. */
114 int lineno; /* include line numbers? */
115{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000116 if (n == NULL) {
117 Py_INCREF(Py_None);
Fred Drake268397f1998-04-29 14:16:32 +0000118 return (Py_None);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000119 }
120 if (ISNONTERMINAL(TYPE(n))) {
121 int i;
Fred Drake268397f1998-04-29 14:16:32 +0000122 PyObject *v;
123 PyObject *w;
124
Guido van Rossum47478871996-08-21 14:32:37 +0000125 v = mkseq(1 + NCH(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000126 if (v == NULL)
Fred Drake268397f1998-04-29 14:16:32 +0000127 return (v);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000128 w = PyInt_FromLong(TYPE(n));
129 if (w == NULL) {
130 Py_DECREF(v);
Fred Drake268397f1998-04-29 14:16:32 +0000131 return ((PyObject*) NULL);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000132 }
Fred Drake268397f1998-04-29 14:16:32 +0000133 (void) addelem(v, 0, w);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000134 for (i = 0; i < NCH(n); i++) {
Guido van Rossum47478871996-08-21 14:32:37 +0000135 w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000136 if (w == NULL) {
137 Py_DECREF(v);
Fred Drake268397f1998-04-29 14:16:32 +0000138 return ((PyObject*) NULL);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000139 }
Fred Drake268397f1998-04-29 14:16:32 +0000140 (void) addelem(v, i+1, w);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000141 }
Guido van Rossum47478871996-08-21 14:32:37 +0000142 return (v);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000143 }
144 else if (ISTERMINAL(TYPE(n))) {
Guido van Rossum47478871996-08-21 14:32:37 +0000145 PyObject *result = mkseq(2 + lineno);
146 if (result != NULL) {
Fred Drake268397f1998-04-29 14:16:32 +0000147 (void) addelem(result, 0, PyInt_FromLong(TYPE(n)));
148 (void) addelem(result, 1, PyString_FromString(STR(n)));
Guido van Rossum47478871996-08-21 14:32:37 +0000149 if (lineno == 1)
Fred Drake268397f1998-04-29 14:16:32 +0000150 (void) addelem(result, 2, PyInt_FromLong(n->n_lineno));
Guido van Rossum47478871996-08-21 14:32:37 +0000151 }
152 return (result);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000153 }
154 else {
155 PyErr_SetString(PyExc_SystemError,
156 "unrecognized parse tree node type");
Fred Drake268397f1998-04-29 14:16:32 +0000157 return ((PyObject*) NULL);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000158 }
Guido van Rossum47478871996-08-21 14:32:37 +0000159} /* node2tuple() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000160/*
161 * End of material copyrighted by Stichting Mathematisch Centrum.
162 */
Guido van Rossum52f2c051993-11-10 12:53:24 +0000163
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000164
165
166/* There are two types of intermediate objects we're interested in:
167 * 'eval' and 'exec' types. These constants can be used in the ast_type
168 * field of the object type to identify which any given object represents.
169 * These should probably go in an external header to allow other extensions
170 * to use them, but then, we really should be using C++ too. ;-)
171 *
Guido van Rossum3d602e31996-07-21 02:33:56 +0000172 * The PyAST_FRAGMENT type is not currently supported. Maybe not useful?
173 * Haven't decided yet.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000174 */
175
176#define PyAST_EXPR 1
177#define PyAST_SUITE 2
178#define PyAST_FRAGMENT 3
179
180
181/* These are the internal objects and definitions required to implement the
182 * AST type. Most of the internal names are more reminiscent of the 'old'
183 * naming style, but the code uses the new naming convention.
184 */
185
186static PyObject*
187parser_error = 0;
188
189
190typedef struct _PyAST_Object {
191
192 PyObject_HEAD /* standard object header */
193 node* ast_node; /* the node* returned by the parser */
194 int ast_type; /* EXPR or SUITE ? */
195
196} PyAST_Object;
197
198
Fred Drake268397f1998-04-29 14:16:32 +0000199staticforward void
200parser_free Py_PROTO((PyAST_Object *ast));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000201
Fred Drake268397f1998-04-29 14:16:32 +0000202staticforward int
203parser_compare Py_PROTO((PyAST_Object *left, PyAST_Object *right));
204
205staticforward PyObject *
206parser_getattr Py_PROTO((PyObject *self, char *name));
Fred Drake503d8d61998-04-13 18:45:18 +0000207
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000208
Fred Drake268397f1998-04-29 14:16:32 +0000209static
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000210PyTypeObject PyAST_Type = {
211
Guido van Rossum3c8c5981998-05-29 02:58:20 +0000212 PyObject_HEAD_INIT(NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000213 0,
214 "ast", /* tp_name */
Fred Drake268397f1998-04-29 14:16:32 +0000215 (int) sizeof(PyAST_Object), /* tp_basicsize */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000216 0, /* tp_itemsize */
217 (destructor)parser_free, /* tp_dealloc */
218 0, /* tp_print */
Fred Drake503d8d61998-04-13 18:45:18 +0000219 parser_getattr, /* tp_getattr */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000220 0, /* tp_setattr */
221 (cmpfunc)parser_compare, /* tp_compare */
222 0, /* tp_repr */
223 0, /* tp_as_number */
224 0, /* tp_as_sequence */
225 0, /* tp_as_mapping */
226 0, /* tp_hash */
227 0, /* tp_call */
Fred Drake69b9ae41997-05-23 04:04:17 +0000228 0, /* tp_str */
229 0, /* tp_getattro */
230 0, /* tp_setattro */
231
232 /* Functions to access object as input/output buffer */
233 0, /* tp_as_buffer */
234
235 /* Space for future expansion */
236 0, /* tp_xxx4 */
237
238 /* __doc__ */
239 "Intermediate representation of a Python parse tree."
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000240
241}; /* PyAST_Type */
242
243
244static int
245parser_compare_nodes(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000246 node *left;
247 node *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000248{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000249 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000250
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000251 if (TYPE(left) < TYPE(right))
252 return (-1);
253
254 if (TYPE(right) < TYPE(left))
255 return (1);
256
257 if (ISTERMINAL(TYPE(left)))
258 return (strcmp(STR(left), STR(right)));
259
260 if (NCH(left) < NCH(right))
261 return (-1);
262
263 if (NCH(right) < NCH(left))
264 return (1);
265
266 for (j = 0; j < NCH(left); ++j) {
267 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
268
Fred Drakeed3da231998-05-11 03:31:16 +0000269 if (v != 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000270 return (v);
271 }
272 return (0);
273
274} /* parser_compare_nodes() */
275
276
277/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
278 *
279 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
280 * This really just wraps a call to parser_compare_nodes() with some easy
281 * checks and protection code.
282 *
283 */
284static int
285parser_compare(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000286 PyAST_Object *left;
287 PyAST_Object *right;
Guido van Rossum47478871996-08-21 14:32:37 +0000288{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000289 if (left == right)
290 return (0);
291
292 if ((left == 0) || (right == 0))
293 return (-1);
294
295 return (parser_compare_nodes(left->ast_node, right->ast_node));
296
297} /* parser_compare() */
298
299
300/* parser_newastobject(node* ast)
301 *
302 * Allocates a new Python object representing an AST. This is simply the
303 * 'wrapper' object that holds a node* and allows it to be passed around in
304 * Python code.
305 *
306 */
307static PyObject*
308parser_newastobject(ast, type)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000309 node *ast;
310 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000311{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000312 PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
313
314 if (o != 0) {
315 o->ast_node = ast;
316 o->ast_type = type;
317 }
Fred Drake268397f1998-04-29 14:16:32 +0000318 else {
319 PyNode_Free(ast);
320 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000321 return ((PyObject*)o);
322
323} /* parser_newastobject() */
324
325
326/* void parser_free(PyAST_Object* ast)
327 *
328 * This is called by a del statement that reduces the reference count to 0.
329 *
330 */
331static void
332parser_free(ast)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000333 PyAST_Object *ast;
Guido van Rossum47478871996-08-21 14:32:37 +0000334{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000335 PyNode_Free(ast->ast_node);
336 PyMem_DEL(ast);
337
338} /* parser_free() */
339
340
341/* parser_ast2tuple(PyObject* self, PyObject* args)
342 *
343 * This provides conversion from a node* to a tuple object that can be
344 * returned to the Python-level caller. The AST object is not modified.
345 *
346 */
347static PyObject*
348parser_ast2tuple(self, args)
Fred Drake503d8d61998-04-13 18:45:18 +0000349 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000350 PyObject *args;
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 Drake268397f1998-04-29 14:16:32 +0000356 if (self == NULL) {
Fred Drake503d8d61998-04-13 18:45:18 +0000357 ok = PyArg_ParseTuple(
358 args, "O!|O:ast2tuple", &PyAST_Type, &self, &line_option);
Fred Drake268397f1998-04-29 14:16:32 +0000359 }
Fred Drake503d8d61998-04-13 18:45:18 +0000360 else
361 ok = PyArg_ParseTuple(args, "|O:totuple", &line_option);
Fred Drake268397f1998-04-29 14:16:32 +0000362 if (ok != 0) {
Guido van Rossum47478871996-08-21 14:32:37 +0000363 int lineno = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000364 if (line_option != NULL) {
Fred Drake268397f1998-04-29 14:16:32 +0000365 lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000366 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000367 /*
368 * Convert AST into a tuple representation. Use Guido's function,
369 * since it's known to work already.
370 */
Fred Drake503d8d61998-04-13 18:45:18 +0000371 res = node2tuple(((PyAST_Object*)self)->ast_node,
Guido van Rossum47478871996-08-21 14:32:37 +0000372 PyTuple_New, PyTuple_SetItem, lineno);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000373 }
374 return (res);
375
376} /* parser_ast2tuple() */
377
378
Guido van Rossum47478871996-08-21 14:32:37 +0000379/* parser_ast2tuple(PyObject* self, PyObject* args)
380 *
381 * This provides conversion from a node* to a tuple object that can be
382 * returned to the Python-level caller. The AST object is not modified.
383 *
384 */
385static PyObject*
386parser_ast2list(self, args)
Fred Drake503d8d61998-04-13 18:45:18 +0000387 PyAST_Object *self;
Guido van Rossum47478871996-08-21 14:32:37 +0000388 PyObject *args;
389{
Guido van Rossum47478871996-08-21 14:32:37 +0000390 PyObject *line_option = 0;
391 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000392 int ok;
Guido van Rossum47478871996-08-21 14:32:37 +0000393
Fred Drake503d8d61998-04-13 18:45:18 +0000394 if (self == NULL)
395 ok = PyArg_ParseTuple(
396 args, "O!|O:ast2list", &PyAST_Type, &self, &line_option);
397 else
398 ok = PyArg_ParseTuple(args, "|O:tolist", &line_option);
399 if (ok) {
Guido van Rossum47478871996-08-21 14:32:37 +0000400 int lineno = 0;
401 if (line_option != 0) {
Fred Drake503d8d61998-04-13 18:45:18 +0000402 lineno = PyObject_IsTrue(line_option) ? 1 : 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000403 }
404 /*
405 * Convert AST into a tuple representation. Use Guido's function,
406 * since it's known to work already.
407 */
Fred Drake268397f1998-04-29 14:16:32 +0000408 res = node2tuple(self->ast_node,
Guido van Rossum47478871996-08-21 14:32:37 +0000409 PyList_New, PyList_SetItem, lineno);
410 }
411 return (res);
412
413} /* parser_ast2list() */
414
415
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000416/* parser_compileast(PyObject* self, PyObject* args)
417 *
418 * This function creates code objects from the parse tree represented by
419 * the passed-in data object. An optional file name is passed in as well.
420 *
421 */
422static PyObject*
423parser_compileast(self, args)
Fred Drake503d8d61998-04-13 18:45:18 +0000424 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000425 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000426{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000427 PyObject* res = 0;
428 char* str = "<ast>";
Fred Drake503d8d61998-04-13 18:45:18 +0000429 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000430
Fred Drake503d8d61998-04-13 18:45:18 +0000431 if (self == NULL)
432 ok = PyArg_ParseTuple(
433 args, "O!|s:compileast", &PyAST_Type, &self, &str);
434 else
435 ok = PyArg_ParseTuple(args, "|s:compile", &str);
436
437 if (ok)
438 res = (PyObject *)PyNode_Compile(self->ast_node, str);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000439
440 return (res);
441
442} /* parser_compileast() */
443
444
445/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
446 * PyObject* parser_issuite(PyObject* self, PyObject* args)
447 *
448 * Checks the passed-in AST object to determine if it is an expression or
449 * a statement suite, respectively. The return is a Python truth value.
450 *
451 */
452static PyObject*
453parser_isexpr(self, args)
Fred Drake503d8d61998-04-13 18:45:18 +0000454 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000455 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000456{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000457 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000458 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000459
Fred Drake503d8d61998-04-13 18:45:18 +0000460 if (self == NULL)
461 ok = PyArg_ParseTuple(args, "O!:isexpr", &PyAST_Type, &self);
462 else
463 ok = PyArg_ParseTuple(args, ":isexpr");
464
465 if (ok) {
466 /* Check to see if the AST represents an expression or not. */
467 res = (self->ast_type == PyAST_EXPR) ? Py_True : Py_False;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000468 Py_INCREF(res);
469 }
470 return (res);
471
472} /* parser_isexpr() */
473
474
475static PyObject*
476parser_issuite(self, args)
Fred Drake503d8d61998-04-13 18:45:18 +0000477 PyAST_Object *self;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000478 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000479{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000480 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000481 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000482
Fred Drake503d8d61998-04-13 18:45:18 +0000483 if (self == NULL)
484 ok = PyArg_ParseTuple(args, "O!:issuite", &PyAST_Type, &self);
485 else
486 ok = PyArg_ParseTuple(args, ":issuite");
487
488 if (ok) {
489 /* Check to see if the AST represents an expression or not. */
490 res = (self->ast_type == PyAST_EXPR) ? Py_False : Py_True;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000491 Py_INCREF(res);
492 }
493 return (res);
494
495} /* parser_issuite() */
496
497
Fred Drake503d8d61998-04-13 18:45:18 +0000498static PyMethodDef
499parser_methods[] = {
Fred Drake301b5be1998-04-21 22:31:45 +0000500 {"compile", (PyCFunction)parser_compileast, METH_VARARGS,
501 "Compile this AST object into a code object."},
502 {"isexpr", (PyCFunction)parser_isexpr, METH_VARARGS,
503 "Determines if this AST object was created from an expression."},
504 {"issuite", (PyCFunction)parser_issuite, METH_VARARGS,
505 "Determines if this AST object was created from a suite."},
506 {"tolist", (PyCFunction)parser_ast2list, METH_VARARGS,
507 "Creates a list-tree representation of this AST."},
508 {"totuple", (PyCFunction)parser_ast2tuple, METH_VARARGS,
509 "Creates a tuple-tree representation of this AST."},
Fred Drake503d8d61998-04-13 18:45:18 +0000510
Fred Drake268397f1998-04-29 14:16:32 +0000511 {NULL, NULL, 0, NULL}
Fred Drake503d8d61998-04-13 18:45:18 +0000512};
513
514static PyObject*
515parser_method_list = NULL;
516
517
518static PyObject*
519parser_getattr(self, name)
520 PyObject *self;
521 char *name;
522{
523 if (strcmp(name, "__methods__") == 0) {
524 Py_INCREF(parser_method_list);
525 return (parser_method_list);
526 }
527 return (Py_FindMethod(parser_methods, self, name));
528
529} /* parser_getattr() */
530
531
Guido van Rossum3d602e31996-07-21 02:33:56 +0000532/* err_string(char* message)
533 *
534 * Sets the error string for an exception of type ParserError.
535 *
536 */
537static void
538err_string(message)
539 char *message;
Guido van Rossum47478871996-08-21 14:32:37 +0000540{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000541 PyErr_SetString(parser_error, message);
542
543} /* err_string() */
544
545
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000546/* PyObject* parser_do_parse(PyObject* args, int type)
547 *
548 * Internal function to actually execute the parse and return the result if
549 * successful, or set an exception if not.
550 *
551 */
552static PyObject*
553parser_do_parse(args, type)
554 PyObject *args;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000555 int type;
Guido van Rossum47478871996-08-21 14:32:37 +0000556{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000557 char* string = 0;
558 PyObject* res = 0;
559
560 if (PyArg_ParseTuple(args, "s", &string)) {
561 node* n = PyParser_SimpleParseString(string,
562 (type == PyAST_EXPR)
563 ? eval_input : file_input);
564
565 if (n != 0)
566 res = parser_newastobject(n, type);
567 else
Guido van Rossum3d602e31996-07-21 02:33:56 +0000568 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000569 }
570 return (res);
571
572} /* parser_do_parse() */
573
574
575/* PyObject* parser_expr(PyObject* self, PyObject* args)
576 * PyObject* parser_suite(PyObject* self, PyObject* args)
577 *
578 * External interfaces to the parser itself. Which is called determines if
579 * the parser attempts to recognize an expression ('eval' form) or statement
580 * suite ('exec' form). The real work is done by parser_do_parse() above.
581 *
582 */
583static PyObject*
584parser_expr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000585 PyObject *self;
586 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000587{
Fred Drake268397f1998-04-29 14:16:32 +0000588 NOTE(ARGUNUSED(self))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000589 return (parser_do_parse(args, PyAST_EXPR));
590
591} /* parser_expr() */
592
593
594static PyObject*
595parser_suite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000596 PyObject *self;
597 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000598{
Fred Drake268397f1998-04-29 14:16:32 +0000599 NOTE(ARGUNUSED(self))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000600 return (parser_do_parse(args, PyAST_SUITE));
601
602} /* parser_suite() */
603
604
605
606/* This is the messy part of the code. Conversion from a tuple to an AST
607 * object requires that the input tuple be valid without having to rely on
608 * catching an exception from the compiler. This is done to allow the
609 * compiler itself to remain fast, since most of its input will come from
610 * the parser directly, and therefore be known to be syntactically correct.
611 * This validation is done to ensure that we don't core dump the compile
612 * phase, returning an exception instead.
613 *
614 * Two aspects can be broken out in this code: creating a node tree from
615 * the tuple passed in, and verifying that it is indeed valid. It may be
616 * advantageous to expand the number of AST types to include funcdefs and
617 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
618 * here. They are not necessary, and not quite as useful in a raw form.
619 * For now, let's get expressions and suites working reliably.
620 */
621
622
Guido van Rossum2a288461996-08-21 21:55:43 +0000623staticforward node* build_node_tree Py_PROTO((PyObject *tuple));
624staticforward int validate_expr_tree Py_PROTO((node *tree));
625staticforward int validate_file_input Py_PROTO((node *tree));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000626
627
628/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
629 *
630 * This is the public function, called from the Python code. It receives a
631 * single tuple object from the caller, and creates an AST object if the
632 * tuple can be validated. It does this by checking the first code of the
633 * tuple, and, if acceptable, builds the internal representation. If this
634 * step succeeds, the internal representation is validated as fully as
635 * possible with the various validate_*() routines defined below.
636 *
637 * This function must be changed if support is to be added for PyAST_FRAGMENT
638 * AST objects.
639 *
640 */
641static PyObject*
642parser_tuple2ast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000643 PyObject *self;
644 PyObject *args;
Guido van Rossum47478871996-08-21 14:32:37 +0000645{
Fred Drake268397f1998-04-29 14:16:32 +0000646 NOTE(ARGUNUSED(self))
Guido van Rossum47478871996-08-21 14:32:37 +0000647 PyObject *ast = 0;
648 PyObject *tuple = 0;
649 PyObject *temp = 0;
650 int ok;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000651 int start_sym = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000652
Guido van Rossum47478871996-08-21 14:32:37 +0000653 if (!PyArg_ParseTuple(args, "O:tuple2ast", &tuple))
654 return (0);
655 if (!PySequence_Check(tuple)) {
656 PyErr_SetString(PyExc_ValueError,
657 "tuple2ast() requires a single sequence argument");
658 return (0);
659 }
660 /*
661 * This mess of tests is written this way so we can use the abstract
662 * object interface (AOI). Unfortunately, the AOI increments reference
663 * counts, which requires that we store a pointer to retrieved object
664 * so we can DECREF it after the check. But we really should accept
665 * lists as well as tuples at the very least.
666 */
667 ok = PyObject_Length(tuple) >= 2;
668 if (ok) {
669 temp = PySequence_GetItem(tuple, 0);
670 ok = (temp != NULL) && PyInt_Check(temp);
671 if (ok)
672 /* this is used after the initial checks: */
Fred Drake1a566ff1999-02-17 17:35:53 +0000673 start_sym = PyInt_AS_LONG(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000674 Py_XDECREF(temp);
675 }
676 if (ok) {
677 temp = PySequence_GetItem(tuple, 1);
678 ok = (temp != NULL) && PySequence_Check(temp);
679 Py_XDECREF(temp);
680 }
681 if (ok) {
682 temp = PySequence_GetItem(tuple, 1);
683 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
684 if (ok) {
685 PyObject *temp2 = PySequence_GetItem(temp, 0);
686 if (temp2 != NULL) {
687 ok = PyInt_Check(temp2);
688 Py_DECREF(temp2);
689 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000690 }
Guido van Rossum47478871996-08-21 14:32:37 +0000691 Py_XDECREF(temp);
692 }
693 /* If we've failed at some point, get out of here. */
694 if (!ok) {
695 err_string("malformed sequence for tuple2ast()");
696 return (0);
697 }
698 /*
699 * This might be a valid parse tree, but let's do a quick check
700 * before we jump the gun.
701 */
702 if (start_sym == eval_input) {
703 /* Might be an eval form. */
704 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000705
Guido van Rossum47478871996-08-21 14:32:37 +0000706 if ((expression != 0) && validate_expr_tree(expression))
707 ast = parser_newastobject(expression, PyAST_EXPR);
708 }
709 else if (start_sym == file_input) {
710 /* This looks like an exec form so far. */
711 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000712
Guido van Rossum47478871996-08-21 14:32:37 +0000713 if ((suite_tree != 0) && validate_file_input(suite_tree))
714 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000715 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000716 else
Guido van Rossum47478871996-08-21 14:32:37 +0000717 /* This is a fragment, and is not yet supported. Maybe they
718 * will be if I find a use for them.
719 */
720 err_string("Fragmentary parse trees not supported.");
721
722 /* Make sure we throw an exception on all errors. We should never
723 * get this, but we'd do well to be sure something is done.
724 */
725 if ((ast == 0) && !PyErr_Occurred())
726 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000727
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000728 return (ast);
729
730} /* parser_tuple2ast() */
731
732
733/* int check_terminal_tuple()
734 *
Guido van Rossum47478871996-08-21 14:32:37 +0000735 * Check a tuple to determine that it is indeed a valid terminal
736 * node. The node is known to be required as a terminal, so we throw
737 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000738 *
Guido van Rossum47478871996-08-21 14:32:37 +0000739 * The format of an acceptable terminal tuple is "(is[i])": the fact
740 * that elem is a tuple and the integer is a valid terminal symbol
741 * has been established before this function is called. We must
742 * check the length of the tuple and the type of the second element
743 * and optional third element. We do *NOT* check the actual text of
744 * the string element, which we could do in many cases. This is done
745 * by the validate_*() functions which operate on the internal
746 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000747 */
748static int
Guido van Rossum47478871996-08-21 14:32:37 +0000749check_terminal_tuple(elem)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000750 PyObject *elem;
Guido van Rossum47478871996-08-21 14:32:37 +0000751{
752 int len = PyObject_Length(elem);
753 int res = 1;
754 char* str = "Illegal terminal symbol; bad node length.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000755
Guido van Rossum47478871996-08-21 14:32:37 +0000756 if ((len == 2) || (len == 3)) {
757 PyObject *temp = PySequence_GetItem(elem, 1);
758 res = PyString_Check(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000759 str = "Illegal terminal symbol; expected a string.";
Guido van Rossum47478871996-08-21 14:32:37 +0000760 if (res && (len == 3)) {
761 PyObject* third = PySequence_GetItem(elem, 2);
762 res = PyInt_Check(third);
763 str = "Invalid third element of terminal node.";
764 Py_XDECREF(third);
765 }
766 Py_XDECREF(temp);
767 }
768 else {
769 res = 0;
770 }
771 if (!res) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000772 elem = Py_BuildValue("(os)", elem, str);
773 PyErr_SetObject(parser_error, elem);
774 }
775 return (res);
776
777} /* check_terminal_tuple() */
778
779
780/* node* build_node_children()
781 *
782 * Iterate across the children of the current non-terminal node and build
783 * their structures. If successful, return the root of this portion of
784 * the tree, otherwise, 0. Any required exception will be specified already,
785 * and no memory will have been deallocated.
786 *
787 */
788static node*
789build_node_children(tuple, root, line_num)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000790 PyObject *tuple;
791 node *root;
792 int *line_num;
Guido van Rossum47478871996-08-21 14:32:37 +0000793{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000794 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000795 int i;
796
797 for (i = 1; i < len; ++i) {
798 /* elem must always be a tuple, however simple */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000799 PyObject* elem = PySequence_GetItem(tuple, i);
Guido van Rossum47478871996-08-21 14:32:37 +0000800 int ok = elem != NULL;
801 long type = 0;
802 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000803
Guido van Rossum47478871996-08-21 14:32:37 +0000804 if (ok)
805 ok = PySequence_Check(elem);
806 if (ok) {
807 PyObject *temp = PySequence_GetItem(elem, 0);
808 if (temp == NULL)
809 ok = 0;
810 else {
811 ok = PyInt_Check(temp);
812 if (ok)
Fred Drake1a566ff1999-02-17 17:35:53 +0000813 type = PyInt_AS_LONG(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000814 Py_DECREF(temp);
815 }
816 }
817 if (!ok) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000818 PyErr_SetObject(parser_error,
819 Py_BuildValue("(os)", elem,
820 "Illegal node construct."));
Guido van Rossum47478871996-08-21 14:32:37 +0000821 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000822 return (0);
823 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000824 if (ISTERMINAL(type)) {
Guido van Rossum47478871996-08-21 14:32:37 +0000825 if (check_terminal_tuple(elem)) {
826 PyObject *temp = PySequence_GetItem(elem, 1);
827
Fred Draked49266e1997-10-09 16:29:31 +0000828 /* check_terminal_tuple() already verified it's a string */
829 strn = (char *)malloc(PyString_GET_SIZE(temp) + 1);
830 if (strn != NULL)
Fred Drake268397f1998-04-29 14:16:32 +0000831 (void) strcpy(strn, PyString_AS_STRING(temp));
Guido van Rossum47478871996-08-21 14:32:37 +0000832 Py_XDECREF(temp);
833
834 if (PyObject_Length(elem) == 3) {
835 PyObject* temp = PySequence_GetItem(elem, 2);
836 *line_num = PyInt_AsLong(temp);
837 Py_DECREF(temp);
838 }
839 }
840 else {
841 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000842 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000843 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000844 }
845 else if (!ISNONTERMINAL(type)) {
846 /*
847 * It has to be one or the other; this is an error.
848 * Throw an exception.
849 */
850 PyErr_SetObject(parser_error,
851 Py_BuildValue("(os)", elem,
852 "Unknown node type."));
Guido van Rossum47478871996-08-21 14:32:37 +0000853 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000854 return (0);
855 }
856 PyNode_AddChild(root, type, strn, *line_num);
857
858 if (ISNONTERMINAL(type)) {
859 node* new_child = CHILD(root, i - 1);
860
Guido van Rossum47478871996-08-21 14:32:37 +0000861 if (new_child != build_node_children(elem, new_child, line_num)) {
862 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000863 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000864 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000865 }
Guido van Rossum47478871996-08-21 14:32:37 +0000866 else if (type == NEWLINE) { /* It's true: we increment the */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000867 ++(*line_num); /* line number *after* the newline! */
Guido van Rossum47478871996-08-21 14:32:37 +0000868 }
869 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000870 }
871 return (root);
872
873} /* build_node_children() */
874
875
876static node*
877build_node_tree(tuple)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000878 PyObject *tuple;
Guido van Rossum47478871996-08-21 14:32:37 +0000879{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000880 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000881 PyObject *temp = PySequence_GetItem(tuple, 0);
882 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000883
Guido van Rossum47478871996-08-21 14:32:37 +0000884 if (temp != NULL)
885 num = PyInt_AsLong(temp);
886 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000887 if (ISTERMINAL(num)) {
888 /*
889 * The tuple is simple, but it doesn't start with a start symbol.
890 * Throw an exception now and be done with it.
891 */
892 tuple = Py_BuildValue("(os)", tuple,
Guido van Rossum3d602e31996-07-21 02:33:56 +0000893 "Illegal ast tuple; cannot start with terminal symbol.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000894 PyErr_SetObject(parser_error, tuple);
895 }
896 else if (ISNONTERMINAL(num)) {
897 /*
898 * Not efficient, but that can be handled later.
899 */
900 int line_num = 0;
901
902 res = PyNode_New(num);
903 if (res != build_node_children(tuple, res, &line_num)) {
904 PyNode_Free(res);
905 res = 0;
906 }
907 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000908 else
909 /* The tuple is illegal -- if the number is neither TERMINAL nor
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000910 * NONTERMINAL, we can't use it.
911 */
912 PyErr_SetObject(parser_error,
913 Py_BuildValue("(os)", tuple,
914 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000915
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000916 return (res);
917
918} /* build_node_tree() */
919
920
Guido van Rossum360a9341996-08-21 19:04:10 +0000921#ifdef HAVE_OLD_CPP
Guido van Rossum2a288461996-08-21 21:55:43 +0000922#define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000923#else
Guido van Rossum2a288461996-08-21 21:55:43 +0000924#define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
Guido van Rossum360a9341996-08-21 19:04:10 +0000925#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000926
927
928/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000929 * Validation routines used within the validation section:
930 */
Guido van Rossum2a288461996-08-21 21:55:43 +0000931staticforward int validate_terminal Py_PROTO((node *terminal,
932 int type, char *string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000933
934#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
935#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
936#define validate_colon(ch) validate_terminal(ch, COLON, ":")
937#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
938#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
939#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Fred Drake268397f1998-04-29 14:16:32 +0000940#define validate_indent(ch) validate_terminal(ch, INDENT, (char*)NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000941#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Fred Drake268397f1998-04-29 14:16:32 +0000942#define validate_newline(ch) validate_terminal(ch, NEWLINE, (char*)NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000943#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
944#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
945#define validate_star(ch) validate_terminal(ch, STAR, "*")
946#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000947#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
Guido van Rossum47478871996-08-21 14:32:37 +0000948#define validate_dot(ch) validate_terminal(ch, DOT, ".")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000949#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000950
Guido van Rossum3d602e31996-07-21 02:33:56 +0000951VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000952VALIDATER(class); VALIDATER(node);
953VALIDATER(parameters); VALIDATER(suite);
954VALIDATER(testlist); VALIDATER(varargslist);
955VALIDATER(fpdef); VALIDATER(fplist);
956VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000957VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000958VALIDATER(print_stmt); VALIDATER(del_stmt);
959VALIDATER(return_stmt);
960VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000961VALIDATER(global_stmt);
Guido van Rossum925e5471997-04-02 05:32:13 +0000962VALIDATER(assert_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000963VALIDATER(exec_stmt); VALIDATER(compound_stmt);
964VALIDATER(while); VALIDATER(for);
965VALIDATER(try); VALIDATER(except_clause);
966VALIDATER(test); VALIDATER(and_test);
967VALIDATER(not_test); VALIDATER(comparison);
968VALIDATER(comp_op); VALIDATER(expr);
969VALIDATER(xor_expr); VALIDATER(and_expr);
970VALIDATER(shift_expr); VALIDATER(arith_expr);
971VALIDATER(term); VALIDATER(factor);
972VALIDATER(atom); VALIDATER(lambdef);
973VALIDATER(trailer); VALIDATER(subscript);
Guido van Rossum47478871996-08-21 14:32:37 +0000974VALIDATER(subscriptlist); VALIDATER(sliceop);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000975VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000976VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000977
978
979#define is_even(n) (((n) & 1) == 0)
980#define is_odd(n) (((n) & 1) == 1)
981
982
983static int
984validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000985 node *n;
986 int t;
Guido van Rossum47478871996-08-21 14:32:37 +0000987{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000988 int res = (TYPE(n) == t);
989
990 if (!res) {
991 char buffer[128];
Fred Drake268397f1998-04-29 14:16:32 +0000992 (void) sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000993 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000994 }
995 return (res);
996
997} /* validate_ntype() */
998
999
1000static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001001validate_numnodes(n, num, name)
1002 node *n;
1003 int num;
1004 const char *const name;
Guido van Rossum47478871996-08-21 14:32:37 +00001005{
Guido van Rossum3d602e31996-07-21 02:33:56 +00001006 if (NCH(n) != num) {
1007 char buff[60];
Fred Drake268397f1998-04-29 14:16:32 +00001008 (void) sprintf(buff, "Illegal number of children for %s node.", name);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001009 err_string(buff);
1010 }
1011 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001012
Guido van Rossum3d602e31996-07-21 02:33:56 +00001013} /* validate_numnodes() */
1014
1015
1016static int
1017validate_terminal(terminal, type, string)
1018 node *terminal;
1019 int type;
1020 char *string;
Guido van Rossum47478871996-08-21 14:32:37 +00001021{
Guido van Rossum3d602e31996-07-21 02:33:56 +00001022 int res = (validate_ntype(terminal, type)
1023 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
1024
1025 if (!res && !PyErr_Occurred()) {
1026 char buffer[60];
Fred Drake268397f1998-04-29 14:16:32 +00001027 (void) sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001028 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001029 }
1030 return (res);
1031
1032} /* validate_terminal() */
1033
1034
Guido van Rossum47478871996-08-21 14:32:37 +00001035/* X (',' X) [',']
1036 */
1037static int
1038validate_repeating_list(tree, ntype, vfunc, name)
1039 node *tree;
1040 int ntype;
1041 int (*vfunc)();
1042 const char *const name;
1043{
1044 int nch = NCH(tree);
1045 int res = (nch && validate_ntype(tree, ntype)
1046 && vfunc(CHILD(tree, 0)));
1047
1048 if (!res && !PyErr_Occurred())
Fred Drake268397f1998-04-29 14:16:32 +00001049 (void) validate_numnodes(tree, 1, name);
Guido van Rossum47478871996-08-21 14:32:37 +00001050 else {
1051 if (is_even(nch))
1052 res = validate_comma(CHILD(tree, --nch));
1053 if (res && nch > 1) {
1054 int pos = 1;
1055 for ( ; res && pos < nch; pos += 2)
1056 res = (validate_comma(CHILD(tree, pos))
1057 && vfunc(CHILD(tree, pos + 1)));
1058 }
1059 }
1060 return (res);
1061
1062} /* validate_repeating_list() */
1063
1064
Guido van Rossum3d602e31996-07-21 02:33:56 +00001065/* VALIDATE(class)
1066 *
1067 * classdef:
1068 * 'class' NAME ['(' testlist ')'] ':' suite
1069 */
Guido van Rossum47478871996-08-21 14:32:37 +00001070static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001071validate_class(tree)
1072 node *tree;
1073{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001074 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001075 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001076
Guido van Rossum3d602e31996-07-21 02:33:56 +00001077 if (res) {
1078 res = (validate_name(CHILD(tree, 0), "class")
1079 && validate_ntype(CHILD(tree, 1), NAME)
1080 && validate_colon(CHILD(tree, nch - 2))
1081 && validate_suite(CHILD(tree, nch - 1)));
1082 }
1083 else
Fred Drake268397f1998-04-29 14:16:32 +00001084 (void) validate_numnodes(tree, 4, "class");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001085 if (res && (nch == 7)) {
1086 res = (validate_lparen(CHILD(tree, 2))
1087 && validate_testlist(CHILD(tree, 3))
1088 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001089 }
1090 return (res);
1091
1092} /* validate_class() */
1093
1094
Guido van Rossum3d602e31996-07-21 02:33:56 +00001095/* if_stmt:
1096 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1097 */
Guido van Rossum47478871996-08-21 14:32:37 +00001098static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001099validate_if(tree)
1100 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001101{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001102 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001103 int res = (validate_ntype(tree, if_stmt)
1104 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001105 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +00001106 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001107 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001108 && validate_suite(CHILD(tree, 3)));
1109
1110 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001111 /* ... 'else' ':' suite */
1112 res = (validate_name(CHILD(tree, nch - 3), "else")
1113 && validate_colon(CHILD(tree, nch - 2))
1114 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001115 nch -= 3;
1116 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001117 else if (!res && !PyErr_Occurred())
Fred Drake268397f1998-04-29 14:16:32 +00001118 (void) validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001119 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001120 /* Will catch the case for nch < 4 */
1121 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001122 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001123 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001124 int j = 4;
1125 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001126 res = (validate_name(CHILD(tree, j), "elif")
1127 && validate_colon(CHILD(tree, j + 2))
1128 && validate_test(CHILD(tree, j + 1))
1129 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001130 j += 4;
1131 }
1132 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001133 return (res);
1134
1135} /* validate_if() */
1136
1137
Guido van Rossum3d602e31996-07-21 02:33:56 +00001138/* parameters:
1139 * '(' [varargslist] ')'
1140 *
1141 */
Guido van Rossum47478871996-08-21 14:32:37 +00001142static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001143validate_parameters(tree)
1144 node *tree;
1145{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001146 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001147 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001148
Guido van Rossum3d602e31996-07-21 02:33:56 +00001149 if (res) {
1150 res = (validate_lparen(CHILD(tree, 0))
1151 && validate_rparen(CHILD(tree, nch - 1)));
1152 if (res && (nch == 3))
1153 res = validate_varargslist(CHILD(tree, 1));
1154 }
1155 else
Fred Drake268397f1998-04-29 14:16:32 +00001156 (void) validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001157
1158 return (res);
1159
1160} /* validate_parameters() */
1161
1162
Guido van Rossum3d602e31996-07-21 02:33:56 +00001163/* VALIDATE(suite)
1164 *
1165 * suite:
1166 * simple_stmt
1167 * | NEWLINE INDENT stmt+ DEDENT
1168 */
Guido van Rossum47478871996-08-21 14:32:37 +00001169static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001170validate_suite(tree)
1171 node *tree;
1172{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001173 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001174 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001175
Guido van Rossum3d602e31996-07-21 02:33:56 +00001176 if (res && (nch == 1))
1177 res = validate_simple_stmt(CHILD(tree, 0));
1178 else if (res) {
1179 /* NEWLINE INDENT stmt+ DEDENT */
1180 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001181 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +00001182 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001183 && validate_dedent(CHILD(tree, nch - 1)));
1184
Guido van Rossum3d602e31996-07-21 02:33:56 +00001185 if (res && (nch > 4)) {
1186 int i = 3;
1187 --nch; /* forget the DEDENT */
1188 for ( ; res && (i < nch); ++i)
1189 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001190 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001191 else if (nch < 4)
Fred Drake268397f1998-04-29 14:16:32 +00001192 res = validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001193 }
1194 return (res);
1195
1196} /* validate_suite() */
1197
1198
Guido van Rossum47478871996-08-21 14:32:37 +00001199static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001200validate_testlist(tree)
1201 node *tree;
1202{
Guido van Rossum47478871996-08-21 14:32:37 +00001203 return (validate_repeating_list(tree, testlist,
1204 validate_test, "testlist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001205
1206} /* validate_testlist() */
1207
1208
Guido van Rossum3d602e31996-07-21 02:33:56 +00001209/* VALIDATE(varargslist)
1210 *
1211 * varargslist:
1212 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1213 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1214 *
1215 * (fpdef ['=' test] ',')*
1216 * ('*' NAME [',' ('**'|'*' '*') NAME]
1217 * | ('**'|'*' '*') NAME)
1218 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1219 *
1220 */
Guido van Rossum47478871996-08-21 14:32:37 +00001221static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001222validate_varargslist(tree)
1223 node *tree;
1224{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001225 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001226 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001227
Guido van Rossum3d602e31996-07-21 02:33:56 +00001228 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1229 /* (fpdef ['=' test] ',')*
1230 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1231 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001232 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001233 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001234
Guido van Rossum3d602e31996-07-21 02:33:56 +00001235 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1236 res = validate_fpdef(CHILD(tree, pos));
1237 if (res) {
1238 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1239 res = validate_test(CHILD(tree, pos + 2));
1240 pos += 2;
1241 }
1242 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001243 pos += 2;
1244 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001245 }
1246 if (res) {
1247 remaining = nch - pos;
1248 res = ((remaining == 2) || (remaining == 3)
1249 || (remaining == 5) || (remaining == 6));
1250 if (!res)
Fred Drake268397f1998-04-29 14:16:32 +00001251 (void) validate_numnodes(tree, 2, "varargslist");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001252 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1253 return ((remaining == 2)
1254 && validate_ntype(CHILD(tree, pos+1), NAME));
1255 else {
1256 res = validate_star(CHILD(tree, pos++));
1257 --remaining;
1258 }
1259 }
1260 if (res) {
1261 if (remaining == 2) {
1262 res = (validate_star(CHILD(tree, pos))
1263 && validate_ntype(CHILD(tree, pos + 1), NAME));
1264 }
1265 else {
1266 res = validate_ntype(CHILD(tree, pos++), NAME);
1267 if (res && (remaining >= 4)) {
1268 res = validate_comma(CHILD(tree, pos));
1269 if (--remaining == 3)
Fred Drakee1607a81996-09-11 21:58:26 +00001270 res = (validate_star(CHILD(tree, pos + 1))
1271 && validate_star(CHILD(tree, pos + 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001272 else
Fred Drake268397f1998-04-29 14:16:32 +00001273 res = validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001274 }
1275 }
1276 }
1277 if (!res && !PyErr_Occurred())
1278 err_string("Incorrect validation of variable arguments list.");
1279 }
1280 else if (res) {
1281 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1282 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1283 --nch;
1284
1285 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1286 res = (is_odd(nch)
1287 && validate_fpdef(CHILD(tree, 0)));
1288
1289 if (res && (nch > 1)) {
1290 int pos = 1;
1291 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1292 res = validate_test(CHILD(tree, 2));
1293 pos += 2;
1294 }
1295 /* ... (',' fpdef ['=' test])* */
1296 for ( ; res && (pos < nch); pos += 2) {
1297 /* ',' fpdef */
1298 res = (validate_comma(CHILD(tree, pos))
1299 && validate_fpdef(CHILD(tree, pos + 1)));
1300 if (res
1301 && ((nch - pos) > 2)
1302 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1303 /* ['=' test] */
1304 res = validate_test(CHILD(tree, pos + 3));
1305 pos += 2;
1306 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001307 }
1308 }
1309 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001310 else
1311 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001312
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001313 return (res);
1314
1315} /* validate_varargslist() */
1316
1317
Guido van Rossum3d602e31996-07-21 02:33:56 +00001318/* VALIDATE(fpdef)
1319 *
1320 * fpdef:
1321 * NAME
1322 * | '(' fplist ')'
1323 */
Guido van Rossum47478871996-08-21 14:32:37 +00001324static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001325validate_fpdef(tree)
1326 node *tree;
1327{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001328 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001329 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001330
Guido van Rossum3d602e31996-07-21 02:33:56 +00001331 if (res) {
1332 if (nch == 1)
1333 res = validate_ntype(CHILD(tree, 0), NAME);
1334 else if (nch == 3)
1335 res = (validate_lparen(CHILD(tree, 0))
1336 && validate_fplist(CHILD(tree, 1))
1337 && validate_rparen(CHILD(tree, 2)));
1338 else
Fred Drake268397f1998-04-29 14:16:32 +00001339 res = validate_numnodes(tree, 1, "fpdef");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001340 }
1341 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001342
1343} /* validate_fpdef() */
1344
1345
Guido van Rossum47478871996-08-21 14:32:37 +00001346static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001347validate_fplist(tree)
1348 node *tree;
1349{
Guido van Rossum47478871996-08-21 14:32:37 +00001350 return (validate_repeating_list(tree, fplist,
1351 validate_fpdef, "fplist"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001352
1353} /* validate_fplist() */
1354
1355
Guido van Rossum3d602e31996-07-21 02:33:56 +00001356/* simple_stmt | compound_stmt
1357 *
1358 */
Guido van Rossum47478871996-08-21 14:32:37 +00001359static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001360validate_stmt(tree)
1361 node *tree;
1362{
1363 int res = (validate_ntype(tree, stmt)
1364 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001365
Guido van Rossum3d602e31996-07-21 02:33:56 +00001366 if (res) {
1367 tree = CHILD(tree, 0);
1368
1369 if (TYPE(tree) == simple_stmt)
1370 res = validate_simple_stmt(tree);
1371 else
1372 res = validate_compound_stmt(tree);
1373 }
1374 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001375
1376} /* validate_stmt() */
1377
1378
Guido van Rossum3d602e31996-07-21 02:33:56 +00001379/* small_stmt (';' small_stmt)* [';'] NEWLINE
1380 *
1381 */
Guido van Rossum47478871996-08-21 14:32:37 +00001382static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001383validate_simple_stmt(tree)
1384 node *tree;
1385{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001386 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001387 int res = (validate_ntype(tree, simple_stmt)
1388 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001389 && validate_small_stmt(CHILD(tree, 0))
1390 && validate_newline(CHILD(tree, nch - 1)));
1391
Guido van Rossum3d602e31996-07-21 02:33:56 +00001392 if (nch < 2)
1393 res = validate_numnodes(tree, 2, "simple_stmt");
1394 --nch; /* forget the NEWLINE */
1395 if (res && is_even(nch))
1396 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001397 if (res && (nch > 2)) {
1398 int i;
1399
Guido van Rossum3d602e31996-07-21 02:33:56 +00001400 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001401 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001402 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001403 }
1404 return (res);
1405
1406} /* validate_simple_stmt() */
1407
1408
Guido van Rossum47478871996-08-21 14:32:37 +00001409static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001410validate_small_stmt(tree)
1411 node *tree;
1412{
1413 int nch = NCH(tree);
1414 int res = (validate_numnodes(tree, 1, "small_stmt")
1415 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1416 || (TYPE(CHILD(tree, 0)) == print_stmt)
1417 || (TYPE(CHILD(tree, 0)) == del_stmt)
1418 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1419 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1420 || (TYPE(CHILD(tree, 0)) == import_stmt)
1421 || (TYPE(CHILD(tree, 0)) == global_stmt)
Guido van Rossum925e5471997-04-02 05:32:13 +00001422 || (TYPE(CHILD(tree, 0)) == assert_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001423 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1424
1425 if (res)
1426 res = validate_node(CHILD(tree, 0));
1427 else if (nch == 1) {
1428 char buffer[60];
Fred Drake268397f1998-04-29 14:16:32 +00001429 (void) sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1430 TYPE(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001431 err_string(buffer);
1432 }
1433 return (res);
1434
1435} /* validate_small_stmt */
1436
1437
1438/* compound_stmt:
1439 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1440 */
Guido van Rossum47478871996-08-21 14:32:37 +00001441static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001442validate_compound_stmt(tree)
1443 node *tree;
1444{
1445 int res = (validate_ntype(tree, compound_stmt)
1446 && validate_numnodes(tree, 1, "compound_stmt"));
1447
1448 if (!res)
1449 return (0);
1450
1451 tree = CHILD(tree, 0);
1452 res = ((TYPE(tree) == if_stmt)
1453 || (TYPE(tree) == while_stmt)
1454 || (TYPE(tree) == for_stmt)
1455 || (TYPE(tree) == try_stmt)
1456 || (TYPE(tree) == funcdef)
1457 || (TYPE(tree) == classdef));
1458 if (res)
1459 res = validate_node(tree);
1460 else {
1461 char buffer[60];
Fred Drake268397f1998-04-29 14:16:32 +00001462 (void) sprintf(buffer, "Illegal compound statement type: %d.",
1463 TYPE(tree));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001464 err_string(buffer);
1465 }
1466 return (res);
1467
1468} /* validate_compound_stmt() */
1469
1470
Guido van Rossum47478871996-08-21 14:32:37 +00001471static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001472validate_expr_stmt(tree)
1473 node *tree;
1474{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001475 int j;
1476 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001477 int res = (validate_ntype(tree, expr_stmt)
1478 && is_odd(nch)
1479 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001480
Guido van Rossum3d602e31996-07-21 02:33:56 +00001481 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001482 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001483 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001484
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001485 return (res);
1486
1487} /* validate_expr_stmt() */
1488
1489
Guido van Rossum3d602e31996-07-21 02:33:56 +00001490/* print_stmt:
1491 *
1492 * 'print' (test ',')* [test]
1493 *
1494 */
Guido van Rossum47478871996-08-21 14:32:37 +00001495static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001496validate_print_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, print_stmt)
1502 && (nch != 0)
1503 && validate_name(CHILD(tree, 0), "print"));
1504
1505 if (res && is_even(nch)) {
1506 res = validate_test(CHILD(tree, nch - 1));
1507 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001508 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001509 else if (!res && !PyErr_Occurred())
Fred Drake268397f1998-04-29 14:16:32 +00001510 (void) validate_numnodes(tree, 1, "print_stmt");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001511 for (j = 1; res && (j < nch); j += 2)
1512 res = (validate_test(CHILD(tree, j))
1513 && validate_ntype(CHILD(tree, j + 1), COMMA));
1514
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001515 return (res);
1516
1517} /* validate_print_stmt() */
1518
1519
Guido van Rossum47478871996-08-21 14:32:37 +00001520static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001521validate_del_stmt(tree)
1522 node *tree;
1523{
1524 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001525 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001526 && validate_exprlist(CHILD(tree, 1)));
1527
1528} /* validate_del_stmt() */
1529
1530
Guido van Rossum47478871996-08-21 14:32:37 +00001531static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001532validate_return_stmt(tree)
1533 node *tree;
1534{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001535 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001536 int res = (validate_ntype(tree, return_stmt)
1537 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001538 && validate_name(CHILD(tree, 0), "return"));
1539
Guido van Rossum3d602e31996-07-21 02:33:56 +00001540 if (res && (nch == 2))
1541 res = validate_testlist(CHILD(tree, 1));
1542
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001543 return (res);
1544
1545} /* validate_return_stmt() */
1546
1547
Guido van Rossum47478871996-08-21 14:32:37 +00001548static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001549validate_raise_stmt(tree)
1550 node *tree;
1551{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001552 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001553 int res = (validate_ntype(tree, raise_stmt)
Fred Drakec542bc71998-04-10 04:43:28 +00001554 && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001555
Guido van Rossum3d602e31996-07-21 02:33:56 +00001556 if (res) {
Fred Drakec542bc71998-04-10 04:43:28 +00001557 res = validate_name(CHILD(tree, 0), "raise");
1558 if (res && (nch >= 2))
1559 res = validate_test(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001560 if (res && nch > 2) {
1561 res = (validate_comma(CHILD(tree, 2))
1562 && validate_test(CHILD(tree, 3)));
1563 if (res && (nch > 4))
1564 res = (validate_comma(CHILD(tree, 4))
1565 && validate_test(CHILD(tree, 5)));
1566 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001567 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001568 else
Fred Drake268397f1998-04-29 14:16:32 +00001569 (void) validate_numnodes(tree, 2, "raise");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001570 if (res && (nch == 4))
1571 res = (validate_comma(CHILD(tree, 2))
1572 && validate_test(CHILD(tree, 3)));
1573
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001574 return (res);
1575
1576} /* validate_raise_stmt() */
1577
1578
Guido van Rossum3d602e31996-07-21 02:33:56 +00001579/* import_stmt:
1580 *
1581 * 'import' dotted_name (',' dotted_name)*
1582 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1583 */
Guido van Rossum47478871996-08-21 14:32:37 +00001584static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001585validate_import_stmt(tree)
1586 node *tree;
1587{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001588 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001589 int res = (validate_ntype(tree, import_stmt)
1590 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001591 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001592 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001593
1594 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001595 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001596
Guido van Rossum3d602e31996-07-21 02:33:56 +00001597 for (j = 2; res && (j < nch); j += 2)
1598 res = (validate_comma(CHILD(tree, j))
1599 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001600 }
1601 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001602 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001603 && validate_name(CHILD(tree, 2), "import"));
1604 if (nch == 4) {
1605 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001606 || (TYPE(CHILD(tree, 3)) == STAR));
1607 if (!res)
1608 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001609 }
1610 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001611 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001612 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001613 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001614 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001615 res = (validate_comma(CHILD(tree, j))
1616 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001617 }
1618 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001619 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001620 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001621
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001622 return (res);
1623
1624} /* validate_import_stmt() */
1625
1626
Guido van Rossum47478871996-08-21 14:32:37 +00001627static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001628validate_global_stmt(tree)
1629 node *tree;
1630{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001631 int j;
1632 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001633 int res = (validate_ntype(tree, global_stmt)
1634 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001635
Guido van Rossum3d602e31996-07-21 02:33:56 +00001636 if (res)
1637 res = (validate_name(CHILD(tree, 0), "global")
1638 && validate_ntype(CHILD(tree, 1), NAME));
1639 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001640 res = (validate_comma(CHILD(tree, j))
1641 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001642
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001643 return (res);
1644
1645} /* validate_global_stmt() */
1646
1647
Guido van Rossum3d602e31996-07-21 02:33:56 +00001648/* exec_stmt:
1649 *
1650 * 'exec' expr ['in' test [',' test]]
1651 */
Guido van Rossum47478871996-08-21 14:32:37 +00001652static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001653validate_exec_stmt(tree)
1654 node *tree;
1655{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001656 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001657 int res = (validate_ntype(tree, exec_stmt)
1658 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001659 && validate_name(CHILD(tree, 0), "exec")
1660 && validate_expr(CHILD(tree, 1)));
1661
Guido van Rossum3d602e31996-07-21 02:33:56 +00001662 if (!res && !PyErr_Occurred())
1663 err_string("Illegal exec statement.");
1664 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001665 res = (validate_name(CHILD(tree, 2), "in")
1666 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001667 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001668 res = (validate_comma(CHILD(tree, 4))
1669 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001670
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001671 return (res);
1672
1673} /* validate_exec_stmt() */
1674
1675
Guido van Rossum925e5471997-04-02 05:32:13 +00001676/* assert_stmt:
1677 *
1678 * 'assert' test [',' test]
1679 */
1680static int
1681validate_assert_stmt(tree)
1682 node *tree;
1683{
1684 int nch = NCH(tree);
1685 int res = (validate_ntype(tree, assert_stmt)
1686 && ((nch == 2) || (nch == 4))
1687 && (validate_name(CHILD(tree, 0), "__assert__") ||
1688 validate_name(CHILD(tree, 0), "assert"))
1689 && validate_test(CHILD(tree, 1)));
1690
1691 if (!res && !PyErr_Occurred())
1692 err_string("Illegal assert statement.");
1693 if (res && (nch > 2))
1694 res = (validate_comma(CHILD(tree, 2))
1695 && validate_test(CHILD(tree, 3)));
1696
1697 return (res);
1698
1699} /* validate_assert_stmt() */
1700
1701
Guido van Rossum47478871996-08-21 14:32:37 +00001702static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001703validate_while(tree)
1704 node *tree;
1705{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001706 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001707 int res = (validate_ntype(tree, while_stmt)
1708 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001709 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001710 && validate_test(CHILD(tree, 1))
1711 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001712 && validate_suite(CHILD(tree, 3)));
1713
Guido van Rossum3d602e31996-07-21 02:33:56 +00001714 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001715 res = (validate_name(CHILD(tree, 4), "else")
1716 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001717 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001718
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001719 return (res);
1720
1721} /* validate_while() */
1722
1723
Guido van Rossum47478871996-08-21 14:32:37 +00001724static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001725validate_for(tree)
1726 node *tree;
1727{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001728 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001729 int res = (validate_ntype(tree, for_stmt)
1730 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001731 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001732 && validate_exprlist(CHILD(tree, 1))
1733 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001734 && validate_testlist(CHILD(tree, 3))
1735 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001736 && validate_suite(CHILD(tree, 5)));
1737
Guido van Rossum3d602e31996-07-21 02:33:56 +00001738 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001739 res = (validate_name(CHILD(tree, 6), "else")
1740 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001741 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001742
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001743 return (res);
1744
1745} /* validate_for() */
1746
1747
Guido van Rossum3d602e31996-07-21 02:33:56 +00001748/* try_stmt:
1749 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1750 * | 'try' ':' suite 'finally' ':' suite
1751 *
1752 */
Guido van Rossum47478871996-08-21 14:32:37 +00001753static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001754validate_try(tree)
1755 node *tree;
1756{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001757 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001758 int pos = 3;
1759 int res = (validate_ntype(tree, try_stmt)
1760 && (nch >= 6) && ((nch % 3) == 0));
1761
1762 if (res)
1763 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001764 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001765 && validate_suite(CHILD(tree, 2))
1766 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001767 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001768 else {
1769 const char* name = "execpt";
1770 char buffer[60];
1771 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1772 name = STR(CHILD(tree, nch - 3));
Fred Drake268397f1998-04-29 14:16:32 +00001773 (void) sprintf(buffer,
1774 "Illegal number of children for try/%s node.", name);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001775 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001776 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001777 /* Skip past except_clause sections: */
1778 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1779 res = (validate_except_clause(CHILD(tree, pos))
1780 && validate_colon(CHILD(tree, pos + 1))
1781 && validate_suite(CHILD(tree, pos + 2)));
1782 pos += 3;
1783 }
1784 if (res && (pos < nch)) {
1785 res = validate_ntype(CHILD(tree, pos), NAME);
1786 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1787 res = (validate_numnodes(tree, 6, "try/finally")
1788 && validate_colon(CHILD(tree, 4))
1789 && validate_suite(CHILD(tree, 5)));
Guido van Rossum730806d1998-04-10 22:27:42 +00001790 else if (res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001791 if (nch == (pos + 3)) {
1792 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1793 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1794 if (!res)
1795 err_string("Illegal trailing triple in try statement.");
1796 }
Guido van Rossum730806d1998-04-10 22:27:42 +00001797 else if (nch == (pos + 6)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001798 res = (validate_name(CHILD(tree, pos), "except")
1799 && validate_colon(CHILD(tree, pos + 1))
1800 && validate_suite(CHILD(tree, pos + 2))
1801 && validate_name(CHILD(tree, pos + 3), "else"));
Guido van Rossum730806d1998-04-10 22:27:42 +00001802 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001803 else
1804 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossum730806d1998-04-10 22:27:42 +00001805 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001806 }
1807 return (res);
1808
1809} /* validate_try() */
1810
1811
Guido van Rossum47478871996-08-21 14:32:37 +00001812static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001813validate_except_clause(tree)
1814 node *tree;
1815{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001816 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001817 int res = (validate_ntype(tree, except_clause)
1818 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001819 && validate_name(CHILD(tree, 0), "except"));
1820
Guido van Rossum3d602e31996-07-21 02:33:56 +00001821 if (res && (nch > 1))
1822 res = validate_test(CHILD(tree, 1));
1823 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001824 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001825 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001826
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001827 return (res);
1828
1829} /* validate_except_clause() */
1830
1831
Guido van Rossum47478871996-08-21 14:32:37 +00001832static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001833validate_test(tree)
1834 node *tree;
1835{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001836 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001837 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001838
Guido van Rossum3d602e31996-07-21 02:33:56 +00001839 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001840 res = ((nch == 1)
1841 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001842 else if (res) {
1843 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001844 res = validate_and_test(CHILD(tree, 0));
1845 for (pos = 1; res && (pos < nch); pos += 2)
1846 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001847 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001848 }
1849 return (res);
1850
1851} /* validate_test() */
1852
1853
Guido van Rossum47478871996-08-21 14:32:37 +00001854static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001855validate_and_test(tree)
1856 node *tree;
1857{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001858 int pos;
1859 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001860 int res = (validate_ntype(tree, and_test)
1861 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001862 && validate_not_test(CHILD(tree, 0)));
1863
Guido van Rossum3d602e31996-07-21 02:33:56 +00001864 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001865 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001866 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001867
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001868 return (res);
1869
1870} /* validate_and_test() */
1871
1872
Guido van Rossum47478871996-08-21 14:32:37 +00001873static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001874validate_not_test(tree)
1875 node *tree;
1876{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001877 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001878 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001879
Guido van Rossum3d602e31996-07-21 02:33:56 +00001880 if (res) {
1881 if (nch == 2)
1882 res = (validate_name(CHILD(tree, 0), "not")
1883 && validate_not_test(CHILD(tree, 1)));
1884 else if (nch == 1)
1885 res = validate_comparison(CHILD(tree, 0));
1886 }
1887 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001888
1889} /* validate_not_test() */
1890
1891
Guido van Rossum47478871996-08-21 14:32:37 +00001892static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001893validate_comparison(tree)
1894 node *tree;
1895{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001896 int pos;
1897 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001898 int res = (validate_ntype(tree, comparison)
1899 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001900 && validate_expr(CHILD(tree, 0)));
1901
Guido van Rossum3d602e31996-07-21 02:33:56 +00001902 for (pos = 1; res && (pos < nch); pos += 2)
1903 res = (validate_comp_op(CHILD(tree, pos))
1904 && validate_expr(CHILD(tree, pos + 1)));
1905
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001906 return (res);
1907
1908} /* validate_comparison() */
1909
1910
Guido van Rossum47478871996-08-21 14:32:37 +00001911static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001912validate_comp_op(tree)
1913 node *tree;
1914{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001915 int res = 0;
1916 int nch = NCH(tree);
1917
Guido van Rossum3d602e31996-07-21 02:33:56 +00001918 if (!validate_ntype(tree, comp_op))
1919 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001920 if (nch == 1) {
1921 /*
1922 * Only child will be a terminal with a well-defined symbolic name
1923 * or a NAME with a string of either 'is' or 'in'
1924 */
1925 tree = CHILD(tree, 0);
1926 switch (TYPE(tree)) {
1927 case LESS:
1928 case GREATER:
1929 case EQEQUAL:
1930 case EQUAL:
1931 case LESSEQUAL:
1932 case GREATEREQUAL:
1933 case NOTEQUAL:
1934 res = 1;
1935 break;
1936 case NAME:
1937 res = ((strcmp(STR(tree), "in") == 0)
1938 || (strcmp(STR(tree), "is") == 0));
1939 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001940 char buff[128];
Fred Drake268397f1998-04-29 14:16:32 +00001941 (void) sprintf(buff, "Illegal operator: '%s'.", STR(tree));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001942 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001943 }
1944 break;
1945 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001946 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001947 break;
1948 }
1949 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001950 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001951 res = (validate_ntype(CHILD(tree, 0), NAME)
1952 && validate_ntype(CHILD(tree, 1), NAME)
1953 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1954 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1955 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1956 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001957 if (!res && !PyErr_Occurred())
1958 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001959 }
1960 return (res);
1961
1962} /* validate_comp_op() */
1963
1964
Guido van Rossum47478871996-08-21 14:32:37 +00001965static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001966validate_expr(tree)
1967 node *tree;
1968{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001969 int j;
1970 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001971 int res = (validate_ntype(tree, expr)
1972 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001973 && validate_xor_expr(CHILD(tree, 0)));
1974
Guido van Rossum3d602e31996-07-21 02:33:56 +00001975 for (j = 2; res && (j < nch); j += 2)
1976 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001977 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001978
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001979 return (res);
1980
1981} /* validate_expr() */
1982
1983
Guido van Rossum47478871996-08-21 14:32:37 +00001984static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001985validate_xor_expr(tree)
1986 node *tree;
1987{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001988 int j;
1989 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001990 int res = (validate_ntype(tree, xor_expr)
1991 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001992 && validate_and_expr(CHILD(tree, 0)));
1993
Guido van Rossum3d602e31996-07-21 02:33:56 +00001994 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001995 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001996 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001997
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001998 return (res);
1999
2000} /* validate_xor_expr() */
2001
2002
Guido van Rossum47478871996-08-21 14:32:37 +00002003static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002004validate_and_expr(tree)
2005 node *tree;
2006{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002007 int pos;
2008 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002009 int res = (validate_ntype(tree, and_expr)
2010 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002011 && validate_shift_expr(CHILD(tree, 0)));
2012
Guido van Rossum3d602e31996-07-21 02:33:56 +00002013 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002014 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002015 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002016
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002017 return (res);
2018
2019} /* validate_and_expr() */
2020
2021
2022static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002023validate_chain_two_ops(tree, termvalid, op1, op2)
2024 node *tree;
2025 int (*termvalid)();
2026 int op1;
2027 int op2;
2028 {
2029 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002030 int nch = NCH(tree);
2031 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002032 && (*termvalid)(CHILD(tree, 0)));
2033
Guido van Rossum3d602e31996-07-21 02:33:56 +00002034 for ( ; res && (pos < nch); pos += 2) {
2035 if (TYPE(CHILD(tree, pos)) != op1)
2036 res = validate_ntype(CHILD(tree, pos), op2);
2037 if (res)
2038 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002039 }
2040 return (res);
2041
2042} /* validate_chain_two_ops() */
2043
2044
Guido van Rossum47478871996-08-21 14:32:37 +00002045static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002046validate_shift_expr(tree)
2047 node *tree;
2048{
2049 return (validate_ntype(tree, shift_expr)
2050 && validate_chain_two_ops(tree, validate_arith_expr,
2051 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002052
2053} /* validate_shift_expr() */
2054
2055
Guido van Rossum47478871996-08-21 14:32:37 +00002056static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002057validate_arith_expr(tree)
2058 node *tree;
2059{
2060 return (validate_ntype(tree, arith_expr)
2061 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002062
2063} /* validate_arith_expr() */
2064
2065
Guido van Rossum47478871996-08-21 14:32:37 +00002066static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002067validate_term(tree)
2068 node *tree;
2069{
2070 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002071 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002072 int res = (validate_ntype(tree, term)
2073 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002074 && validate_factor(CHILD(tree, 0)));
2075
Guido van Rossum3d602e31996-07-21 02:33:56 +00002076 for ( ; res && (pos < nch); pos += 2)
2077 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002078 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002079 || (TYPE(CHILD(tree, pos)) == PERCENT))
2080 && validate_factor(CHILD(tree, pos + 1)));
2081
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002082 return (res);
2083
2084} /* validate_term() */
2085
2086
Guido van Rossum3d602e31996-07-21 02:33:56 +00002087/* factor:
2088 *
2089 * factor: ('+'|'-'|'~') factor | power
2090 */
Guido van Rossum47478871996-08-21 14:32:37 +00002091static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002092validate_factor(tree)
2093 node *tree;
2094{
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, factor)
2097 && (((nch == 2)
2098 && ((TYPE(CHILD(tree, 0)) == PLUS)
2099 || (TYPE(CHILD(tree, 0)) == MINUS)
2100 || (TYPE(CHILD(tree, 0)) == TILDE))
2101 && validate_factor(CHILD(tree, 1)))
2102 || ((nch == 1)
2103 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002104 return (res);
2105
2106} /* validate_factor() */
2107
2108
Guido van Rossum3d602e31996-07-21 02:33:56 +00002109/* power:
2110 *
2111 * power: atom trailer* ('**' factor)*
2112 */
Guido van Rossum47478871996-08-21 14:32:37 +00002113static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002114validate_power(tree)
2115 node *tree;
2116{
2117 int pos = 1;
2118 int nch = NCH(tree);
2119 int res = (validate_ntype(tree, power) && (nch >= 1)
2120 && validate_atom(CHILD(tree, 0)));
2121
2122 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2123 res = validate_trailer(CHILD(tree, pos++));
2124 if (res && (pos < nch)) {
2125 if (!is_even(nch - pos)) {
2126 err_string("Illegal number of nodes for 'power'.");
2127 return (0);
2128 }
2129 for ( ; res && (pos < (nch - 1)); pos += 2)
2130 res = (validate_doublestar(CHILD(tree, pos))
2131 && validate_factor(CHILD(tree, pos + 1)));
2132 }
2133 return (res);
2134
2135} /* validate_power() */
2136
2137
Guido van Rossum47478871996-08-21 14:32:37 +00002138static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002139validate_atom(tree)
2140 node *tree;
2141{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002142 int pos;
2143 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002144 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002145
2146 if (res) {
2147 switch (TYPE(CHILD(tree, 0))) {
2148 case LPAR:
2149 res = ((nch <= 3)
2150 && (validate_rparen(CHILD(tree, nch - 1))));
2151
Guido van Rossum3d602e31996-07-21 02:33:56 +00002152 if (res && (nch == 3))
2153 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002154 break;
2155 case LSQB:
2156 res = ((nch <= 3)
2157 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2158
Guido van Rossum3d602e31996-07-21 02:33:56 +00002159 if (res && (nch == 3))
2160 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002161 break;
2162 case LBRACE:
2163 res = ((nch <= 3)
2164 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2165
Guido van Rossum3d602e31996-07-21 02:33:56 +00002166 if (res && (nch == 3))
2167 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002168 break;
2169 case BACKQUOTE:
2170 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002171 && validate_testlist(CHILD(tree, 1))
2172 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2173 break;
2174 case NAME:
2175 case NUMBER:
2176 res = (nch == 1);
2177 break;
2178 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002179 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002180 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002181 break;
2182 default:
2183 res = 0;
2184 break;
2185 }
2186 }
2187 return (res);
2188
2189} /* validate_atom() */
2190
2191
Guido van Rossum3d602e31996-07-21 02:33:56 +00002192/* funcdef:
2193 * 'def' NAME parameters ':' suite
2194 *
2195 */
Guido van Rossum47478871996-08-21 14:32:37 +00002196static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002197validate_funcdef(tree)
2198 node *tree;
2199{
2200 return (validate_ntype(tree, funcdef)
2201 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002202 && validate_name(CHILD(tree, 0), "def")
2203 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002204 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002205 && validate_parameters(CHILD(tree, 2))
2206 && validate_suite(CHILD(tree, 4)));
2207
2208} /* validate_funcdef() */
2209
2210
Guido van Rossum47478871996-08-21 14:32:37 +00002211static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002212validate_lambdef(tree)
2213 node *tree;
2214{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002215 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002216 int res = (validate_ntype(tree, lambdef)
2217 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002218 && validate_name(CHILD(tree, 0), "lambda")
2219 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002220 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002221
Guido van Rossum3d602e31996-07-21 02:33:56 +00002222 if (res && (nch == 4))
2223 res = validate_varargslist(CHILD(tree, 1));
2224 else if (!res && !PyErr_Occurred())
Fred Drake268397f1998-04-29 14:16:32 +00002225 (void) validate_numnodes(tree, 3, "lambdef");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002226
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002227 return (res);
2228
2229} /* validate_lambdef() */
2230
2231
Guido van Rossum3d602e31996-07-21 02:33:56 +00002232/* arglist:
2233 *
2234 * argument (',' argument)* [',']
2235 */
Guido van Rossum47478871996-08-21 14:32:37 +00002236static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002237validate_arglist(tree)
2238 node *tree;
2239{
Guido van Rossum47478871996-08-21 14:32:37 +00002240 return (validate_repeating_list(tree, arglist,
2241 validate_argument, "arglist"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002242
2243} /* validate_arglist() */
2244
2245
2246
2247/* argument:
2248 *
2249 * [test '='] test
2250 */
Guido van Rossum47478871996-08-21 14:32:37 +00002251static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002252validate_argument(tree)
2253 node *tree;
2254{
2255 int nch = NCH(tree);
2256 int res = (validate_ntype(tree, argument)
2257 && ((nch == 1) || (nch == 3))
2258 && validate_test(CHILD(tree, 0)));
2259
2260 if (res && (nch == 3))
2261 res = (validate_equal(CHILD(tree, 1))
2262 && validate_test(CHILD(tree, 2)));
2263
2264 return (res);
2265
2266} /* validate_argument() */
2267
2268
2269
2270/* trailer:
2271 *
Guido van Rossum47478871996-08-21 14:32:37 +00002272 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002273 */
Guido van Rossum47478871996-08-21 14:32:37 +00002274static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002275validate_trailer(tree)
2276 node *tree;
2277{
2278 int nch = NCH(tree);
2279 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002280
2281 if (res) {
2282 switch (TYPE(CHILD(tree, 0))) {
2283 case LPAR:
2284 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002285 if (res && (nch == 3))
2286 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002287 break;
2288 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002289 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossum47478871996-08-21 14:32:37 +00002290 && validate_subscriptlist(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002291 && validate_ntype(CHILD(tree, 2), RSQB));
2292 break;
2293 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002294 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002295 && validate_ntype(CHILD(tree, 1), NAME));
2296 break;
2297 default:
2298 res = 0;
2299 break;
2300 }
2301 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002302 else
Fred Drake268397f1998-04-29 14:16:32 +00002303 (void) validate_numnodes(tree, 2, "trailer");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002304
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002305 return (res);
2306
2307} /* validate_trailer() */
2308
2309
Guido van Rossum47478871996-08-21 14:32:37 +00002310/* subscriptlist:
2311 *
2312 * subscript (',' subscript)* [',']
2313 */
2314static int
2315validate_subscriptlist(tree)
2316 node *tree;
2317{
2318 return (validate_repeating_list(tree, subscriptlist,
2319 validate_subscript, "subscriptlist"));
2320
2321} /* validate_subscriptlist() */
2322
2323
Guido van Rossum3d602e31996-07-21 02:33:56 +00002324/* subscript:
2325 *
Guido van Rossum47478871996-08-21 14:32:37 +00002326 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002327 */
Guido van Rossum47478871996-08-21 14:32:37 +00002328static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002329validate_subscript(tree)
2330 node *tree;
2331{
Guido van Rossum47478871996-08-21 14:32:37 +00002332 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002333 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002334 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002335
Guido van Rossum47478871996-08-21 14:32:37 +00002336 if (!res) {
2337 if (!PyErr_Occurred())
2338 err_string("invalid number of arguments for subscript node");
2339 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002340 }
Guido van Rossum47478871996-08-21 14:32:37 +00002341 if (TYPE(CHILD(tree, 0)) == DOT)
2342 /* take care of ('.' '.' '.') possibility */
2343 return (validate_numnodes(tree, 3, "subscript")
2344 && validate_dot(CHILD(tree, 0))
2345 && validate_dot(CHILD(tree, 1))
2346 && validate_dot(CHILD(tree, 2)));
2347 if (nch == 1) {
2348 if (TYPE(CHILD(tree, 0)) == test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002349 res = validate_test(CHILD(tree, 0));
2350 else
Guido van Rossum47478871996-08-21 14:32:37 +00002351 res = validate_colon(CHILD(tree, 0));
2352 return (res);
2353 }
2354 /* Must be [test] ':' [test] [sliceop],
2355 * but at least one of the optional components will
2356 * be present, but we don't know which yet.
2357 */
2358 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2359 res = validate_test(CHILD(tree, 0));
2360 offset = 1;
2361 }
2362 if (res)
2363 res = validate_colon(CHILD(tree, offset));
2364 if (res) {
2365 int rem = nch - ++offset;
2366 if (rem) {
2367 if (TYPE(CHILD(tree, offset)) == test) {
2368 res = validate_test(CHILD(tree, offset));
2369 ++offset;
2370 --rem;
2371 }
2372 if (res && rem)
2373 res = validate_sliceop(CHILD(tree, offset));
2374 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002375 }
2376 return (res);
2377
2378} /* validate_subscript() */
2379
2380
Guido van Rossum47478871996-08-21 14:32:37 +00002381static int
2382validate_sliceop(tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002383 node *tree;
2384{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002385 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002386 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2387 && validate_ntype(tree, sliceop);
2388 if (!res && !PyErr_Occurred()) {
Fred Drake268397f1998-04-29 14:16:32 +00002389 res = validate_numnodes(tree, 1, "sliceop");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002390 }
Guido van Rossum47478871996-08-21 14:32:37 +00002391 if (res)
2392 res = validate_colon(CHILD(tree, 0));
2393 if (res && (nch == 2))
2394 res = validate_test(CHILD(tree, 1));
2395
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002396 return (res);
2397
Guido van Rossum47478871996-08-21 14:32:37 +00002398} /* validate_sliceop() */
2399
2400
2401static int
2402validate_exprlist(tree)
2403 node *tree;
2404{
2405 return (validate_repeating_list(tree, exprlist,
2406 validate_expr, "exprlist"));
2407
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002408} /* validate_exprlist() */
2409
2410
Guido van Rossum47478871996-08-21 14:32:37 +00002411static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002412validate_dictmaker(tree)
2413 node *tree;
2414{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002415 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002416 int res = (validate_ntype(tree, dictmaker)
2417 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002418 && validate_test(CHILD(tree, 0))
2419 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002420 && validate_test(CHILD(tree, 2)));
2421
Guido van Rossum3d602e31996-07-21 02:33:56 +00002422 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002423 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002424 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002425 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002426
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002427 if (res && (nch > 3)) {
2428 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002429 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002430 while (res && (pos < nch)) {
2431 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002432 && validate_test(CHILD(tree, pos + 1))
2433 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002434 && validate_test(CHILD(tree, pos + 3)));
2435 pos += 4;
2436 }
2437 }
2438 return (res);
2439
2440} /* validate_dictmaker() */
2441
2442
Guido van Rossum47478871996-08-21 14:32:37 +00002443static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002444validate_eval_input(tree)
2445 node *tree;
2446{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002447 int pos;
2448 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002449 int res = (validate_ntype(tree, eval_input)
2450 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002451 && validate_testlist(CHILD(tree, 0))
2452 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2453
Guido van Rossum3d602e31996-07-21 02:33:56 +00002454 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002455 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002456
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002457 return (res);
2458
2459} /* validate_eval_input() */
2460
2461
Guido van Rossum47478871996-08-21 14:32:37 +00002462static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002463validate_node(tree)
2464 node *tree;
2465{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002466 int nch = 0; /* num. children on current node */
2467 int res = 1; /* result value */
2468 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002469
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002470 while (res & (tree != 0)) {
2471 nch = NCH(tree);
2472 next = 0;
2473 switch (TYPE(tree)) {
2474 /*
2475 * Definition nodes.
2476 */
2477 case funcdef:
2478 res = validate_funcdef(tree);
2479 break;
2480 case classdef:
2481 res = validate_class(tree);
2482 break;
2483 /*
2484 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002485 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002486 */
2487 case stmt:
2488 res = validate_stmt(tree);
2489 break;
2490 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002491 /*
2492 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
Guido van Rossum925e5471997-04-02 05:32:13 +00002493 * | import_stmt | global_stmt | exec_stmt | assert_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00002494 */
2495 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002496 break;
2497 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002498 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002499 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2500 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2501 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002502 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2503 if (res)
2504 next = CHILD(tree, 0);
2505 else if (nch == 1)
2506 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002507 break;
2508 /*
2509 * Compound statements.
2510 */
2511 case simple_stmt:
2512 res = validate_simple_stmt(tree);
2513 break;
2514 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002515 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002516 break;
2517 /*
2518 * Fundemental statements.
2519 */
2520 case expr_stmt:
2521 res = validate_expr_stmt(tree);
2522 break;
2523 case print_stmt:
2524 res = validate_print_stmt(tree);
2525 break;
2526 case del_stmt:
2527 res = validate_del_stmt(tree);
2528 break;
2529 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002530 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002531 && validate_name(CHILD(tree, 0), "pass"));
2532 break;
2533 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002534 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002535 && validate_name(CHILD(tree, 0), "break"));
2536 break;
2537 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002538 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002539 && validate_name(CHILD(tree, 0), "continue"));
2540 break;
2541 case return_stmt:
2542 res = validate_return_stmt(tree);
2543 break;
2544 case raise_stmt:
2545 res = validate_raise_stmt(tree);
2546 break;
2547 case import_stmt:
2548 res = validate_import_stmt(tree);
2549 break;
2550 case global_stmt:
2551 res = validate_global_stmt(tree);
2552 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002553 case exec_stmt:
2554 res = validate_exec_stmt(tree);
2555 break;
Guido van Rossum925e5471997-04-02 05:32:13 +00002556 case assert_stmt:
2557 res = validate_assert_stmt(tree);
2558 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002559 case if_stmt:
2560 res = validate_if(tree);
2561 break;
2562 case while_stmt:
2563 res = validate_while(tree);
2564 break;
2565 case for_stmt:
2566 res = validate_for(tree);
2567 break;
2568 case try_stmt:
2569 res = validate_try(tree);
2570 break;
2571 case suite:
2572 res = validate_suite(tree);
2573 break;
2574 /*
2575 * Expression nodes.
2576 */
2577 case testlist:
2578 res = validate_testlist(tree);
2579 break;
2580 case test:
2581 res = validate_test(tree);
2582 break;
2583 case and_test:
2584 res = validate_and_test(tree);
2585 break;
2586 case not_test:
2587 res = validate_not_test(tree);
2588 break;
2589 case comparison:
2590 res = validate_comparison(tree);
2591 break;
2592 case exprlist:
2593 res = validate_exprlist(tree);
2594 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002595 case comp_op:
2596 res = validate_comp_op(tree);
2597 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002598 case expr:
2599 res = validate_expr(tree);
2600 break;
2601 case xor_expr:
2602 res = validate_xor_expr(tree);
2603 break;
2604 case and_expr:
2605 res = validate_and_expr(tree);
2606 break;
2607 case shift_expr:
2608 res = validate_shift_expr(tree);
2609 break;
2610 case arith_expr:
2611 res = validate_arith_expr(tree);
2612 break;
2613 case term:
2614 res = validate_term(tree);
2615 break;
2616 case factor:
2617 res = validate_factor(tree);
2618 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002619 case power:
2620 res = validate_power(tree);
2621 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002622 case atom:
2623 res = validate_atom(tree);
2624 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002625
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002626 default:
2627 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002628 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002629 res = 0;
2630 break;
2631 }
2632 tree = next;
2633 }
2634 return (res);
2635
2636} /* validate_node() */
2637
2638
Guido van Rossum47478871996-08-21 14:32:37 +00002639static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002640validate_expr_tree(tree)
2641 node *tree;
2642{
2643 int res = validate_eval_input(tree);
2644
2645 if (!res && !PyErr_Occurred())
2646 err_string("Could not validate expression tuple.");
2647
2648 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002649
2650} /* validate_expr_tree() */
2651
2652
Guido van Rossum3d602e31996-07-21 02:33:56 +00002653/* file_input:
2654 * (NEWLINE | stmt)* ENDMARKER
2655 */
Guido van Rossum47478871996-08-21 14:32:37 +00002656static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00002657validate_file_input(tree)
2658 node *tree;
2659{
2660 int j = 0;
2661 int nch = NCH(tree) - 1;
2662 int res = ((nch >= 0)
2663 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002664
Guido van Rossum3d602e31996-07-21 02:33:56 +00002665 for ( ; res && (j < nch); ++j) {
2666 if (TYPE(CHILD(tree, j)) == stmt)
2667 res = validate_stmt(CHILD(tree, j));
2668 else
2669 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002670 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002671 /* This stays in to prevent any internal failues from getting to the
2672 * user. Hopefully, this won't be needed. If a user reports getting
2673 * this, we have some debugging to do.
2674 */
2675 if (!res && !PyErr_Occurred())
2676 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2677
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002678 return (res);
2679
Guido van Rossum2a288461996-08-21 21:55:43 +00002680} /* validate_file_input() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002681
2682
Fred Drake43f8f9b1998-04-13 16:25:46 +00002683static PyObject*
2684pickle_constructor = NULL;
2685
2686
2687static PyObject*
2688parser__pickler(self, args)
2689 PyObject *self;
2690 PyObject *args;
2691{
Fred Drake268397f1998-04-29 14:16:32 +00002692 NOTE(ARGUNUSED(self))
Fred Drake43f8f9b1998-04-13 16:25:46 +00002693 PyObject *result = NULL;
2694 PyObject *ast = NULL;
2695
2696 if (PyArg_ParseTuple(args, "O!:_pickler", &PyAST_Type, &ast)) {
2697 PyObject *newargs;
2698 PyObject *tuple;
2699
2700 if ((newargs = Py_BuildValue("Oi", ast, 1)) == NULL)
2701 goto finally;
Fred Drake268397f1998-04-29 14:16:32 +00002702 tuple = parser_ast2tuple((PyAST_Object*)NULL, newargs);
Fred Drake43f8f9b1998-04-13 16:25:46 +00002703 if (tuple != NULL) {
2704 result = Py_BuildValue("O(O)", pickle_constructor, tuple);
2705 Py_DECREF(tuple);
2706 }
Fred Drake7f875ef1998-08-04 15:58:10 +00002707 Py_DECREF(newargs);
Fred Drake43f8f9b1998-04-13 16:25:46 +00002708 }
2709 finally:
2710 return (result);
2711
2712} /* parser__pickler() */
2713
2714
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002715/* Functions exported by this module. Most of this should probably
2716 * be converted into an AST object with methods, but that is better
2717 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002718 * We'd really have to write a wrapper around it all anyway to allow
2719 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002720 */
2721static PyMethodDef parser_functions[] = {
Fred Drake301b5be1998-04-21 22:31:45 +00002722 {"ast2tuple", (PyCFunction)parser_ast2tuple, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002723 "Creates a tuple-tree representation of an AST."},
Fred Drake301b5be1998-04-21 22:31:45 +00002724 {"ast2list", (PyCFunction)parser_ast2list, METH_VARARGS,
Guido van Rossum47478871996-08-21 14:32:37 +00002725 "Creates a list-tree representation of an AST."},
Fred Drake301b5be1998-04-21 22:31:45 +00002726 {"compileast", (PyCFunction)parser_compileast, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002727 "Compiles an AST object into a code object."},
Fred Drake301b5be1998-04-21 22:31:45 +00002728 {"expr", (PyCFunction)parser_expr, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002729 "Creates an AST object from an expression."},
Fred Drake301b5be1998-04-21 22:31:45 +00002730 {"isexpr", (PyCFunction)parser_isexpr, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002731 "Determines if an AST object was created from an expression."},
Fred Drake301b5be1998-04-21 22:31:45 +00002732 {"issuite", (PyCFunction)parser_issuite, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002733 "Determines if an AST object was created from a suite."},
Fred Drake301b5be1998-04-21 22:31:45 +00002734 {"suite", (PyCFunction)parser_suite, METH_VARARGS,
Guido van Rossum3d602e31996-07-21 02:33:56 +00002735 "Creates an AST object from a suite."},
Fred Drake301b5be1998-04-21 22:31:45 +00002736 {"sequence2ast", (PyCFunction)parser_tuple2ast, METH_VARARGS,
Guido van Rossum47478871996-08-21 14:32:37 +00002737 "Creates an AST object from a tree representation."},
Fred Drake301b5be1998-04-21 22:31:45 +00002738 {"tuple2ast", (PyCFunction)parser_tuple2ast, METH_VARARGS,
Guido van Rossum47478871996-08-21 14:32:37 +00002739 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002740
Fred Drake43f8f9b1998-04-13 16:25:46 +00002741 /* private stuff: support pickle module */
Fred Drake301b5be1998-04-21 22:31:45 +00002742 {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS,
Fred Drake43f8f9b1998-04-13 16:25:46 +00002743 "Returns the pickle magic to allow ast objects to be pickled."},
2744
Fred Drake268397f1998-04-29 14:16:32 +00002745 {NULL, NULL, 0, NULL}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002746 };
2747
2748
Guido van Rossum3886bb61998-12-04 18:50:17 +00002749DL_EXPORT(void)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002750initparser()
2751 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002752 PyObject* module;
2753 PyObject* dict;
2754
2755 PyAST_Type.ob_type = &PyType_Type;
2756 module = Py_InitModule("parser", parser_functions);
2757 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002758
Fred Drake0225a381997-10-07 19:32:00 +00002759 parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002760
2761 if ((parser_error == 0)
2762 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2763 /*
2764 * This is serious.
2765 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002766 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002767 }
2768 /*
2769 * Nice to have, but don't cry if we fail.
2770 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002771 Py_INCREF(&PyAST_Type);
2772 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2773
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002774 PyDict_SetItemString(dict, "__copyright__",
2775 PyString_FromString(parser_copyright_string));
2776 PyDict_SetItemString(dict, "__doc__",
2777 PyString_FromString(parser_doc_string));
2778 PyDict_SetItemString(dict, "__version__",
2779 PyString_FromString(parser_version_string));
2780
Fred Drake503d8d61998-04-13 18:45:18 +00002781 parser_method_list = PyList_New(0);
2782 if (parser_method_list != NULL) {
2783 PyMethodDef *mdef = parser_methods;
2784
2785 while (mdef->ml_name != NULL) {
2786 PyObject *temp = PyString_FromString(mdef->ml_name);
2787 if (temp != NULL) {
2788 PyList_Append(parser_method_list, temp);
2789 Py_DECREF(temp);
2790 }
2791 ++mdef;
2792 }
2793 }
2794
Fred Drake43f8f9b1998-04-13 16:25:46 +00002795 /* register to support pickling */
2796 module = PyImport_ImportModule("copy_reg");
2797 if (module != NULL) {
Fred Drake301b5be1998-04-21 22:31:45 +00002798 PyObject *func, *pickler;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002799
2800 func = PyObject_GetAttrString(module, "pickle");
2801 pickle_constructor = PyDict_GetItemString(dict, "sequence2ast");
2802 pickler = PyDict_GetItemString(dict, "_pickler");
2803 Py_XINCREF(pickle_constructor);
2804 if ((func != NULL) && (pickle_constructor != NULL)
2805 && (pickler != NULL)) {
2806 PyObject *res;
2807
2808 res = PyObject_CallFunction(
2809 func, "OOO", &PyAST_Type, pickler, pickle_constructor);
2810 Py_XDECREF(res);
2811 }
2812 Py_XDECREF(func);
2813 Py_DECREF(module);
2814 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002815} /* initparser() */