blob: f4fb805f69e373a3db14ddc4d1c6a9cc704b7b3a [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
Fred Drakeff9ea482000-04-19 13:54:15 +000028#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() */
33#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
Fred Drakeff9ea482000-04-19 13:54:15 +000042char *strdup(char *);
Guido van Rossum19efc5f1998-04-28 16:10:19 +000043#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*
Fred Drakecff283c2000-08-21 22:24:43 +000061parser_version_string = "0.5";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000062
63
Fred Drakeff9ea482000-04-19 13:54:15 +000064typedef PyObject* (*SeqMaker) (int length);
65typedef int (*SeqInserter) (PyObject* sequence,
66 int index,
67 PyObject* element);
Guido van Rossum47478871996-08-21 14:32:37 +000068
Thomas Wouters7e474022000-07-16 12:04:32 +000069/* The function below is copyrighted 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 Rossumd9e9f9c1995-10-11 17:35:38 +000079static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +000080node2tuple(node *n, /* node to convert */
81 SeqMaker mkseq, /* create sequence */
82 SeqInserter addelem, /* func. to add elem. in seq. */
83 int lineno) /* include line numbers? */
Guido van Rossum47478871996-08-21 14:32:37 +000084{
Guido van Rossum3d602e31996-07-21 02:33:56 +000085 if (n == NULL) {
Fred Drakeff9ea482000-04-19 13:54:15 +000086 Py_INCREF(Py_None);
87 return (Py_None);
Guido van Rossum3d602e31996-07-21 02:33:56 +000088 }
89 if (ISNONTERMINAL(TYPE(n))) {
Fred Drakeff9ea482000-04-19 13:54:15 +000090 int i;
91 PyObject *v;
92 PyObject *w;
Fred Drake268397f1998-04-29 14:16:32 +000093
Fred Drakeff9ea482000-04-19 13:54:15 +000094 v = mkseq(1 + NCH(n));
95 if (v == NULL)
96 return (v);
97 w = PyInt_FromLong(TYPE(n));
98 if (w == NULL) {
99 Py_DECREF(v);
100 return ((PyObject*) NULL);
101 }
102 (void) addelem(v, 0, w);
103 for (i = 0; i < NCH(n); i++) {
104 w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
105 if (w == NULL) {
106 Py_DECREF(v);
107 return ((PyObject*) NULL);
108 }
109 (void) addelem(v, i+1, w);
110 }
111 return (v);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000112 }
113 else if (ISTERMINAL(TYPE(n))) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000114 PyObject *result = mkseq(2 + lineno);
115 if (result != NULL) {
116 (void) addelem(result, 0, PyInt_FromLong(TYPE(n)));
117 (void) addelem(result, 1, PyString_FromString(STR(n)));
118 if (lineno == 1)
119 (void) addelem(result, 2, PyInt_FromLong(n->n_lineno));
120 }
121 return (result);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000122 }
123 else {
Fred Drakeff9ea482000-04-19 13:54:15 +0000124 PyErr_SetString(PyExc_SystemError,
125 "unrecognized parse tree node type");
126 return ((PyObject*) NULL);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000127 }
Fred Drakeff9ea482000-04-19 13:54:15 +0000128}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000129/*
130 * End of material copyrighted by Stichting Mathematisch Centrum.
131 */
Guido van Rossum52f2c051993-11-10 12:53:24 +0000132
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000133
134
135/* There are two types of intermediate objects we're interested in:
136 * 'eval' and 'exec' types. These constants can be used in the ast_type
137 * field of the object type to identify which any given object represents.
138 * These should probably go in an external header to allow other extensions
139 * to use them, but then, we really should be using C++ too. ;-)
140 *
Guido van Rossum3d602e31996-07-21 02:33:56 +0000141 * The PyAST_FRAGMENT type is not currently supported. Maybe not useful?
142 * Haven't decided yet.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000143 */
144
Fred Drakeff9ea482000-04-19 13:54:15 +0000145#define PyAST_EXPR 1
146#define PyAST_SUITE 2
147#define PyAST_FRAGMENT 3
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000148
149
150/* These are the internal objects and definitions required to implement the
151 * AST type. Most of the internal names are more reminiscent of the 'old'
152 * naming style, but the code uses the new naming convention.
153 */
154
155static PyObject*
156parser_error = 0;
157
158
159typedef struct _PyAST_Object {
Fred Drakeff9ea482000-04-19 13:54:15 +0000160 PyObject_HEAD /* standard object header */
161 node* ast_node; /* the node* returned by the parser */
162 int ast_type; /* EXPR or SUITE ? */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000163} PyAST_Object;
164
165
Fred Drake268397f1998-04-29 14:16:32 +0000166staticforward void
Fred Drakeff9ea482000-04-19 13:54:15 +0000167parser_free(PyAST_Object *ast);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000168
Fred Drake268397f1998-04-29 14:16:32 +0000169staticforward int
Fred Drakeff9ea482000-04-19 13:54:15 +0000170parser_compare(PyAST_Object *left, PyAST_Object *right);
Fred Drake268397f1998-04-29 14:16:32 +0000171
172staticforward PyObject *
Fred Drakeff9ea482000-04-19 13:54:15 +0000173parser_getattr(PyObject *self, char *name);
Fred Drake503d8d61998-04-13 18:45:18 +0000174
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000175
Fred Drake268397f1998-04-29 14:16:32 +0000176static
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000177PyTypeObject PyAST_Type = {
Guido van Rossum3c8c5981998-05-29 02:58:20 +0000178 PyObject_HEAD_INIT(NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000179 0,
Fred Drakeff9ea482000-04-19 13:54:15 +0000180 "ast", /* tp_name */
181 (int) sizeof(PyAST_Object), /* tp_basicsize */
182 0, /* tp_itemsize */
183 (destructor)parser_free, /* tp_dealloc */
184 0, /* tp_print */
185 parser_getattr, /* tp_getattr */
186 0, /* tp_setattr */
187 (cmpfunc)parser_compare, /* tp_compare */
188 0, /* tp_repr */
189 0, /* tp_as_number */
190 0, /* tp_as_sequence */
191 0, /* tp_as_mapping */
192 0, /* tp_hash */
193 0, /* tp_call */
194 0, /* tp_str */
195 0, /* tp_getattro */
196 0, /* tp_setattro */
Fred Drake69b9ae41997-05-23 04:04:17 +0000197
198 /* Functions to access object as input/output buffer */
Fred Drakeff9ea482000-04-19 13:54:15 +0000199 0, /* tp_as_buffer */
Fred Drake69b9ae41997-05-23 04:04:17 +0000200
Fred Drakeff9ea482000-04-19 13:54:15 +0000201 Py_TPFLAGS_DEFAULT, /* tp_flags */
Fred Drake69b9ae41997-05-23 04:04:17 +0000202
203 /* __doc__ */
204 "Intermediate representation of a Python parse tree."
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000205}; /* PyAST_Type */
206
207
208static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000209parser_compare_nodes(node *left, node *right)
Guido van Rossum47478871996-08-21 14:32:37 +0000210{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000211 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000212
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000213 if (TYPE(left) < TYPE(right))
Fred Drakeff9ea482000-04-19 13:54:15 +0000214 return (-1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000215
216 if (TYPE(right) < TYPE(left))
Fred Drakeff9ea482000-04-19 13:54:15 +0000217 return (1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000218
219 if (ISTERMINAL(TYPE(left)))
Fred Drakeff9ea482000-04-19 13:54:15 +0000220 return (strcmp(STR(left), STR(right)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000221
222 if (NCH(left) < NCH(right))
Fred Drakeff9ea482000-04-19 13:54:15 +0000223 return (-1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000224
225 if (NCH(right) < NCH(left))
Fred Drakeff9ea482000-04-19 13:54:15 +0000226 return (1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000227
228 for (j = 0; j < NCH(left); ++j) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000229 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000230
Fred Drakeff9ea482000-04-19 13:54:15 +0000231 if (v != 0)
232 return (v);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000233 }
234 return (0);
Fred Drakeff9ea482000-04-19 13:54:15 +0000235}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000236
237
238/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
239 *
240 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
241 * This really just wraps a call to parser_compare_nodes() with some easy
242 * checks and protection code.
243 *
244 */
245static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000246parser_compare(PyAST_Object *left, PyAST_Object *right)
Guido van Rossum47478871996-08-21 14:32:37 +0000247{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000248 if (left == right)
Fred Drakeff9ea482000-04-19 13:54:15 +0000249 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000250
251 if ((left == 0) || (right == 0))
Fred Drakeff9ea482000-04-19 13:54:15 +0000252 return (-1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000253
254 return (parser_compare_nodes(left->ast_node, right->ast_node));
Fred Drakeff9ea482000-04-19 13:54:15 +0000255}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000256
257
258/* parser_newastobject(node* ast)
259 *
260 * Allocates a new Python object representing an AST. This is simply the
261 * 'wrapper' object that holds a node* and allows it to be passed around in
262 * Python code.
263 *
264 */
265static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000266parser_newastobject(node *ast, int type)
Guido van Rossum47478871996-08-21 14:32:37 +0000267{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000268 PyAST_Object* o = PyObject_New(PyAST_Object, &PyAST_Type);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000269
270 if (o != 0) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000271 o->ast_node = ast;
272 o->ast_type = type;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000273 }
Fred Drake268397f1998-04-29 14:16:32 +0000274 else {
Fred Drakeff9ea482000-04-19 13:54:15 +0000275 PyNode_Free(ast);
Fred Drake268397f1998-04-29 14:16:32 +0000276 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000277 return ((PyObject*)o);
Fred Drakeff9ea482000-04-19 13:54:15 +0000278}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000279
280
281/* void parser_free(PyAST_Object* ast)
282 *
283 * This is called by a del statement that reduces the reference count to 0.
284 *
285 */
286static void
Fred Drakeff9ea482000-04-19 13:54:15 +0000287parser_free(PyAST_Object *ast)
Guido van Rossum47478871996-08-21 14:32:37 +0000288{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000289 PyNode_Free(ast->ast_node);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000290 PyObject_Del(ast);
Fred Drakeff9ea482000-04-19 13:54:15 +0000291}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000292
293
Fred Drake2a6875e1999-09-20 22:32:18 +0000294/* parser_ast2tuple(PyObject* self, PyObject* args, PyObject* kw)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000295 *
296 * This provides conversion from a node* to a tuple object that can be
297 * returned to the Python-level caller. The AST object is not modified.
298 *
299 */
300static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000301parser_ast2tuple(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000302{
Guido van Rossum47478871996-08-21 14:32:37 +0000303 PyObject *line_option = 0;
304 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000305 int ok;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000306
Fred Drake7a15ba51999-09-09 14:21:52 +0000307 static char *keywords[] = {"ast", "line_info", NULL};
308
Fred Drake268397f1998-04-29 14:16:32 +0000309 if (self == NULL) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000310 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:ast2tuple", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000311 &PyAST_Type, &self, &line_option);
Fred Drake268397f1998-04-29 14:16:32 +0000312 }
Fred Drake503d8d61998-04-13 18:45:18 +0000313 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000314 ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:totuple", &keywords[1],
Fred Drake7a15ba51999-09-09 14:21:52 +0000315 &line_option);
Fred Drake268397f1998-04-29 14:16:32 +0000316 if (ok != 0) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000317 int lineno = 0;
318 if (line_option != NULL) {
319 lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0;
320 }
321 /*
322 * Convert AST into a tuple representation. Use Guido's function,
323 * since it's known to work already.
324 */
325 res = node2tuple(((PyAST_Object*)self)->ast_node,
326 PyTuple_New, PyTuple_SetItem, lineno);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000327 }
328 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000329}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000330
331
Fred Drake2a6875e1999-09-20 22:32:18 +0000332/* parser_ast2list(PyObject* self, PyObject* args, PyObject* kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000333 *
Fred Drake2a6875e1999-09-20 22:32:18 +0000334 * This provides conversion from a node* to a list object that can be
Guido van Rossum47478871996-08-21 14:32:37 +0000335 * returned to the Python-level caller. The AST object is not modified.
336 *
337 */
338static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000339parser_ast2list(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000340{
Guido van Rossum47478871996-08-21 14:32:37 +0000341 PyObject *line_option = 0;
342 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000343 int ok;
Guido van Rossum47478871996-08-21 14:32:37 +0000344
Fred Drake7a15ba51999-09-09 14:21:52 +0000345 static char *keywords[] = {"ast", "line_info", NULL};
346
Fred Drake503d8d61998-04-13 18:45:18 +0000347 if (self == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000348 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:ast2list", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000349 &PyAST_Type, &self, &line_option);
Fred Drake503d8d61998-04-13 18:45:18 +0000350 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000351 ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1],
Fred Drake7a15ba51999-09-09 14:21:52 +0000352 &line_option);
Fred Drake503d8d61998-04-13 18:45:18 +0000353 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000354 int lineno = 0;
355 if (line_option != 0) {
356 lineno = PyObject_IsTrue(line_option) ? 1 : 0;
357 }
358 /*
359 * Convert AST into a tuple representation. Use Guido's function,
360 * since it's known to work already.
361 */
362 res = node2tuple(self->ast_node,
363 PyList_New, PyList_SetItem, lineno);
Guido van Rossum47478871996-08-21 14:32:37 +0000364 }
365 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000366}
Guido van Rossum47478871996-08-21 14:32:37 +0000367
368
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000369/* parser_compileast(PyObject* self, PyObject* args)
370 *
371 * This function creates code objects from the parse tree represented by
372 * the passed-in data object. An optional file name is passed in as well.
373 *
374 */
375static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000376parser_compileast(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000377{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000378 PyObject* res = 0;
Fred Drakeff9ea482000-04-19 13:54:15 +0000379 char* str = "<ast>";
Fred Drake503d8d61998-04-13 18:45:18 +0000380 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000381
Fred Drake7a15ba51999-09-09 14:21:52 +0000382 static char *keywords[] = {"ast", "filename", NULL};
383
Fred Drake503d8d61998-04-13 18:45:18 +0000384 if (self == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000385 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compileast", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000386 &PyAST_Type, &self, &str);
Fred Drake503d8d61998-04-13 18:45:18 +0000387 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000388 ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1],
Fred Drake7a15ba51999-09-09 14:21:52 +0000389 &str);
Fred Drake503d8d61998-04-13 18:45:18 +0000390
391 if (ok)
Fred Drakeff9ea482000-04-19 13:54:15 +0000392 res = (PyObject *)PyNode_Compile(self->ast_node, str);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000393
394 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000395}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000396
397
398/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
399 * PyObject* parser_issuite(PyObject* self, PyObject* args)
400 *
401 * Checks the passed-in AST object to determine if it is an expression or
402 * a statement suite, respectively. The return is a Python truth value.
403 *
404 */
405static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000406parser_isexpr(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000407{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000408 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000409 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000410
Fred Drake7a15ba51999-09-09 14:21:52 +0000411 static char *keywords[] = {"ast", NULL};
412
Fred Drake503d8d61998-04-13 18:45:18 +0000413 if (self == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000414 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000415 &PyAST_Type, &self);
Fred Drake503d8d61998-04-13 18:45:18 +0000416 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000417 ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]);
Fred Drake503d8d61998-04-13 18:45:18 +0000418
419 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000420 /* Check to see if the AST represents an expression or not. */
421 res = (self->ast_type == PyAST_EXPR) ? Py_True : Py_False;
422 Py_INCREF(res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000423 }
424 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000425}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000426
427
428static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000429parser_issuite(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000430{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000431 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000432 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000433
Fred Drake7a15ba51999-09-09 14:21:52 +0000434 static char *keywords[] = {"ast", NULL};
435
Fred Drake503d8d61998-04-13 18:45:18 +0000436 if (self == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000437 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000438 &PyAST_Type, &self);
Fred Drake503d8d61998-04-13 18:45:18 +0000439 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000440 ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]);
Fred Drake503d8d61998-04-13 18:45:18 +0000441
442 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000443 /* Check to see if the AST represents an expression or not. */
444 res = (self->ast_type == PyAST_EXPR) ? Py_False : Py_True;
445 Py_INCREF(res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000446 }
447 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000448}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000449
450
Fred Drake7a15ba51999-09-09 14:21:52 +0000451#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS)
452
Fred Drake503d8d61998-04-13 18:45:18 +0000453static PyMethodDef
454parser_methods[] = {
Fred Drakeff9ea482000-04-19 13:54:15 +0000455 {"compile", (PyCFunction)parser_compileast, PUBLIC_METHOD_TYPE,
456 "Compile this AST object into a code object."},
457 {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
458 "Determines if this AST object was created from an expression."},
459 {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
460 "Determines if this AST object was created from a suite."},
461 {"tolist", (PyCFunction)parser_ast2list, PUBLIC_METHOD_TYPE,
462 "Creates a list-tree representation of this AST."},
463 {"totuple", (PyCFunction)parser_ast2tuple, PUBLIC_METHOD_TYPE,
464 "Creates a tuple-tree representation of this AST."},
Fred Drake503d8d61998-04-13 18:45:18 +0000465
Fred Drake268397f1998-04-29 14:16:32 +0000466 {NULL, NULL, 0, NULL}
Fred Drake503d8d61998-04-13 18:45:18 +0000467};
468
Fred Drake503d8d61998-04-13 18:45:18 +0000469
470static PyObject*
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +0000471parser_getattr(PyObject *self, char *name)
Fred Drake503d8d61998-04-13 18:45:18 +0000472{
Fred Drake503d8d61998-04-13 18:45:18 +0000473 return (Py_FindMethod(parser_methods, self, name));
Fred Drakeff9ea482000-04-19 13:54:15 +0000474}
Fred Drake503d8d61998-04-13 18:45:18 +0000475
476
Guido van Rossum3d602e31996-07-21 02:33:56 +0000477/* err_string(char* message)
478 *
479 * Sets the error string for an exception of type ParserError.
480 *
481 */
482static void
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +0000483err_string(char *message)
Guido van Rossum47478871996-08-21 14:32:37 +0000484{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000485 PyErr_SetString(parser_error, message);
Fred Drakeff9ea482000-04-19 13:54:15 +0000486}
Guido van Rossum3d602e31996-07-21 02:33:56 +0000487
488
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000489/* PyObject* parser_do_parse(PyObject* args, int type)
490 *
491 * Internal function to actually execute the parse and return the result if
492 * successful, or set an exception if not.
493 *
494 */
495static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000496parser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type)
Guido van Rossum47478871996-08-21 14:32:37 +0000497{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000498 char* string = 0;
499 PyObject* res = 0;
500
Fred Drake7a15ba51999-09-09 14:21:52 +0000501 static char *keywords[] = {"source", NULL};
502
503 if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000504 node* n = PyParser_SimpleParseString(string,
505 (type == PyAST_EXPR)
506 ? eval_input : file_input);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000507
Fred Drakeff9ea482000-04-19 13:54:15 +0000508 if (n != 0)
509 res = parser_newastobject(n, type);
510 else
511 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000512 }
513 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000514}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000515
516
517/* PyObject* parser_expr(PyObject* self, PyObject* args)
518 * PyObject* parser_suite(PyObject* self, PyObject* args)
519 *
520 * External interfaces to the parser itself. Which is called determines if
521 * the parser attempts to recognize an expression ('eval' form) or statement
522 * suite ('exec' form). The real work is done by parser_do_parse() above.
523 *
524 */
525static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000526parser_expr(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000527{
Fred Drake268397f1998-04-29 14:16:32 +0000528 NOTE(ARGUNUSED(self))
Fred Drake7a15ba51999-09-09 14:21:52 +0000529 return (parser_do_parse(args, kw, "s:expr", PyAST_EXPR));
Fred Drakeff9ea482000-04-19 13:54:15 +0000530}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000531
532
533static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000534parser_suite(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000535{
Fred Drake268397f1998-04-29 14:16:32 +0000536 NOTE(ARGUNUSED(self))
Fred Drake7a15ba51999-09-09 14:21:52 +0000537 return (parser_do_parse(args, kw, "s:suite", PyAST_SUITE));
Fred Drakeff9ea482000-04-19 13:54:15 +0000538}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000539
540
541
542/* This is the messy part of the code. Conversion from a tuple to an AST
543 * object requires that the input tuple be valid without having to rely on
544 * catching an exception from the compiler. This is done to allow the
545 * compiler itself to remain fast, since most of its input will come from
546 * the parser directly, and therefore be known to be syntactically correct.
547 * This validation is done to ensure that we don't core dump the compile
548 * phase, returning an exception instead.
549 *
550 * Two aspects can be broken out in this code: creating a node tree from
551 * the tuple passed in, and verifying that it is indeed valid. It may be
552 * advantageous to expand the number of AST types to include funcdefs and
553 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
554 * here. They are not necessary, and not quite as useful in a raw form.
555 * For now, let's get expressions and suites working reliably.
556 */
557
558
Fred Drakeff9ea482000-04-19 13:54:15 +0000559staticforward node* build_node_tree(PyObject *tuple);
560staticforward int validate_expr_tree(node *tree);
561staticforward int validate_file_input(node *tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000562
563
564/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
565 *
566 * This is the public function, called from the Python code. It receives a
567 * single tuple object from the caller, and creates an AST object if the
568 * tuple can be validated. It does this by checking the first code of the
569 * tuple, and, if acceptable, builds the internal representation. If this
570 * step succeeds, the internal representation is validated as fully as
571 * possible with the various validate_*() routines defined below.
572 *
573 * This function must be changed if support is to be added for PyAST_FRAGMENT
574 * AST objects.
575 *
576 */
577static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000578parser_tuple2ast(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000579{
Fred Drake268397f1998-04-29 14:16:32 +0000580 NOTE(ARGUNUSED(self))
Guido van Rossum47478871996-08-21 14:32:37 +0000581 PyObject *ast = 0;
582 PyObject *tuple = 0;
583 PyObject *temp = 0;
584 int ok;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000585 int start_sym = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000586
Fred Drake7a15ba51999-09-09 14:21:52 +0000587 static char *keywords[] = {"sequence", NULL};
588
589 if (!PyArg_ParseTupleAndKeywords(args, kw, "O:tuple2ast", keywords,
590 &tuple))
Fred Drakeff9ea482000-04-19 13:54:15 +0000591 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000592 if (!PySequence_Check(tuple)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000593 PyErr_SetString(PyExc_ValueError,
594 "tuple2ast() requires a single sequence argument");
595 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000596 }
597 /*
Fred Drakeff9ea482000-04-19 13:54:15 +0000598 * This mess of tests is written this way so we can use the abstract
599 * object interface (AOI). Unfortunately, the AOI increments reference
600 * counts, which requires that we store a pointer to retrieved object
601 * so we can DECREF it after the check. But we really should accept
602 * lists as well as tuples at the very least.
Guido van Rossum47478871996-08-21 14:32:37 +0000603 */
Jeremy Hylton03657cf2000-07-12 13:05:33 +0000604 ok = PyObject_Size(tuple) >= 2;
Guido van Rossum47478871996-08-21 14:32:37 +0000605 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000606 temp = PySequence_GetItem(tuple, 0);
607 ok = (temp != NULL) && PyInt_Check(temp);
608 if (ok)
609 /* this is used after the initial checks: */
610 start_sym = PyInt_AS_LONG(temp);
611 Py_XDECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000612 }
613 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000614 temp = PySequence_GetItem(tuple, 1);
615 ok = (temp != NULL) && PySequence_Check(temp);
616 Py_XDECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000617 }
618 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000619 temp = PySequence_GetItem(tuple, 1);
Jeremy Hylton03657cf2000-07-12 13:05:33 +0000620 ok = (temp != NULL) && PyObject_Size(temp) >= 2;
Fred Drakeff9ea482000-04-19 13:54:15 +0000621 if (ok) {
622 PyObject *temp2 = PySequence_GetItem(temp, 0);
623 if (temp2 != NULL) {
624 ok = PyInt_Check(temp2);
625 Py_DECREF(temp2);
626 }
627 }
628 Py_XDECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000629 }
630 /* If we've failed at some point, get out of here. */
631 if (!ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000632 err_string("malformed sequence for tuple2ast()");
633 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000634 }
635 /*
636 * This might be a valid parse tree, but let's do a quick check
637 * before we jump the gun.
638 */
639 if (start_sym == eval_input) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000640 /* Might be an eval form. */
641 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000642
Fred Drakeff9ea482000-04-19 13:54:15 +0000643 if ((expression != 0) && validate_expr_tree(expression))
644 ast = parser_newastobject(expression, PyAST_EXPR);
Guido van Rossum47478871996-08-21 14:32:37 +0000645 }
646 else if (start_sym == file_input) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000647 /* This looks like an exec form so far. */
648 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000649
Fred Drakeff9ea482000-04-19 13:54:15 +0000650 if ((suite_tree != 0) && validate_file_input(suite_tree))
651 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000652 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000653 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000654 /* This is a fragment, and is not yet supported. Maybe they
655 * will be if I find a use for them.
656 */
657 err_string("Fragmentary parse trees not supported.");
Guido van Rossum47478871996-08-21 14:32:37 +0000658
659 /* Make sure we throw an exception on all errors. We should never
660 * get this, but we'd do well to be sure something is done.
661 */
662 if ((ast == 0) && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +0000663 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000664
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000665 return (ast);
Fred Drakeff9ea482000-04-19 13:54:15 +0000666}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000667
668
669/* int check_terminal_tuple()
670 *
Guido van Rossum47478871996-08-21 14:32:37 +0000671 * Check a tuple to determine that it is indeed a valid terminal
672 * node. The node is known to be required as a terminal, so we throw
673 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000674 *
Guido van Rossum47478871996-08-21 14:32:37 +0000675 * The format of an acceptable terminal tuple is "(is[i])": the fact
676 * that elem is a tuple and the integer is a valid terminal symbol
677 * has been established before this function is called. We must
678 * check the length of the tuple and the type of the second element
679 * and optional third element. We do *NOT* check the actual text of
680 * the string element, which we could do in many cases. This is done
681 * by the validate_*() functions which operate on the internal
682 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000683 */
684static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000685check_terminal_tuple(PyObject *elem)
Guido van Rossum47478871996-08-21 14:32:37 +0000686{
Jeremy Hylton03657cf2000-07-12 13:05:33 +0000687 int len = PyObject_Size(elem);
Guido van Rossum47478871996-08-21 14:32:37 +0000688 int res = 1;
689 char* str = "Illegal terminal symbol; bad node length.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000690
Guido van Rossum47478871996-08-21 14:32:37 +0000691 if ((len == 2) || (len == 3)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000692 PyObject *temp = PySequence_GetItem(elem, 1);
693 res = PyString_Check(temp);
694 str = "Illegal terminal symbol; expected a string.";
695 if (res && (len == 3)) {
696 PyObject* third = PySequence_GetItem(elem, 2);
697 res = PyInt_Check(third);
698 str = "Invalid third element of terminal node.";
699 Py_XDECREF(third);
700 }
701 Py_XDECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000702 }
703 else {
Fred Drakeff9ea482000-04-19 13:54:15 +0000704 res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000705 }
706 if (!res) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000707 elem = Py_BuildValue("(os)", elem, str);
708 PyErr_SetObject(parser_error, elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000709 }
710 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000711}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000712
713
714/* node* build_node_children()
715 *
716 * Iterate across the children of the current non-terminal node and build
717 * their structures. If successful, return the root of this portion of
718 * the tree, otherwise, 0. Any required exception will be specified already,
719 * and no memory will have been deallocated.
720 *
721 */
722static node*
Fred Drakeff9ea482000-04-19 13:54:15 +0000723build_node_children(PyObject *tuple, node *root, int *line_num)
Guido van Rossum47478871996-08-21 14:32:37 +0000724{
Jeremy Hylton03657cf2000-07-12 13:05:33 +0000725 int len = PyObject_Size(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000726 int i;
727
728 for (i = 1; i < len; ++i) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000729 /* elem must always be a tuple, however simple */
730 PyObject* elem = PySequence_GetItem(tuple, i);
731 int ok = elem != NULL;
732 long type = 0;
733 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000734
Fred Drakeff9ea482000-04-19 13:54:15 +0000735 if (ok)
736 ok = PySequence_Check(elem);
737 if (ok) {
738 PyObject *temp = PySequence_GetItem(elem, 0);
739 if (temp == NULL)
740 ok = 0;
741 else {
742 ok = PyInt_Check(temp);
743 if (ok)
744 type = PyInt_AS_LONG(temp);
745 Py_DECREF(temp);
746 }
747 }
748 if (!ok) {
749 PyErr_SetObject(parser_error,
750 Py_BuildValue("(os)", elem,
751 "Illegal node construct."));
752 Py_XDECREF(elem);
753 return (0);
754 }
755 if (ISTERMINAL(type)) {
756 if (check_terminal_tuple(elem)) {
757 PyObject *temp = PySequence_GetItem(elem, 1);
Guido van Rossum47478871996-08-21 14:32:37 +0000758
Fred Drakeff9ea482000-04-19 13:54:15 +0000759 /* check_terminal_tuple() already verified it's a string */
Guido van Rossumb18618d2000-05-03 23:44:39 +0000760 strn = (char *)PyMem_MALLOC(PyString_GET_SIZE(temp) + 1);
Fred Drakeff9ea482000-04-19 13:54:15 +0000761 if (strn != NULL)
762 (void) strcpy(strn, PyString_AS_STRING(temp));
Guido van Rossumb18618d2000-05-03 23:44:39 +0000763 Py_DECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000764
Jeremy Hylton03657cf2000-07-12 13:05:33 +0000765 if (PyObject_Size(elem) == 3) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000766 PyObject* temp = PySequence_GetItem(elem, 2);
767 *line_num = PyInt_AsLong(temp);
768 Py_DECREF(temp);
769 }
770 }
771 else {
772 Py_XDECREF(elem);
773 return (0);
774 }
775 }
776 else if (!ISNONTERMINAL(type)) {
777 /*
778 * It has to be one or the other; this is an error.
779 * Throw an exception.
780 */
781 PyErr_SetObject(parser_error,
782 Py_BuildValue("(os)", elem,
783 "Unknown node type."));
784 Py_XDECREF(elem);
785 return (0);
786 }
787 PyNode_AddChild(root, type, strn, *line_num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000788
Fred Drakeff9ea482000-04-19 13:54:15 +0000789 if (ISNONTERMINAL(type)) {
790 node* new_child = CHILD(root, i - 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000791
Fred Drakeff9ea482000-04-19 13:54:15 +0000792 if (new_child != build_node_children(elem, new_child, line_num)) {
793 Py_XDECREF(elem);
794 return (0);
795 }
796 }
797 else if (type == NEWLINE) { /* It's true: we increment the */
798 ++(*line_num); /* line number *after* the newline! */
799 }
800 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000801 }
802 return (root);
Fred Drakeff9ea482000-04-19 13:54:15 +0000803}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000804
805
806static node*
Fred Drakeff9ea482000-04-19 13:54:15 +0000807build_node_tree(PyObject *tuple)
Guido van Rossum47478871996-08-21 14:32:37 +0000808{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000809 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000810 PyObject *temp = PySequence_GetItem(tuple, 0);
811 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000812
Guido van Rossum47478871996-08-21 14:32:37 +0000813 if (temp != NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000814 num = PyInt_AsLong(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000815 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000816 if (ISTERMINAL(num)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000817 /*
818 * The tuple is simple, but it doesn't start with a start symbol.
819 * Throw an exception now and be done with it.
820 */
821 tuple = Py_BuildValue("(os)", tuple,
822 "Illegal ast tuple; cannot start with terminal symbol.");
823 PyErr_SetObject(parser_error, tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000824 }
825 else if (ISNONTERMINAL(num)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000826 /*
827 * Not efficient, but that can be handled later.
828 */
829 int line_num = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000830
Fred Drakeff9ea482000-04-19 13:54:15 +0000831 res = PyNode_New(num);
832 if (res != build_node_children(tuple, res, &line_num)) {
833 PyNode_Free(res);
834 res = 0;
835 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000836 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000837 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000838 /* The tuple is illegal -- if the number is neither TERMINAL nor
839 * NONTERMINAL, we can't use it.
840 */
841 PyErr_SetObject(parser_error,
842 Py_BuildValue("(os)", tuple,
843 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000844
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000845 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000846}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000847
848
Fred Drakeff9ea482000-04-19 13:54:15 +0000849#define VALIDATER(n) static int validate_##n(node *tree)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000850
851
852/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000853 * Validation routines used within the validation section:
854 */
Fred Drakeff9ea482000-04-19 13:54:15 +0000855staticforward int validate_terminal(node *terminal, int type, char *string);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000856
Fred Drakeff9ea482000-04-19 13:54:15 +0000857#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
858#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
859#define validate_colon(ch) validate_terminal(ch, COLON, ":")
860#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
861#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
862#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
863#define validate_indent(ch) validate_terminal(ch, INDENT, (char*)NULL)
864#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
865#define validate_newline(ch) validate_terminal(ch, NEWLINE, (char*)NULL)
866#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
867#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
868#define validate_star(ch) validate_terminal(ch, STAR, "*")
869#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
870#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
871#define validate_dot(ch) validate_terminal(ch, DOT, ".")
872#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000873
Fred Drakeff9ea482000-04-19 13:54:15 +0000874VALIDATER(node); VALIDATER(small_stmt);
875VALIDATER(class); VALIDATER(node);
876VALIDATER(parameters); VALIDATER(suite);
877VALIDATER(testlist); VALIDATER(varargslist);
878VALIDATER(fpdef); VALIDATER(fplist);
879VALIDATER(stmt); VALIDATER(simple_stmt);
880VALIDATER(expr_stmt); VALIDATER(power);
881VALIDATER(print_stmt); VALIDATER(del_stmt);
Fred Drakecff283c2000-08-21 22:24:43 +0000882VALIDATER(return_stmt); VALIDATER(list_iter);
Fred Drakeff9ea482000-04-19 13:54:15 +0000883VALIDATER(raise_stmt); VALIDATER(import_stmt);
Fred Drakecff283c2000-08-21 22:24:43 +0000884VALIDATER(global_stmt); VALIDATER(list_if);
885VALIDATER(assert_stmt); VALIDATER(list_for);
Fred Drakeff9ea482000-04-19 13:54:15 +0000886VALIDATER(exec_stmt); VALIDATER(compound_stmt);
887VALIDATER(while); VALIDATER(for);
888VALIDATER(try); VALIDATER(except_clause);
889VALIDATER(test); VALIDATER(and_test);
890VALIDATER(not_test); VALIDATER(comparison);
891VALIDATER(comp_op); VALIDATER(expr);
892VALIDATER(xor_expr); VALIDATER(and_expr);
893VALIDATER(shift_expr); VALIDATER(arith_expr);
894VALIDATER(term); VALIDATER(factor);
895VALIDATER(atom); VALIDATER(lambdef);
896VALIDATER(trailer); VALIDATER(subscript);
897VALIDATER(subscriptlist); VALIDATER(sliceop);
898VALIDATER(exprlist); VALIDATER(dictmaker);
899VALIDATER(arglist); VALIDATER(argument);
Fred Drakecff283c2000-08-21 22:24:43 +0000900VALIDATER(listmaker);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000901
902
Fred Drakeff9ea482000-04-19 13:54:15 +0000903#define is_even(n) (((n) & 1) == 0)
904#define is_odd(n) (((n) & 1) == 1)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000905
906
907static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000908validate_ntype(node *n, int t)
Guido van Rossum47478871996-08-21 14:32:37 +0000909{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000910 int res = (TYPE(n) == t);
911
912 if (!res) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000913 char buffer[128];
914 (void) sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
915 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000916 }
917 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000918}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000919
920
Fred Drakee7ab64e2000-04-25 04:14:46 +0000921/* Verifies that the number of child nodes is exactly 'num', raising
922 * an exception if it isn't. The exception message does not indicate
923 * the exact number of nodes, allowing this to be used to raise the
924 * "right" exception when the wrong number of nodes is present in a
925 * specific variant of a statement's syntax. This is commonly used
926 * in that fashion.
927 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000928static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000929validate_numnodes(node *n, int num, const char *const name)
Guido van Rossum47478871996-08-21 14:32:37 +0000930{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000931 if (NCH(n) != num) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000932 char buff[60];
933 (void) sprintf(buff, "Illegal number of children for %s node.", name);
934 err_string(buff);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000935 }
936 return (NCH(n) == num);
Fred Drakeff9ea482000-04-19 13:54:15 +0000937}
Guido van Rossum3d602e31996-07-21 02:33:56 +0000938
939
940static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000941validate_terminal(node *terminal, int type, char *string)
Guido van Rossum47478871996-08-21 14:32:37 +0000942{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000943 int res = (validate_ntype(terminal, type)
Fred Drakeff9ea482000-04-19 13:54:15 +0000944 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000945
946 if (!res && !PyErr_Occurred()) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000947 char buffer[60];
948 (void) sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
949 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000950 }
951 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000952}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000953
954
Guido van Rossum47478871996-08-21 14:32:37 +0000955/* X (',' X) [',']
956 */
957static int
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +0000958validate_repeating_list(node *tree, int ntype, int (*vfunc)(node *),
Fred Drakeff9ea482000-04-19 13:54:15 +0000959 const char *const name)
Guido van Rossum47478871996-08-21 14:32:37 +0000960{
961 int nch = NCH(tree);
962 int res = (nch && validate_ntype(tree, ntype)
Fred Drakeff9ea482000-04-19 13:54:15 +0000963 && vfunc(CHILD(tree, 0)));
Guido van Rossum47478871996-08-21 14:32:37 +0000964
965 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +0000966 (void) validate_numnodes(tree, 1, name);
Guido van Rossum47478871996-08-21 14:32:37 +0000967 else {
Fred Drakeff9ea482000-04-19 13:54:15 +0000968 if (is_even(nch))
969 res = validate_comma(CHILD(tree, --nch));
970 if (res && nch > 1) {
971 int pos = 1;
972 for ( ; res && pos < nch; pos += 2)
973 res = (validate_comma(CHILD(tree, pos))
974 && vfunc(CHILD(tree, pos + 1)));
975 }
Guido van Rossum47478871996-08-21 14:32:37 +0000976 }
977 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000978}
Guido van Rossum47478871996-08-21 14:32:37 +0000979
980
Fred Drakecff283c2000-08-21 22:24:43 +0000981/* validate_class()
Guido van Rossum3d602e31996-07-21 02:33:56 +0000982 *
983 * classdef:
Fred Drakeff9ea482000-04-19 13:54:15 +0000984 * 'class' NAME ['(' testlist ')'] ':' suite
Guido van Rossum3d602e31996-07-21 02:33:56 +0000985 */
Guido van Rossum47478871996-08-21 14:32:37 +0000986static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000987validate_class(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000988{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000989 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000990 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000991
Guido van Rossum3d602e31996-07-21 02:33:56 +0000992 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000993 res = (validate_name(CHILD(tree, 0), "class")
994 && validate_ntype(CHILD(tree, 1), NAME)
995 && validate_colon(CHILD(tree, nch - 2))
996 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000997 }
998 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000999 (void) validate_numnodes(tree, 4, "class");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001000 if (res && (nch == 7)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001001 res = (validate_lparen(CHILD(tree, 2))
1002 && validate_testlist(CHILD(tree, 3))
1003 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001004 }
1005 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001006}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001007
1008
Guido van Rossum3d602e31996-07-21 02:33:56 +00001009/* if_stmt:
Fred Drakeff9ea482000-04-19 13:54:15 +00001010 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001011 */
Guido van Rossum47478871996-08-21 14:32:37 +00001012static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001013validate_if(node *tree)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001014{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001015 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001016 int res = (validate_ntype(tree, if_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001017 && (nch >= 4)
1018 && validate_name(CHILD(tree, 0), "if")
1019 && validate_test(CHILD(tree, 1))
1020 && validate_colon(CHILD(tree, 2))
1021 && validate_suite(CHILD(tree, 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001022
1023 if (res && ((nch % 4) == 3)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001024 /* ... 'else' ':' suite */
1025 res = (validate_name(CHILD(tree, nch - 3), "else")
1026 && validate_colon(CHILD(tree, nch - 2))
1027 && validate_suite(CHILD(tree, nch - 1)));
1028 nch -= 3;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001029 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001030 else if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00001031 (void) validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001032 if ((nch % 4) != 0)
Fred Drakeff9ea482000-04-19 13:54:15 +00001033 /* Will catch the case for nch < 4 */
1034 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001035 else if (res && (nch > 4)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001036 /* ... ('elif' test ':' suite)+ ... */
1037 int j = 4;
1038 while ((j < nch) && res) {
1039 res = (validate_name(CHILD(tree, j), "elif")
1040 && validate_colon(CHILD(tree, j + 2))
1041 && validate_test(CHILD(tree, j + 1))
1042 && validate_suite(CHILD(tree, j + 3)));
1043 j += 4;
1044 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001045 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001046 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001047}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001048
1049
Guido van Rossum3d602e31996-07-21 02:33:56 +00001050/* parameters:
Fred Drakeff9ea482000-04-19 13:54:15 +00001051 * '(' [varargslist] ')'
Guido van Rossum3d602e31996-07-21 02:33:56 +00001052 *
1053 */
Guido van Rossum47478871996-08-21 14:32:37 +00001054static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001055validate_parameters(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001056{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001057 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001058 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001059
Guido van Rossum3d602e31996-07-21 02:33:56 +00001060 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001061 res = (validate_lparen(CHILD(tree, 0))
1062 && validate_rparen(CHILD(tree, nch - 1)));
1063 if (res && (nch == 3))
1064 res = validate_varargslist(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001065 }
Fred Drakeff9ea482000-04-19 13:54:15 +00001066 else {
1067 (void) validate_numnodes(tree, 2, "parameters");
1068 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001069 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001070}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001071
1072
Fred Drakecff283c2000-08-21 22:24:43 +00001073/* validate_suite()
Guido van Rossum3d602e31996-07-21 02:33:56 +00001074 *
1075 * suite:
Fred Drakeff9ea482000-04-19 13:54:15 +00001076 * simple_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00001077 * | NEWLINE INDENT stmt+ DEDENT
1078 */
Guido van Rossum47478871996-08-21 14:32:37 +00001079static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001080validate_suite(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001081{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001082 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001083 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001084
Guido van Rossum3d602e31996-07-21 02:33:56 +00001085 if (res && (nch == 1))
Fred Drakeff9ea482000-04-19 13:54:15 +00001086 res = validate_simple_stmt(CHILD(tree, 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001087 else if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001088 /* NEWLINE INDENT stmt+ DEDENT */
1089 res = (validate_newline(CHILD(tree, 0))
1090 && validate_indent(CHILD(tree, 1))
1091 && validate_stmt(CHILD(tree, 2))
1092 && validate_dedent(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001093
Fred Drakeff9ea482000-04-19 13:54:15 +00001094 if (res && (nch > 4)) {
1095 int i = 3;
1096 --nch; /* forget the DEDENT */
1097 for ( ; res && (i < nch); ++i)
1098 res = validate_stmt(CHILD(tree, i));
1099 }
1100 else if (nch < 4)
1101 res = validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001102 }
1103 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001104}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001105
1106
Guido van Rossum47478871996-08-21 14:32:37 +00001107static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001108validate_testlist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001109{
Guido van Rossum47478871996-08-21 14:32:37 +00001110 return (validate_repeating_list(tree, testlist,
Fred Drakeff9ea482000-04-19 13:54:15 +00001111 validate_test, "testlist"));
1112}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001113
1114
Fred Drakecff283c2000-08-21 22:24:43 +00001115/* '*' NAME [',' '**' NAME] | '**' NAME
1116 */
1117static int
1118validate_varargslist_trailer(node *tree, int start)
1119{
1120 int nch = NCH(tree);
1121 int res = 0;
1122 int sym;
1123
1124 if (nch <= start) {
1125 err_string("expected variable argument trailer for varargslist");
1126 return 0;
1127 }
1128 sym = TYPE(CHILD(tree, start));
1129 if (sym == STAR) {
1130 /*
1131 * ('*' NAME [',' '**' NAME]
1132 */
1133 if (nch-start == 2)
1134 res = validate_name(CHILD(tree, start+1), NULL);
1135 else if (nch-start == 5)
1136 res = (validate_name(CHILD(tree, start+1), NULL)
1137 && validate_comma(CHILD(tree, start+2))
1138 && validate_doublestar(CHILD(tree, start+3))
1139 && validate_name(CHILD(tree, start+4), NULL));
1140 }
1141 else if (sym == DOUBLESTAR) {
1142 /*
1143 * '**' NAME
1144 */
1145 if (nch-start == 2)
1146 res = validate_name(CHILD(tree, start+1), NULL);
1147 }
1148 if (!res)
1149 err_string("illegal variable argument trailer for varargslist");
1150 return res;
1151}
1152
1153
1154/* validate_varargslist()
Guido van Rossum3d602e31996-07-21 02:33:56 +00001155 *
1156 * varargslist:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001157 * (fpdef ['=' test] ',')*
Fred Drakecff283c2000-08-21 22:24:43 +00001158 * ('*' NAME [',' '**' NAME]
1159 * | '**' NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001160 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1161 *
1162 */
Guido van Rossum47478871996-08-21 14:32:37 +00001163static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001164validate_varargslist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001165{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001166 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001167 int res = validate_ntype(tree, varargslist) && (nch != 0);
Fred Drakecff283c2000-08-21 22:24:43 +00001168 int sym;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001169
Fred Drakecff283c2000-08-21 22:24:43 +00001170 if (nch < 1) {
1171 err_string("varargslist missing child nodes");
1172 return 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001173 }
Fred Drakecff283c2000-08-21 22:24:43 +00001174 sym = TYPE(CHILD(tree, 0));
1175 if (sym == STAR || sym == DOUBLESTAR)
1176 res = validate_varargslist_trailer(tree, 0);
1177 else if (sym == fpdef) {
1178 int i = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001179
Fred Drakecff283c2000-08-21 22:24:43 +00001180 sym = TYPE(CHILD(tree, nch-1));
1181 if (sym == NAME) {
1182 /*
1183 * (fpdef ['=' test] ',')+
1184 * ('*' NAME [',' '**' NAME]
1185 * | '**' NAME)
1186 */
1187 /* skip over (fpdef ['=' test] ',')+ */
1188 while (res && (i+2 <= nch)) {
1189 res = validate_fpdef(CHILD(tree, i));
1190 ++i;
1191 if (res && TYPE(CHILD(tree, i)) == EQUAL && (i+2 <= nch)) {
1192 res = (validate_equal(CHILD(tree, i))
1193 && validate_test(CHILD(tree, i+1)));
1194 if (res)
1195 i += 2;
Fred Drakeff9ea482000-04-19 13:54:15 +00001196 }
Fred Drakecff283c2000-08-21 22:24:43 +00001197 if (res && i < nch) {
1198 res = validate_comma(CHILD(tree, i));
1199 if (res)
1200 ++i;
1201 }
1202 }
1203 /* handle '*' NAME [',' '**' NAME] | '**' NAME */
1204 if (res)
1205 res = validate_varargslist_trailer(tree, i);
1206 }
1207 else {
1208 /*
1209 * fpdef ['=' test] (',' fpdef ['=' test])* [',']
1210 */
1211 if (sym == COMMA) {
1212 res = validate_comma(CHILD(tree, nch-1));
1213 if (!res)
1214 return 0;
1215 --nch;
1216 }
1217 /*
1218 * fpdef ['=' test] (',' fpdef ['=' test])*
1219 */
1220 res = validate_fpdef(CHILD(tree, 0));
1221 ++i;
1222 if (res && (i+2 < nch) && TYPE(CHILD(tree, 1)) == EQUAL) {
1223 res = (validate_equal(CHILD(tree, 1))
1224 && validate_test(CHILD(tree, 2)));
1225 i += 2;
1226 }
1227 /*
1228 * ... (',' fpdef ['=' test])*
1229 * i ---^^^
1230 */
1231 while (res && (nch - i) >= 2) {
1232 res = (validate_comma(CHILD(tree, i))
1233 && validate_fpdef(CHILD(tree, i+1)));
1234 i += 2;
1235 if (res && (nch - i) >= 2
1236 && TYPE(CHILD(tree, i)) == COMMA) {
1237 res = (validate_comma(CHILD(tree, i))
1238 && validate_test(CHILD(tree, i+1)));
1239 if (res)
1240 i += 2;
1241 }
1242 }
1243 if (res && nch - i != 0) {
1244 res = 0;
1245 err_string("illegal formation for varargslist");
Fred Drakeff9ea482000-04-19 13:54:15 +00001246 }
1247 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001248 }
Fred Drakecff283c2000-08-21 22:24:43 +00001249 return res;
Fred Drakeff9ea482000-04-19 13:54:15 +00001250}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001251
1252
Fred Drakecff283c2000-08-21 22:24:43 +00001253/* list_iter: list_for | list_if
1254 */
1255static int
1256validate_list_iter(node *tree)
1257{
1258 int res = (validate_ntype(tree, list_iter)
1259 && validate_numnodes(tree, 1, "list_iter"));
1260 if (res && TYPE(CHILD(tree, 0)) == list_for)
1261 res = validate_list_for(CHILD(tree, 0));
1262 else
1263 res = validate_list_if(CHILD(tree, 0));
1264
1265 return res;
1266}
1267
1268/* list_for: 'for' exprlist 'in' testlist [list_iter]
1269 */
1270static int
1271validate_list_for(node *tree)
1272{
1273 int nch = NCH(tree);
1274 int res;
1275
1276 if (nch == 5)
1277 res = validate_list_iter(CHILD(tree, 4));
1278 else
1279 res = validate_numnodes(tree, 4, "list_for");
1280
1281 if (res)
1282 res = (validate_name(CHILD(tree, 0), "for")
1283 && validate_exprlist(CHILD(tree, 1))
1284 && validate_name(CHILD(tree, 2), "in")
1285 && validate_testlist(CHILD(tree, 3)));
1286
1287 return res;
1288}
1289
1290/* list_if: 'if' test [list_iter]
1291 */
1292static int
1293validate_list_if(node *tree)
1294{
1295 int nch = NCH(tree);
1296 int res;
1297
1298 if (nch == 3)
1299 res = validate_list_iter(CHILD(tree, 2));
1300 else
1301 res = validate_numnodes(tree, 2, "list_if");
1302
1303 if (res)
1304 res = (validate_name(CHILD(tree, 0), "if")
1305 && validate_test(CHILD(tree, 1)));
1306
1307 return res;
1308}
1309
1310
1311/* validate_fpdef()
Guido van Rossum3d602e31996-07-21 02:33:56 +00001312 *
1313 * fpdef:
Fred Drakeff9ea482000-04-19 13:54:15 +00001314 * NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00001315 * | '(' fplist ')'
1316 */
Guido van Rossum47478871996-08-21 14:32:37 +00001317static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001318validate_fpdef(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001319{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001320 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001321 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001322
Guido van Rossum3d602e31996-07-21 02:33:56 +00001323 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001324 if (nch == 1)
1325 res = validate_ntype(CHILD(tree, 0), NAME);
1326 else if (nch == 3)
1327 res = (validate_lparen(CHILD(tree, 0))
1328 && validate_fplist(CHILD(tree, 1))
1329 && validate_rparen(CHILD(tree, 2)));
1330 else
1331 res = validate_numnodes(tree, 1, "fpdef");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001332 }
1333 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001334}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001335
1336
Guido van Rossum47478871996-08-21 14:32:37 +00001337static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001338validate_fplist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001339{
Guido van Rossum47478871996-08-21 14:32:37 +00001340 return (validate_repeating_list(tree, fplist,
Fred Drakeff9ea482000-04-19 13:54:15 +00001341 validate_fpdef, "fplist"));
1342}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001343
1344
Guido van Rossum3d602e31996-07-21 02:33:56 +00001345/* simple_stmt | compound_stmt
1346 *
1347 */
Guido van Rossum47478871996-08-21 14:32:37 +00001348static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001349validate_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001350{
1351 int res = (validate_ntype(tree, stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001352 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001353
Guido van Rossum3d602e31996-07-21 02:33:56 +00001354 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001355 tree = CHILD(tree, 0);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001356
Fred Drakeff9ea482000-04-19 13:54:15 +00001357 if (TYPE(tree) == simple_stmt)
1358 res = validate_simple_stmt(tree);
1359 else
1360 res = validate_compound_stmt(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001361 }
1362 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001363}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001364
1365
Guido van Rossum3d602e31996-07-21 02:33:56 +00001366/* small_stmt (';' small_stmt)* [';'] NEWLINE
1367 *
1368 */
Guido van Rossum47478871996-08-21 14:32:37 +00001369static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001370validate_simple_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001371{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001372 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001373 int res = (validate_ntype(tree, simple_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001374 && (nch >= 2)
1375 && validate_small_stmt(CHILD(tree, 0))
1376 && validate_newline(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001377
Guido van Rossum3d602e31996-07-21 02:33:56 +00001378 if (nch < 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001379 res = validate_numnodes(tree, 2, "simple_stmt");
1380 --nch; /* forget the NEWLINE */
Guido van Rossum3d602e31996-07-21 02:33:56 +00001381 if (res && is_even(nch))
Fred Drakeff9ea482000-04-19 13:54:15 +00001382 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001383 if (res && (nch > 2)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001384 int i;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001385
Fred Drakeff9ea482000-04-19 13:54:15 +00001386 for (i = 1; res && (i < nch); i += 2)
1387 res = (validate_semi(CHILD(tree, i))
1388 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001389 }
1390 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001391}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001392
1393
Guido van Rossum47478871996-08-21 14:32:37 +00001394static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001395validate_small_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001396{
1397 int nch = NCH(tree);
Fred Drakeff9ea482000-04-19 13:54:15 +00001398 int res = (validate_numnodes(tree, 1, "small_stmt")
1399 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1400 || (TYPE(CHILD(tree, 0)) == print_stmt)
1401 || (TYPE(CHILD(tree, 0)) == del_stmt)
1402 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1403 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1404 || (TYPE(CHILD(tree, 0)) == import_stmt)
1405 || (TYPE(CHILD(tree, 0)) == global_stmt)
1406 || (TYPE(CHILD(tree, 0)) == assert_stmt)
1407 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001408
1409 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001410 res = validate_node(CHILD(tree, 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001411 else if (nch == 1) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001412 char buffer[60];
1413 (void) sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1414 TYPE(CHILD(tree, 0)));
1415 err_string(buffer);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001416 }
1417 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001418}
Guido van Rossum3d602e31996-07-21 02:33:56 +00001419
1420
1421/* compound_stmt:
Fred Drakeff9ea482000-04-19 13:54:15 +00001422 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
Guido van Rossum3d602e31996-07-21 02:33:56 +00001423 */
Guido van Rossum47478871996-08-21 14:32:37 +00001424static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001425validate_compound_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001426{
1427 int res = (validate_ntype(tree, compound_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001428 && validate_numnodes(tree, 1, "compound_stmt"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001429
1430 if (!res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001431 return (0);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001432
1433 tree = CHILD(tree, 0);
1434 res = ((TYPE(tree) == if_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001435 || (TYPE(tree) == while_stmt)
1436 || (TYPE(tree) == for_stmt)
1437 || (TYPE(tree) == try_stmt)
1438 || (TYPE(tree) == funcdef)
1439 || (TYPE(tree) == classdef));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001440 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001441 res = validate_node(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001442 else {
Fred Drakeff9ea482000-04-19 13:54:15 +00001443 char buffer[60];
1444 (void) sprintf(buffer, "Illegal compound statement type: %d.",
1445 TYPE(tree));
1446 err_string(buffer);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001447 }
1448 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001449}
Guido van Rossum3d602e31996-07-21 02:33:56 +00001450
1451
Guido van Rossum47478871996-08-21 14:32:37 +00001452static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001453validate_expr_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001454{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001455 int j;
1456 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001457 int res = (validate_ntype(tree, expr_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001458 && is_odd(nch)
1459 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001460
Fred Drake28f739a2000-08-25 22:42:40 +00001461 if (res && nch == 3
1462 && TYPE(CHILD(tree, 1)) == augassign) {
1463 res = (validate_numnodes(CHILD(tree, 1), 1, "augassign")
1464 && validate_testlist(CHILD(tree, 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001465
Fred Drake28f739a2000-08-25 22:42:40 +00001466 if (res) {
1467 char *s = STR(CHILD(CHILD(tree, 1), 0));
1468
1469 res = (strcmp(s, "+=") == 0
1470 || strcmp(s, "-=") == 0
1471 || strcmp(s, "*=") == 0
1472 || strcmp(s, "/=") == 0
1473 || strcmp(s, "%=") == 0
1474 || strcmp(s, "&=") == 0
1475 || strcmp(s, "|=") == 0
1476 || strcmp(s, "^=") == 0
1477 || strcmp(s, "<<=") == 0
1478 || strcmp(s, ">>=") == 0
1479 || strcmp(s, "**=") == 0);
1480 if (!res)
1481 err_string("illegal augmmented assignment operator");
1482 }
1483 }
1484 else {
1485 for (j = 1; res && (j < nch); j += 2)
1486 res = (validate_equal(CHILD(tree, j))
1487 && validate_testlist(CHILD(tree, j + 1)));
1488 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001489 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001490}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001491
1492
Guido van Rossum3d602e31996-07-21 02:33:56 +00001493/* print_stmt:
1494 *
Fred Drakecff283c2000-08-21 22:24:43 +00001495 * 'print' ( [ test (',' test)* [','] ]
1496 * | '>>' test [ (',' test)+ [','] ] )
Guido van Rossum3d602e31996-07-21 02:33:56 +00001497 */
Guido van Rossum47478871996-08-21 14:32:37 +00001498static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001499validate_print_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001500{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001501 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001502 int res = (validate_ntype(tree, print_stmt)
Fred Drakecff283c2000-08-21 22:24:43 +00001503 && (nch > 0)
Fred Drakeff9ea482000-04-19 13:54:15 +00001504 && validate_name(CHILD(tree, 0), "print"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001505
Fred Drakecff283c2000-08-21 22:24:43 +00001506 if (res && nch > 1) {
1507 int sym = TYPE(CHILD(tree, 1));
1508 int i = 1;
1509 int allow_trailing_comma = 1;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001510
Fred Drakecff283c2000-08-21 22:24:43 +00001511 if (sym == test)
1512 res = validate_test(CHILD(tree, i++));
1513 else {
1514 if (nch < 3)
1515 res = validate_numnodes(tree, 3, "print_stmt");
1516 else {
1517 res = (validate_ntype(CHILD(tree, i), RIGHTSHIFT)
1518 && validate_test(CHILD(tree, i+1)));
1519 i += 2;
1520 allow_trailing_comma = 0;
1521 }
1522 }
1523 if (res) {
1524 /* ... (',' test)* [','] */
1525 while (res && i+2 <= nch) {
1526 res = (validate_comma(CHILD(tree, i))
1527 && validate_test(CHILD(tree, i+1)));
1528 allow_trailing_comma = 1;
1529 i += 2;
1530 }
1531 if (res && !allow_trailing_comma)
1532 res = validate_numnodes(tree, i, "print_stmt");
1533 else if (res && i < nch)
1534 res = validate_comma(CHILD(tree, i));
1535 }
1536 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001537 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001538}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001539
1540
Guido van Rossum47478871996-08-21 14:32:37 +00001541static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001542validate_del_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001543{
1544 return (validate_numnodes(tree, 2, "del_stmt")
Fred Drakeff9ea482000-04-19 13:54:15 +00001545 && validate_name(CHILD(tree, 0), "del")
1546 && validate_exprlist(CHILD(tree, 1)));
1547}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001548
1549
Guido van Rossum47478871996-08-21 14:32:37 +00001550static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001551validate_return_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001552{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001553 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001554 int res = (validate_ntype(tree, return_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001555 && ((nch == 1) || (nch == 2))
1556 && validate_name(CHILD(tree, 0), "return"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001557
Guido van Rossum3d602e31996-07-21 02:33:56 +00001558 if (res && (nch == 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00001559 res = validate_testlist(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001560
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001561 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001562}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001563
1564
Guido van Rossum47478871996-08-21 14:32:37 +00001565static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001566validate_raise_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001567{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001568 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001569 int res = (validate_ntype(tree, raise_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001570 && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001571
Guido van Rossum3d602e31996-07-21 02:33:56 +00001572 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001573 res = validate_name(CHILD(tree, 0), "raise");
1574 if (res && (nch >= 2))
1575 res = validate_test(CHILD(tree, 1));
1576 if (res && nch > 2) {
1577 res = (validate_comma(CHILD(tree, 2))
1578 && validate_test(CHILD(tree, 3)));
1579 if (res && (nch > 4))
1580 res = (validate_comma(CHILD(tree, 4))
1581 && validate_test(CHILD(tree, 5)));
1582 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001583 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001584 else
Fred Drakeff9ea482000-04-19 13:54:15 +00001585 (void) validate_numnodes(tree, 2, "raise");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001586 if (res && (nch == 4))
Fred Drakeff9ea482000-04-19 13:54:15 +00001587 res = (validate_comma(CHILD(tree, 2))
1588 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001589
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001590 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001591}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001592
1593
Fred Drakecff283c2000-08-21 22:24:43 +00001594static int
1595validate_import_as_name(node *tree)
1596{
1597 int nch = NCH(tree);
1598 int ok = validate_ntype(tree, import_as_name);
1599
1600 if (ok) {
1601 if (nch == 1)
1602 ok = validate_name(CHILD(tree, 0), NULL);
1603 else if (nch == 3)
1604 ok = (validate_name(CHILD(tree, 0), NULL)
1605 && validate_name(CHILD(tree, 1), "as")
1606 && validate_name(CHILD(tree, 2), NULL));
1607 else
1608 ok = validate_numnodes(tree, 3, "import_as_name");
1609 }
1610 return ok;
1611}
1612
1613
1614/* dotted_as_name: dotted_name [NAME NAME]
1615 */
1616static int
1617validate_dotted_as_name(node *tree)
1618{
1619 int nch = NCH(tree);
1620 int res = validate_ntype(tree, dotted_as_name);
1621
1622 if (res) {
1623 if (nch == 1)
1624 res = validate_ntype(CHILD(tree, 0), dotted_name);
1625 else if (nch == 3)
1626 res = (validate_ntype(CHILD(tree, 0), dotted_name)
1627 && validate_name(CHILD(tree, 1), "as")
1628 && validate_name(CHILD(tree, 2), NULL));
1629 else {
1630 res = 0;
1631 err_string("Illegal number of children for dotted_as_name.");
1632 }
1633 }
1634 return res;
1635}
1636
1637
Guido van Rossum3d602e31996-07-21 02:33:56 +00001638/* import_stmt:
1639 *
Fred Drakecff283c2000-08-21 22:24:43 +00001640 * 'import' dotted_as_name (',' dotted_as_name)*
1641 * | 'from' dotted_name 'import' ('*' | import_as_name (',' import_as_name)*)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001642 */
Guido van Rossum47478871996-08-21 14:32:37 +00001643static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001644validate_import_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001645{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001646 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001647 int res = (validate_ntype(tree, import_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001648 && (nch >= 2) && is_even(nch)
Fred Drakecff283c2000-08-21 22:24:43 +00001649 && validate_ntype(CHILD(tree, 0), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001650
1651 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001652 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001653
Fred Drakecff283c2000-08-21 22:24:43 +00001654 res = validate_dotted_as_name(CHILD(tree, 1));
Fred Drakeff9ea482000-04-19 13:54:15 +00001655 for (j = 2; res && (j < nch); j += 2)
1656 res = (validate_comma(CHILD(tree, j))
1657 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001658 }
Fred Drakecff283c2000-08-21 22:24:43 +00001659 else if (res && (res = validate_name(CHILD(tree, 0), "from"))) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001660 res = ((nch >= 4) && is_even(nch)
Fred Drakecff283c2000-08-21 22:24:43 +00001661 && validate_name(CHILD(tree, 2), "import")
1662 && validate_dotted_as_name(CHILD(tree, 1)));
Fred Drakeff9ea482000-04-19 13:54:15 +00001663 if (nch == 4) {
Fred Drakecff283c2000-08-21 22:24:43 +00001664 if (TYPE(CHILD(tree, 3)) == import_as_name)
1665 res = validate_import_as_name(CHILD(tree, 3));
1666 else
1667 res = validate_star(CHILD(tree, 3));
Fred Drakeff9ea482000-04-19 13:54:15 +00001668 }
1669 else {
Fred Drakecff283c2000-08-21 22:24:43 +00001670 /* 'from' dotted_name 'import' import_as_name
1671 * (',' import_as_name)+
1672 */
Fred Drakeff9ea482000-04-19 13:54:15 +00001673 int j;
Fred Drakecff283c2000-08-21 22:24:43 +00001674 res = validate_import_as_name(CHILD(tree, 3));
Fred Drakeff9ea482000-04-19 13:54:15 +00001675 for (j = 4; res && (j < nch); j += 2)
1676 res = (validate_comma(CHILD(tree, j))
Fred Drakecff283c2000-08-21 22:24:43 +00001677 && validate_import_as_name(CHILD(tree, j + 1)));
Fred Drakeff9ea482000-04-19 13:54:15 +00001678 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001679 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001680 else
Fred Drakeff9ea482000-04-19 13:54:15 +00001681 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001682
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001683 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001684}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001685
1686
Guido van Rossum47478871996-08-21 14:32:37 +00001687static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001688validate_global_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001689{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001690 int j;
1691 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001692 int res = (validate_ntype(tree, global_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001693 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001694
Guido van Rossum3d602e31996-07-21 02:33:56 +00001695 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001696 res = (validate_name(CHILD(tree, 0), "global")
1697 && validate_ntype(CHILD(tree, 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001698 for (j = 2; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001699 res = (validate_comma(CHILD(tree, j))
1700 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001701
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001702 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001703}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001704
1705
Guido van Rossum3d602e31996-07-21 02:33:56 +00001706/* exec_stmt:
1707 *
1708 * 'exec' expr ['in' test [',' test]]
1709 */
Guido van Rossum47478871996-08-21 14:32:37 +00001710static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001711validate_exec_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001712{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001713 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001714 int res = (validate_ntype(tree, exec_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001715 && ((nch == 2) || (nch == 4) || (nch == 6))
1716 && validate_name(CHILD(tree, 0), "exec")
1717 && validate_expr(CHILD(tree, 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001718
Guido van Rossum3d602e31996-07-21 02:33:56 +00001719 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00001720 err_string("Illegal exec statement.");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001721 if (res && (nch > 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00001722 res = (validate_name(CHILD(tree, 2), "in")
1723 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001724 if (res && (nch == 6))
Fred Drakeff9ea482000-04-19 13:54:15 +00001725 res = (validate_comma(CHILD(tree, 4))
1726 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001727
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001728 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001729}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001730
1731
Guido van Rossum925e5471997-04-02 05:32:13 +00001732/* assert_stmt:
1733 *
1734 * 'assert' test [',' test]
1735 */
1736static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001737validate_assert_stmt(node *tree)
Guido van Rossum925e5471997-04-02 05:32:13 +00001738{
1739 int nch = NCH(tree);
1740 int res = (validate_ntype(tree, assert_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001741 && ((nch == 2) || (nch == 4))
1742 && (validate_name(CHILD(tree, 0), "__assert__") ||
1743 validate_name(CHILD(tree, 0), "assert"))
1744 && validate_test(CHILD(tree, 1)));
Guido van Rossum925e5471997-04-02 05:32:13 +00001745
1746 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00001747 err_string("Illegal assert statement.");
Guido van Rossum925e5471997-04-02 05:32:13 +00001748 if (res && (nch > 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00001749 res = (validate_comma(CHILD(tree, 2))
1750 && validate_test(CHILD(tree, 3)));
Guido van Rossum925e5471997-04-02 05:32:13 +00001751
1752 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001753}
Guido van Rossum925e5471997-04-02 05:32:13 +00001754
1755
Guido van Rossum47478871996-08-21 14:32:37 +00001756static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001757validate_while(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001758{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001759 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001760 int res = (validate_ntype(tree, while_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001761 && ((nch == 4) || (nch == 7))
1762 && validate_name(CHILD(tree, 0), "while")
1763 && validate_test(CHILD(tree, 1))
1764 && validate_colon(CHILD(tree, 2))
1765 && validate_suite(CHILD(tree, 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001766
Guido van Rossum3d602e31996-07-21 02:33:56 +00001767 if (res && (nch == 7))
Fred Drakeff9ea482000-04-19 13:54:15 +00001768 res = (validate_name(CHILD(tree, 4), "else")
1769 && validate_colon(CHILD(tree, 5))
1770 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001771
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001772 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001773}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001774
1775
Guido van Rossum47478871996-08-21 14:32:37 +00001776static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001777validate_for(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001778{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001779 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001780 int res = (validate_ntype(tree, for_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001781 && ((nch == 6) || (nch == 9))
1782 && validate_name(CHILD(tree, 0), "for")
1783 && validate_exprlist(CHILD(tree, 1))
1784 && validate_name(CHILD(tree, 2), "in")
1785 && validate_testlist(CHILD(tree, 3))
1786 && validate_colon(CHILD(tree, 4))
1787 && validate_suite(CHILD(tree, 5)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001788
Guido van Rossum3d602e31996-07-21 02:33:56 +00001789 if (res && (nch == 9))
Fred Drakeff9ea482000-04-19 13:54:15 +00001790 res = (validate_name(CHILD(tree, 6), "else")
1791 && validate_colon(CHILD(tree, 7))
1792 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001793
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001794 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001795}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001796
1797
Guido van Rossum3d602e31996-07-21 02:33:56 +00001798/* try_stmt:
Fred Drakeff9ea482000-04-19 13:54:15 +00001799 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001800 * | 'try' ':' suite 'finally' ':' suite
1801 *
1802 */
Guido van Rossum47478871996-08-21 14:32:37 +00001803static int
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +00001804validate_try(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001805{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001806 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001807 int pos = 3;
1808 int res = (validate_ntype(tree, try_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001809 && (nch >= 6) && ((nch % 3) == 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001810
1811 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001812 res = (validate_name(CHILD(tree, 0), "try")
1813 && validate_colon(CHILD(tree, 1))
1814 && validate_suite(CHILD(tree, 2))
1815 && validate_colon(CHILD(tree, nch - 2))
1816 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001817 else {
Fred Drake22269b52000-07-03 18:07:43 +00001818 const char* name = "except";
Fred Drakeff9ea482000-04-19 13:54:15 +00001819 char buffer[60];
1820 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1821 name = STR(CHILD(tree, nch - 3));
1822 (void) sprintf(buffer,
1823 "Illegal number of children for try/%s node.", name);
1824 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001825 }
Fred Drakeff9ea482000-04-19 13:54:15 +00001826 /* Skip past except_clause sections: */
Guido van Rossum3d602e31996-07-21 02:33:56 +00001827 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001828 res = (validate_except_clause(CHILD(tree, pos))
1829 && validate_colon(CHILD(tree, pos + 1))
1830 && validate_suite(CHILD(tree, pos + 2)));
1831 pos += 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001832 }
1833 if (res && (pos < nch)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001834 res = validate_ntype(CHILD(tree, pos), NAME);
1835 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1836 res = (validate_numnodes(tree, 6, "try/finally")
1837 && validate_colon(CHILD(tree, 4))
1838 && validate_suite(CHILD(tree, 5)));
1839 else if (res) {
1840 if (nch == (pos + 3)) {
1841 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1842 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1843 if (!res)
1844 err_string("Illegal trailing triple in try statement.");
1845 }
1846 else if (nch == (pos + 6)) {
1847 res = (validate_name(CHILD(tree, pos), "except")
1848 && validate_colon(CHILD(tree, pos + 1))
1849 && validate_suite(CHILD(tree, pos + 2))
1850 && validate_name(CHILD(tree, pos + 3), "else"));
1851 }
1852 else
1853 res = validate_numnodes(tree, pos + 3, "try/except");
1854 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001855 }
1856 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001857}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001858
1859
Guido van Rossum47478871996-08-21 14:32:37 +00001860static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001861validate_except_clause(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001862{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001863 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001864 int res = (validate_ntype(tree, except_clause)
Fred Drakeff9ea482000-04-19 13:54:15 +00001865 && ((nch == 1) || (nch == 2) || (nch == 4))
1866 && validate_name(CHILD(tree, 0), "except"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001867
Guido van Rossum3d602e31996-07-21 02:33:56 +00001868 if (res && (nch > 1))
Fred Drakeff9ea482000-04-19 13:54:15 +00001869 res = validate_test(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001870 if (res && (nch == 4))
Fred Drakeff9ea482000-04-19 13:54:15 +00001871 res = (validate_comma(CHILD(tree, 2))
1872 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001873
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001874 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001875}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001876
1877
Guido van Rossum47478871996-08-21 14:32:37 +00001878static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001879validate_test(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001880{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001881 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001882 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001883
Guido van Rossum3d602e31996-07-21 02:33:56 +00001884 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Fred Drakeff9ea482000-04-19 13:54:15 +00001885 res = ((nch == 1)
1886 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001887 else if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001888 int pos;
1889 res = validate_and_test(CHILD(tree, 0));
1890 for (pos = 1; res && (pos < nch); pos += 2)
1891 res = (validate_name(CHILD(tree, pos), "or")
1892 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001893 }
1894 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001895}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001896
1897
Guido van Rossum47478871996-08-21 14:32:37 +00001898static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001899validate_and_test(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001900{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001901 int pos;
1902 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001903 int res = (validate_ntype(tree, and_test)
Fred Drakeff9ea482000-04-19 13:54:15 +00001904 && is_odd(nch)
1905 && validate_not_test(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001906
Guido van Rossum3d602e31996-07-21 02:33:56 +00001907 for (pos = 1; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001908 res = (validate_name(CHILD(tree, pos), "and")
1909 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001910
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001911 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001912}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001913
1914
Guido van Rossum47478871996-08-21 14:32:37 +00001915static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001916validate_not_test(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001917{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001918 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001919 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001920
Guido van Rossum3d602e31996-07-21 02:33:56 +00001921 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001922 if (nch == 2)
1923 res = (validate_name(CHILD(tree, 0), "not")
1924 && validate_not_test(CHILD(tree, 1)));
1925 else if (nch == 1)
1926 res = validate_comparison(CHILD(tree, 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001927 }
1928 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001929}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001930
1931
Guido van Rossum47478871996-08-21 14:32:37 +00001932static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001933validate_comparison(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001934{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001935 int pos;
1936 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001937 int res = (validate_ntype(tree, comparison)
Fred Drakeff9ea482000-04-19 13:54:15 +00001938 && is_odd(nch)
1939 && validate_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001940
Guido van Rossum3d602e31996-07-21 02:33:56 +00001941 for (pos = 1; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001942 res = (validate_comp_op(CHILD(tree, pos))
1943 && validate_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001944
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001945 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001946}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001947
1948
Guido van Rossum47478871996-08-21 14:32:37 +00001949static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001950validate_comp_op(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001951{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001952 int res = 0;
1953 int nch = NCH(tree);
1954
Guido van Rossum3d602e31996-07-21 02:33:56 +00001955 if (!validate_ntype(tree, comp_op))
Fred Drakeff9ea482000-04-19 13:54:15 +00001956 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001957 if (nch == 1) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001958 /*
1959 * Only child will be a terminal with a well-defined symbolic name
1960 * or a NAME with a string of either 'is' or 'in'
1961 */
1962 tree = CHILD(tree, 0);
1963 switch (TYPE(tree)) {
1964 case LESS:
1965 case GREATER:
1966 case EQEQUAL:
1967 case EQUAL:
1968 case LESSEQUAL:
1969 case GREATEREQUAL:
1970 case NOTEQUAL:
1971 res = 1;
1972 break;
1973 case NAME:
1974 res = ((strcmp(STR(tree), "in") == 0)
1975 || (strcmp(STR(tree), "is") == 0));
1976 if (!res) {
1977 char buff[128];
1978 (void) sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1979 err_string(buff);
1980 }
1981 break;
1982 default:
1983 err_string("Illegal comparison operator type.");
1984 break;
1985 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001986 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001987 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001988 res = (validate_ntype(CHILD(tree, 0), NAME)
1989 && validate_ntype(CHILD(tree, 1), NAME)
1990 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1991 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1992 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1993 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
1994 if (!res && !PyErr_Occurred())
1995 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001996 }
1997 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001998}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001999
2000
Guido van Rossum47478871996-08-21 14:32:37 +00002001static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002002validate_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002003{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002004 int j;
2005 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002006 int res = (validate_ntype(tree, expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00002007 && is_odd(nch)
2008 && validate_xor_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002009
Guido van Rossum3d602e31996-07-21 02:33:56 +00002010 for (j = 2; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00002011 res = (validate_xor_expr(CHILD(tree, j))
2012 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002013
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002014 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002015}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002016
2017
Guido van Rossum47478871996-08-21 14:32:37 +00002018static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002019validate_xor_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002020{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002021 int j;
2022 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002023 int res = (validate_ntype(tree, xor_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00002024 && is_odd(nch)
2025 && validate_and_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002026
Guido van Rossum3d602e31996-07-21 02:33:56 +00002027 for (j = 2; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00002028 res = (validate_circumflex(CHILD(tree, j - 1))
2029 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002030
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002031 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002032}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002033
2034
Guido van Rossum47478871996-08-21 14:32:37 +00002035static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002036validate_and_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002037{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002038 int pos;
2039 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002040 int res = (validate_ntype(tree, and_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00002041 && is_odd(nch)
2042 && validate_shift_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002043
Guido van Rossum3d602e31996-07-21 02:33:56 +00002044 for (pos = 1; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00002045 res = (validate_ampersand(CHILD(tree, pos))
2046 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002047
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002048 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002049}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002050
2051
2052static int
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +00002053validate_chain_two_ops(node *tree, int (*termvalid)(node *), int op1, int op2)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002054 {
2055 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002056 int nch = NCH(tree);
2057 int res = (is_odd(nch)
Fred Drakeff9ea482000-04-19 13:54:15 +00002058 && (*termvalid)(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002059
Guido van Rossum3d602e31996-07-21 02:33:56 +00002060 for ( ; res && (pos < nch); pos += 2) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002061 if (TYPE(CHILD(tree, pos)) != op1)
2062 res = validate_ntype(CHILD(tree, pos), op2);
2063 if (res)
2064 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002065 }
2066 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002067}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002068
2069
Guido van Rossum47478871996-08-21 14:32:37 +00002070static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002071validate_shift_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002072{
2073 return (validate_ntype(tree, shift_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00002074 && validate_chain_two_ops(tree, validate_arith_expr,
2075 LEFTSHIFT, RIGHTSHIFT));
2076}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002077
2078
Guido van Rossum47478871996-08-21 14:32:37 +00002079static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002080validate_arith_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002081{
2082 return (validate_ntype(tree, arith_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00002083 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
2084}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002085
2086
Guido van Rossum47478871996-08-21 14:32:37 +00002087static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002088validate_term(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002089{
2090 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002091 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002092 int res = (validate_ntype(tree, term)
Fred Drakeff9ea482000-04-19 13:54:15 +00002093 && is_odd(nch)
2094 && validate_factor(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002095
Guido van Rossum3d602e31996-07-21 02:33:56 +00002096 for ( ; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00002097 res = (((TYPE(CHILD(tree, pos)) == STAR)
2098 || (TYPE(CHILD(tree, pos)) == SLASH)
2099 || (TYPE(CHILD(tree, pos)) == PERCENT))
2100 && validate_factor(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002101
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002102 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002103}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002104
2105
Guido van Rossum3d602e31996-07-21 02:33:56 +00002106/* factor:
2107 *
2108 * factor: ('+'|'-'|'~') factor | power
2109 */
Guido van Rossum47478871996-08-21 14:32:37 +00002110static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002111validate_factor(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002112{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002113 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002114 int res = (validate_ntype(tree, factor)
Fred Drakeff9ea482000-04-19 13:54:15 +00002115 && (((nch == 2)
2116 && ((TYPE(CHILD(tree, 0)) == PLUS)
2117 || (TYPE(CHILD(tree, 0)) == MINUS)
2118 || (TYPE(CHILD(tree, 0)) == TILDE))
2119 && validate_factor(CHILD(tree, 1)))
2120 || ((nch == 1)
2121 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002122 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002123}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002124
2125
Guido van Rossum3d602e31996-07-21 02:33:56 +00002126/* power:
2127 *
2128 * power: atom trailer* ('**' factor)*
2129 */
Guido van Rossum47478871996-08-21 14:32:37 +00002130static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002131validate_power(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002132{
2133 int pos = 1;
2134 int nch = NCH(tree);
2135 int res = (validate_ntype(tree, power) && (nch >= 1)
Fred Drakeff9ea482000-04-19 13:54:15 +00002136 && validate_atom(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002137
2138 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
Fred Drakeff9ea482000-04-19 13:54:15 +00002139 res = validate_trailer(CHILD(tree, pos++));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002140 if (res && (pos < nch)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002141 if (!is_even(nch - pos)) {
2142 err_string("Illegal number of nodes for 'power'.");
2143 return (0);
2144 }
2145 for ( ; res && (pos < (nch - 1)); pos += 2)
2146 res = (validate_doublestar(CHILD(tree, pos))
2147 && validate_factor(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002148 }
2149 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002150}
Guido van Rossum3d602e31996-07-21 02:33:56 +00002151
2152
Guido van Rossum47478871996-08-21 14:32:37 +00002153static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002154validate_atom(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002155{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002156 int pos;
2157 int nch = NCH(tree);
Fred Drakecff283c2000-08-21 22:24:43 +00002158 int res = validate_ntype(tree, atom);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002159
Fred Drakecff283c2000-08-21 22:24:43 +00002160 if (res && nch < 1)
2161 res = validate_numnodes(tree, nch+1, "atom");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002162 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002163 switch (TYPE(CHILD(tree, 0))) {
2164 case LPAR:
2165 res = ((nch <= 3)
2166 && (validate_rparen(CHILD(tree, nch - 1))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002167
Fred Drakeff9ea482000-04-19 13:54:15 +00002168 if (res && (nch == 3))
2169 res = validate_testlist(CHILD(tree, 1));
2170 break;
2171 case LSQB:
Fred Drakecff283c2000-08-21 22:24:43 +00002172 if (nch == 2)
2173 res = validate_ntype(CHILD(tree, 1), RSQB);
2174 else if (nch == 3)
2175 res = (validate_listmaker(CHILD(tree, 1))
2176 && validate_ntype(CHILD(tree, 2), RSQB));
2177 else {
2178 res = 0;
2179 err_string("illegal list display atom");
2180 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002181 break;
2182 case LBRACE:
2183 res = ((nch <= 3)
2184 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002185
Fred Drakeff9ea482000-04-19 13:54:15 +00002186 if (res && (nch == 3))
2187 res = validate_dictmaker(CHILD(tree, 1));
2188 break;
2189 case BACKQUOTE:
2190 res = ((nch == 3)
2191 && validate_testlist(CHILD(tree, 1))
2192 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2193 break;
2194 case NAME:
2195 case NUMBER:
2196 res = (nch == 1);
2197 break;
2198 case STRING:
2199 for (pos = 1; res && (pos < nch); ++pos)
2200 res = validate_ntype(CHILD(tree, pos), STRING);
2201 break;
2202 default:
2203 res = 0;
2204 break;
2205 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002206 }
2207 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002208}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002209
2210
Fred Drake85bf3bb2000-08-23 15:35:26 +00002211/* listmaker:
2212 * test ( list_for | (',' test)* [','] )
2213 */
Fred Drakecff283c2000-08-21 22:24:43 +00002214static int
2215validate_listmaker(node *tree)
2216{
2217 int nch = NCH(tree);
2218 int ok = nch;
2219
2220 if (nch == 0)
2221 err_string("missing child nodes of listmaker");
2222 else
2223 ok = validate_test(CHILD(tree, 0));
2224
2225 /*
2226 * list_iter | (',' test)* [',']
2227 */
Fred Drake85bf3bb2000-08-23 15:35:26 +00002228 if (nch == 2 && TYPE(CHILD(tree, 1)) == list_for)
2229 ok = validate_list_for(CHILD(tree, 1));
Fred Drakecff283c2000-08-21 22:24:43 +00002230 else {
2231 /* (',' test)* [','] */
2232 int i = 1;
2233 while (ok && nch - i >= 2) {
2234 ok = (validate_comma(CHILD(tree, i))
2235 && validate_test(CHILD(tree, i+1)));
Fred Drake85bf3bb2000-08-23 15:35:26 +00002236 i += 2;
Fred Drakecff283c2000-08-21 22:24:43 +00002237 }
Fred Drake85bf3bb2000-08-23 15:35:26 +00002238 if (ok && i == nch-1)
2239 ok = validate_comma(CHILD(tree, i));
2240 else if (i != nch) {
2241 ok = 0;
2242 err_string("illegal trailing nodes for listmaker");
2243 }
Fred Drakecff283c2000-08-21 22:24:43 +00002244 }
2245 return ok;
2246}
2247
2248
Guido van Rossum3d602e31996-07-21 02:33:56 +00002249/* funcdef:
Fred Drakeff9ea482000-04-19 13:54:15 +00002250 * 'def' NAME parameters ':' suite
Guido van Rossum3d602e31996-07-21 02:33:56 +00002251 *
2252 */
Guido van Rossum47478871996-08-21 14:32:37 +00002253static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002254validate_funcdef(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002255{
2256 return (validate_ntype(tree, funcdef)
Fred Drakeff9ea482000-04-19 13:54:15 +00002257 && validate_numnodes(tree, 5, "funcdef")
2258 && validate_name(CHILD(tree, 0), "def")
2259 && validate_ntype(CHILD(tree, 1), NAME)
2260 && validate_colon(CHILD(tree, 3))
2261 && validate_parameters(CHILD(tree, 2))
2262 && validate_suite(CHILD(tree, 4)));
2263}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002264
2265
Guido van Rossum47478871996-08-21 14:32:37 +00002266static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002267validate_lambdef(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002268{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002269 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002270 int res = (validate_ntype(tree, lambdef)
Fred Drakeff9ea482000-04-19 13:54:15 +00002271 && ((nch == 3) || (nch == 4))
2272 && validate_name(CHILD(tree, 0), "lambda")
2273 && validate_colon(CHILD(tree, nch - 2))
2274 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002275
Guido van Rossum3d602e31996-07-21 02:33:56 +00002276 if (res && (nch == 4))
Fred Drakeff9ea482000-04-19 13:54:15 +00002277 res = validate_varargslist(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002278 else if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00002279 (void) validate_numnodes(tree, 3, "lambdef");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002280
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002281 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002282}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002283
2284
Guido van Rossum3d602e31996-07-21 02:33:56 +00002285/* arglist:
2286 *
Fred Drakecff283c2000-08-21 22:24:43 +00002287 * (argument ',')* (argument [','] | '*' test [',' '**' test] | '**' test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002288 */
Guido van Rossum47478871996-08-21 14:32:37 +00002289static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002290validate_arglist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002291{
Fred Drakee7ab64e2000-04-25 04:14:46 +00002292 int nch = NCH(tree);
Fred Drakecff283c2000-08-21 22:24:43 +00002293 int i = 0;
2294 int ok = 1;
Fred Drakee7ab64e2000-04-25 04:14:46 +00002295
2296 if (nch <= 0)
2297 /* raise the right error from having an invalid number of children */
2298 return validate_numnodes(tree, nch + 1, "arglist");
2299
Fred Drakecff283c2000-08-21 22:24:43 +00002300 while (ok && nch-i >= 2) {
2301 /* skip leading (argument ',') */
2302 ok = (validate_argument(CHILD(tree, i))
2303 && validate_comma(CHILD(tree, i+1)));
2304 if (ok)
2305 i += 2;
2306 else
2307 PyErr_Clear();
2308 }
2309 ok = 1;
2310 if (nch-i > 0) {
2311 /*
2312 * argument | '*' test [',' '**' test] | '**' test
Fred Drakee7ab64e2000-04-25 04:14:46 +00002313 */
Fred Drakecff283c2000-08-21 22:24:43 +00002314 int sym = TYPE(CHILD(tree, i));
2315
2316 if (sym == argument) {
2317 ok = validate_argument(CHILD(tree, i));
2318 if (ok && i+1 != nch) {
2319 err_string("illegal arglist specification"
2320 " (extra stuff on end)");
2321 ok = 0;
Fred Drakee7ab64e2000-04-25 04:14:46 +00002322 }
Fred Drakecff283c2000-08-21 22:24:43 +00002323 }
2324 else if (sym == STAR) {
2325 ok = validate_star(CHILD(tree, i));
2326 if (ok && (nch-i == 2))
2327 ok = validate_test(CHILD(tree, i+1));
2328 else if (ok && (nch-i == 5))
2329 ok = (validate_test(CHILD(tree, i+1))
2330 && validate_comma(CHILD(tree, i+2))
2331 && validate_doublestar(CHILD(tree, i+3))
2332 && validate_test(CHILD(tree, i+4)));
Fred Drakee7ab64e2000-04-25 04:14:46 +00002333 else {
Fred Drakecff283c2000-08-21 22:24:43 +00002334 err_string("illegal use of '*' in arglist");
2335 ok = 0;
Fred Drakee7ab64e2000-04-25 04:14:46 +00002336 }
2337 }
Fred Drakecff283c2000-08-21 22:24:43 +00002338 else if (sym == DOUBLESTAR) {
2339 if (nch-i == 2)
2340 ok = (validate_doublestar(CHILD(tree, i))
2341 && validate_test(CHILD(tree, i+1)));
2342 else {
2343 err_string("illegal use of '**' in arglist");
2344 ok = 0;
2345 }
2346 }
2347 else {
2348 err_string("illegal arglist specification");
2349 ok = 0;
2350 }
Fred Drakee7ab64e2000-04-25 04:14:46 +00002351 }
2352 return (ok);
Fred Drakeff9ea482000-04-19 13:54:15 +00002353}
Guido van Rossum3d602e31996-07-21 02:33:56 +00002354
2355
2356
2357/* argument:
2358 *
2359 * [test '='] test
2360 */
Guido van Rossum47478871996-08-21 14:32:37 +00002361static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002362validate_argument(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002363{
2364 int nch = NCH(tree);
2365 int res = (validate_ntype(tree, argument)
Fred Drakeff9ea482000-04-19 13:54:15 +00002366 && ((nch == 1) || (nch == 3))
2367 && validate_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002368
2369 if (res && (nch == 3))
Fred Drakeff9ea482000-04-19 13:54:15 +00002370 res = (validate_equal(CHILD(tree, 1))
2371 && validate_test(CHILD(tree, 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002372
2373 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002374}
Guido van Rossum3d602e31996-07-21 02:33:56 +00002375
2376
2377
2378/* trailer:
2379 *
Guido van Rossum47478871996-08-21 14:32:37 +00002380 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002381 */
Guido van Rossum47478871996-08-21 14:32:37 +00002382static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002383validate_trailer(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002384{
2385 int nch = NCH(tree);
2386 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002387
2388 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002389 switch (TYPE(CHILD(tree, 0))) {
2390 case LPAR:
2391 res = validate_rparen(CHILD(tree, nch - 1));
2392 if (res && (nch == 3))
2393 res = validate_arglist(CHILD(tree, 1));
2394 break;
2395 case LSQB:
2396 res = (validate_numnodes(tree, 3, "trailer")
2397 && validate_subscriptlist(CHILD(tree, 1))
2398 && validate_ntype(CHILD(tree, 2), RSQB));
2399 break;
2400 case DOT:
2401 res = (validate_numnodes(tree, 2, "trailer")
2402 && validate_ntype(CHILD(tree, 1), NAME));
2403 break;
2404 default:
2405 res = 0;
2406 break;
2407 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002408 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002409 else {
2410 (void) validate_numnodes(tree, 2, "trailer");
2411 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002412 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002413}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002414
2415
Guido van Rossum47478871996-08-21 14:32:37 +00002416/* subscriptlist:
2417 *
2418 * subscript (',' subscript)* [',']
2419 */
2420static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002421validate_subscriptlist(node *tree)
Guido van Rossum47478871996-08-21 14:32:37 +00002422{
2423 return (validate_repeating_list(tree, subscriptlist,
Fred Drakeff9ea482000-04-19 13:54:15 +00002424 validate_subscript, "subscriptlist"));
2425}
Guido van Rossum47478871996-08-21 14:32:37 +00002426
2427
Guido van Rossum3d602e31996-07-21 02:33:56 +00002428/* subscript:
2429 *
Guido van Rossum47478871996-08-21 14:32:37 +00002430 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002431 */
Guido van Rossum47478871996-08-21 14:32:37 +00002432static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002433validate_subscript(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002434{
Guido van Rossum47478871996-08-21 14:32:37 +00002435 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002436 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002437 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002438
Guido van Rossum47478871996-08-21 14:32:37 +00002439 if (!res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002440 if (!PyErr_Occurred())
2441 err_string("invalid number of arguments for subscript node");
2442 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002443 }
Guido van Rossum47478871996-08-21 14:32:37 +00002444 if (TYPE(CHILD(tree, 0)) == DOT)
Fred Drakeff9ea482000-04-19 13:54:15 +00002445 /* take care of ('.' '.' '.') possibility */
2446 return (validate_numnodes(tree, 3, "subscript")
2447 && validate_dot(CHILD(tree, 0))
2448 && validate_dot(CHILD(tree, 1))
2449 && validate_dot(CHILD(tree, 2)));
Guido van Rossum47478871996-08-21 14:32:37 +00002450 if (nch == 1) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002451 if (TYPE(CHILD(tree, 0)) == test)
2452 res = validate_test(CHILD(tree, 0));
2453 else
2454 res = validate_colon(CHILD(tree, 0));
2455 return (res);
Guido van Rossum47478871996-08-21 14:32:37 +00002456 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002457 /* Must be [test] ':' [test] [sliceop],
2458 * but at least one of the optional components will
2459 * be present, but we don't know which yet.
Guido van Rossum47478871996-08-21 14:32:37 +00002460 */
2461 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002462 res = validate_test(CHILD(tree, 0));
2463 offset = 1;
Guido van Rossum47478871996-08-21 14:32:37 +00002464 }
2465 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00002466 res = validate_colon(CHILD(tree, offset));
Guido van Rossum47478871996-08-21 14:32:37 +00002467 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002468 int rem = nch - ++offset;
2469 if (rem) {
2470 if (TYPE(CHILD(tree, offset)) == test) {
2471 res = validate_test(CHILD(tree, offset));
2472 ++offset;
2473 --rem;
2474 }
2475 if (res && rem)
2476 res = validate_sliceop(CHILD(tree, offset));
2477 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002478 }
2479 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002480}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002481
2482
Guido van Rossum47478871996-08-21 14:32:37 +00002483static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002484validate_sliceop(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002485{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002486 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002487 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
Fred Drakeff9ea482000-04-19 13:54:15 +00002488 && validate_ntype(tree, sliceop);
Guido van Rossum47478871996-08-21 14:32:37 +00002489 if (!res && !PyErr_Occurred()) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002490 res = validate_numnodes(tree, 1, "sliceop");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002491 }
Guido van Rossum47478871996-08-21 14:32:37 +00002492 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00002493 res = validate_colon(CHILD(tree, 0));
Guido van Rossum47478871996-08-21 14:32:37 +00002494 if (res && (nch == 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00002495 res = validate_test(CHILD(tree, 1));
Guido van Rossum47478871996-08-21 14:32:37 +00002496
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002497 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002498}
Guido van Rossum47478871996-08-21 14:32:37 +00002499
2500
2501static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002502validate_exprlist(node *tree)
Guido van Rossum47478871996-08-21 14:32:37 +00002503{
2504 return (validate_repeating_list(tree, exprlist,
Fred Drakeff9ea482000-04-19 13:54:15 +00002505 validate_expr, "exprlist"));
2506}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002507
2508
Guido van Rossum47478871996-08-21 14:32:37 +00002509static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002510validate_dictmaker(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002511{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002512 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002513 int res = (validate_ntype(tree, dictmaker)
Fred Drakeff9ea482000-04-19 13:54:15 +00002514 && (nch >= 3)
2515 && validate_test(CHILD(tree, 0))
2516 && validate_colon(CHILD(tree, 1))
2517 && validate_test(CHILD(tree, 2)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002518
Guido van Rossum3d602e31996-07-21 02:33:56 +00002519 if (res && ((nch % 4) == 0))
Fred Drakeff9ea482000-04-19 13:54:15 +00002520 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002521 else if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00002522 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002523
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002524 if (res && (nch > 3)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002525 int pos = 3;
2526 /* ( ',' test ':' test )* */
2527 while (res && (pos < nch)) {
2528 res = (validate_comma(CHILD(tree, pos))
2529 && validate_test(CHILD(tree, pos + 1))
2530 && validate_colon(CHILD(tree, pos + 2))
2531 && validate_test(CHILD(tree, pos + 3)));
2532 pos += 4;
2533 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002534 }
2535 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002536}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002537
2538
Guido van Rossum47478871996-08-21 14:32:37 +00002539static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002540validate_eval_input(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002541{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002542 int pos;
2543 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002544 int res = (validate_ntype(tree, eval_input)
Fred Drakeff9ea482000-04-19 13:54:15 +00002545 && (nch >= 2)
2546 && validate_testlist(CHILD(tree, 0))
2547 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002548
Guido van Rossum3d602e31996-07-21 02:33:56 +00002549 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Fred Drakeff9ea482000-04-19 13:54:15 +00002550 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002551
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002552 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002553}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002554
2555
Guido van Rossum47478871996-08-21 14:32:37 +00002556static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002557validate_node(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002558{
Fred Drakeff9ea482000-04-19 13:54:15 +00002559 int nch = 0; /* num. children on current node */
2560 int res = 1; /* result value */
2561 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002562
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002563 while (res & (tree != 0)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002564 nch = NCH(tree);
2565 next = 0;
2566 switch (TYPE(tree)) {
2567 /*
2568 * Definition nodes.
2569 */
2570 case funcdef:
2571 res = validate_funcdef(tree);
2572 break;
2573 case classdef:
2574 res = validate_class(tree);
2575 break;
2576 /*
2577 * "Trivial" parse tree nodes.
2578 * (Why did I call these trivial?)
2579 */
2580 case stmt:
2581 res = validate_stmt(tree);
2582 break;
2583 case small_stmt:
2584 /*
2585 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
2586 * | import_stmt | global_stmt | exec_stmt | assert_stmt
2587 */
2588 res = validate_small_stmt(tree);
2589 break;
2590 case flow_stmt:
2591 res = (validate_numnodes(tree, 1, "flow_stmt")
2592 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2593 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2594 || (TYPE(CHILD(tree, 0)) == return_stmt)
2595 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2596 if (res)
2597 next = CHILD(tree, 0);
2598 else if (nch == 1)
2599 err_string("Illegal flow_stmt type.");
2600 break;
2601 /*
2602 * Compound statements.
2603 */
2604 case simple_stmt:
2605 res = validate_simple_stmt(tree);
2606 break;
2607 case compound_stmt:
2608 res = validate_compound_stmt(tree);
2609 break;
2610 /*
Thomas Wouters7e474022000-07-16 12:04:32 +00002611 * Fundamental statements.
Fred Drakeff9ea482000-04-19 13:54:15 +00002612 */
2613 case expr_stmt:
2614 res = validate_expr_stmt(tree);
2615 break;
2616 case print_stmt:
2617 res = validate_print_stmt(tree);
2618 break;
2619 case del_stmt:
2620 res = validate_del_stmt(tree);
2621 break;
2622 case pass_stmt:
2623 res = (validate_numnodes(tree, 1, "pass")
2624 && validate_name(CHILD(tree, 0), "pass"));
2625 break;
2626 case break_stmt:
2627 res = (validate_numnodes(tree, 1, "break")
2628 && validate_name(CHILD(tree, 0), "break"));
2629 break;
2630 case continue_stmt:
2631 res = (validate_numnodes(tree, 1, "continue")
2632 && validate_name(CHILD(tree, 0), "continue"));
2633 break;
2634 case return_stmt:
2635 res = validate_return_stmt(tree);
2636 break;
2637 case raise_stmt:
2638 res = validate_raise_stmt(tree);
2639 break;
2640 case import_stmt:
2641 res = validate_import_stmt(tree);
2642 break;
2643 case global_stmt:
2644 res = validate_global_stmt(tree);
2645 break;
2646 case exec_stmt:
2647 res = validate_exec_stmt(tree);
2648 break;
2649 case assert_stmt:
2650 res = validate_assert_stmt(tree);
2651 break;
2652 case if_stmt:
2653 res = validate_if(tree);
2654 break;
2655 case while_stmt:
2656 res = validate_while(tree);
2657 break;
2658 case for_stmt:
2659 res = validate_for(tree);
2660 break;
2661 case try_stmt:
2662 res = validate_try(tree);
2663 break;
2664 case suite:
2665 res = validate_suite(tree);
2666 break;
2667 /*
2668 * Expression nodes.
2669 */
2670 case testlist:
2671 res = validate_testlist(tree);
2672 break;
2673 case test:
2674 res = validate_test(tree);
2675 break;
2676 case and_test:
2677 res = validate_and_test(tree);
2678 break;
2679 case not_test:
2680 res = validate_not_test(tree);
2681 break;
2682 case comparison:
2683 res = validate_comparison(tree);
2684 break;
2685 case exprlist:
2686 res = validate_exprlist(tree);
2687 break;
2688 case comp_op:
2689 res = validate_comp_op(tree);
2690 break;
2691 case expr:
2692 res = validate_expr(tree);
2693 break;
2694 case xor_expr:
2695 res = validate_xor_expr(tree);
2696 break;
2697 case and_expr:
2698 res = validate_and_expr(tree);
2699 break;
2700 case shift_expr:
2701 res = validate_shift_expr(tree);
2702 break;
2703 case arith_expr:
2704 res = validate_arith_expr(tree);
2705 break;
2706 case term:
2707 res = validate_term(tree);
2708 break;
2709 case factor:
2710 res = validate_factor(tree);
2711 break;
2712 case power:
2713 res = validate_power(tree);
2714 break;
2715 case atom:
2716 res = validate_atom(tree);
2717 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002718
Fred Drakeff9ea482000-04-19 13:54:15 +00002719 default:
2720 /* Hopefully never reached! */
2721 err_string("Unrecogniged node type.");
2722 res = 0;
2723 break;
2724 }
2725 tree = next;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002726 }
2727 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002728}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002729
2730
Guido van Rossum47478871996-08-21 14:32:37 +00002731static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002732validate_expr_tree(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002733{
2734 int res = validate_eval_input(tree);
2735
2736 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00002737 err_string("Could not validate expression tuple.");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002738
2739 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002740}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002741
2742
Guido van Rossum3d602e31996-07-21 02:33:56 +00002743/* file_input:
Fred Drakeff9ea482000-04-19 13:54:15 +00002744 * (NEWLINE | stmt)* ENDMARKER
Guido van Rossum3d602e31996-07-21 02:33:56 +00002745 */
Guido van Rossum47478871996-08-21 14:32:37 +00002746static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002747validate_file_input(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002748{
2749 int j = 0;
2750 int nch = NCH(tree) - 1;
2751 int res = ((nch >= 0)
Fred Drakeff9ea482000-04-19 13:54:15 +00002752 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002753
Guido van Rossum3d602e31996-07-21 02:33:56 +00002754 for ( ; res && (j < nch); ++j) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002755 if (TYPE(CHILD(tree, j)) == stmt)
2756 res = validate_stmt(CHILD(tree, j));
2757 else
2758 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002759 }
Thomas Wouters7e474022000-07-16 12:04:32 +00002760 /* This stays in to prevent any internal failures from getting to the
Fred Drakeff9ea482000-04-19 13:54:15 +00002761 * user. Hopefully, this won't be needed. If a user reports getting
2762 * this, we have some debugging to do.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002763 */
2764 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00002765 err_string("VALIDATION FAILURE: report this to the maintainer!.");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002766
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002767 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002768}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002769
2770
Fred Drake43f8f9b1998-04-13 16:25:46 +00002771static PyObject*
2772pickle_constructor = NULL;
2773
2774
2775static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +00002776parser__pickler(PyObject *self, PyObject *args)
Fred Drake43f8f9b1998-04-13 16:25:46 +00002777{
Fred Drake268397f1998-04-29 14:16:32 +00002778 NOTE(ARGUNUSED(self))
Fred Drake43f8f9b1998-04-13 16:25:46 +00002779 PyObject *result = NULL;
2780 PyObject *ast = NULL;
Fred Drake2a6875e1999-09-20 22:32:18 +00002781 PyObject *empty_dict = NULL;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002782
2783 if (PyArg_ParseTuple(args, "O!:_pickler", &PyAST_Type, &ast)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002784 PyObject *newargs;
2785 PyObject *tuple;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002786
Fred Drake2a6875e1999-09-20 22:32:18 +00002787 if ((empty_dict = PyDict_New()) == NULL)
2788 goto finally;
2789 if ((newargs = Py_BuildValue("Oi", ast, 1)) == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +00002790 goto finally;
2791 tuple = parser_ast2tuple((PyAST_Object*)NULL, newargs, empty_dict);
2792 if (tuple != NULL) {
2793 result = Py_BuildValue("O(O)", pickle_constructor, tuple);
2794 Py_DECREF(tuple);
2795 }
Fred Drake2a6875e1999-09-20 22:32:18 +00002796 Py_DECREF(empty_dict);
Fred Drakeff9ea482000-04-19 13:54:15 +00002797 Py_DECREF(newargs);
Fred Drake43f8f9b1998-04-13 16:25:46 +00002798 }
2799 finally:
Fred Drake2a6875e1999-09-20 22:32:18 +00002800 Py_XDECREF(empty_dict);
2801
Fred Drake43f8f9b1998-04-13 16:25:46 +00002802 return (result);
Fred Drakeff9ea482000-04-19 13:54:15 +00002803}
Fred Drake43f8f9b1998-04-13 16:25:46 +00002804
2805
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002806/* Functions exported by this module. Most of this should probably
2807 * be converted into an AST object with methods, but that is better
2808 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002809 * We'd really have to write a wrapper around it all anyway to allow
2810 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002811 */
2812static PyMethodDef parser_functions[] = {
Fred Drakeff9ea482000-04-19 13:54:15 +00002813 {"ast2tuple", (PyCFunction)parser_ast2tuple, PUBLIC_METHOD_TYPE,
2814 "Creates a tuple-tree representation of an AST."},
2815 {"ast2list", (PyCFunction)parser_ast2list, PUBLIC_METHOD_TYPE,
2816 "Creates a list-tree representation of an AST."},
2817 {"compileast", (PyCFunction)parser_compileast, PUBLIC_METHOD_TYPE,
2818 "Compiles an AST object into a code object."},
2819 {"expr", (PyCFunction)parser_expr, PUBLIC_METHOD_TYPE,
2820 "Creates an AST object from an expression."},
2821 {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
2822 "Determines if an AST object was created from an expression."},
2823 {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
2824 "Determines if an AST object was created from a suite."},
2825 {"suite", (PyCFunction)parser_suite, PUBLIC_METHOD_TYPE,
2826 "Creates an AST object from a suite."},
2827 {"sequence2ast", (PyCFunction)parser_tuple2ast, PUBLIC_METHOD_TYPE,
2828 "Creates an AST object from a tree representation."},
2829 {"tuple2ast", (PyCFunction)parser_tuple2ast, PUBLIC_METHOD_TYPE,
2830 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002831
Fred Drake43f8f9b1998-04-13 16:25:46 +00002832 /* private stuff: support pickle module */
Fred Drakeff9ea482000-04-19 13:54:15 +00002833 {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS,
Fred Drake43f8f9b1998-04-13 16:25:46 +00002834 "Returns the pickle magic to allow ast objects to be pickled."},
2835
Fred Drake268397f1998-04-29 14:16:32 +00002836 {NULL, NULL, 0, NULL}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002837 };
2838
2839
Tim Peters6d7c4422000-08-26 07:38:06 +00002840DL_EXPORT(void) initparser(void); /* supply a prototype */
Fred Drake28f739a2000-08-25 22:42:40 +00002841
Guido van Rossum3886bb61998-12-04 18:50:17 +00002842DL_EXPORT(void)
Thomas Wouters5c669862000-07-24 15:49:08 +00002843initparser(void)
Fred Drake28f739a2000-08-25 22:42:40 +00002844{
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002845 PyObject* module;
2846 PyObject* dict;
Fred Drakeff9ea482000-04-19 13:54:15 +00002847
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002848 PyAST_Type.ob_type = &PyType_Type;
2849 module = Py_InitModule("parser", parser_functions);
2850 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002851
Fred Drake7a15ba51999-09-09 14:21:52 +00002852 if (parser_error == 0)
2853 parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002854
2855 if ((parser_error == 0)
Barry Warsaw9bfd2bf2000-09-01 09:01:32 +00002856 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0))
2857 {
2858 /* caller will check PyErr_Occurred() */
2859 return;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002860 }
2861 /*
2862 * Nice to have, but don't cry if we fail.
2863 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002864 Py_INCREF(&PyAST_Type);
2865 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2866
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002867 PyDict_SetItemString(dict, "__copyright__",
Fred Drakeff9ea482000-04-19 13:54:15 +00002868 PyString_FromString(parser_copyright_string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002869 PyDict_SetItemString(dict, "__doc__",
Fred Drakeff9ea482000-04-19 13:54:15 +00002870 PyString_FromString(parser_doc_string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002871 PyDict_SetItemString(dict, "__version__",
Fred Drakeff9ea482000-04-19 13:54:15 +00002872 PyString_FromString(parser_version_string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002873
Fred Drake43f8f9b1998-04-13 16:25:46 +00002874 /* register to support pickling */
2875 module = PyImport_ImportModule("copy_reg");
2876 if (module != NULL) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002877 PyObject *func, *pickler;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002878
Fred Drakeff9ea482000-04-19 13:54:15 +00002879 func = PyObject_GetAttrString(module, "pickle");
2880 pickle_constructor = PyDict_GetItemString(dict, "sequence2ast");
2881 pickler = PyDict_GetItemString(dict, "_pickler");
2882 Py_XINCREF(pickle_constructor);
2883 if ((func != NULL) && (pickle_constructor != NULL)
2884 && (pickler != NULL)) {
2885 PyObject *res;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002886
Fred Drakeff9ea482000-04-19 13:54:15 +00002887 res = PyObject_CallFunction(
2888 func, "OOO", &PyAST_Type, pickler, pickle_constructor);
2889 Py_XDECREF(res);
2890 }
2891 Py_XDECREF(func);
2892 Py_DECREF(module);
Fred Drake43f8f9b1998-04-13 16:25:46 +00002893 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002894}