blob: 9b9baf0cea14de2b30f73512f8648a2527a37a2b [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*
Guido van Rossum47478871996-08-21 14:32:37 +000061parser_version_string = "0.4";
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
Guido van Rossum3d602e31996-07-21 02:33:56 +000069/* The function below is copyrigthed by Stichting Mathematisch Centrum. The
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000070 * original copyright statement is included below, and continues to apply
71 * in full to the function immediately following. All other material is
72 * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
73 * Institute and State University. Changes were made to comply with the
Guido van Rossum2a288461996-08-21 21:55:43 +000074 * new naming conventions. Added arguments to provide support for creating
75 * lists as well as tuples, and optionally including the line numbers.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000076 */
77
Guido van Rossum52f2c051993-11-10 12:53:24 +000078/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +000079Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
80The Netherlands.
Guido van Rossum52f2c051993-11-10 12:53:24 +000081
82 All Rights Reserved
83
Guido van Rossum3d602e31996-07-21 02:33:56 +000084Permission to use, copy, modify, and distribute this software and its
85documentation for any purpose and without fee is hereby granted,
Guido van Rossum52f2c051993-11-10 12:53:24 +000086provided that the above copyright notice appear in all copies and that
Guido van Rossum3d602e31996-07-21 02:33:56 +000087both that copyright notice and this permission notice appear in
Guido van Rossum52f2c051993-11-10 12:53:24 +000088supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000089Centrum or CWI or Corporation for National Research Initiatives or
90CNRI not be used in advertising or publicity pertaining to
91distribution of the software without specific, written prior
92permission.
Guido van Rossum52f2c051993-11-10 12:53:24 +000093
Guido van Rossumd266eb41996-10-25 14:44:06 +000094While CWI is the initial source for this software, a modified version
95is made available by the Corporation for National Research Initiatives
96(CNRI) at the Internet address ftp://ftp.python.org.
97
98STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
99REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
100MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
101CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
102DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
103PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
104TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
105PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum52f2c051993-11-10 12:53:24 +0000106
107******************************************************************/
108
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000109static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000110node2tuple(node *n, /* node to convert */
111 SeqMaker mkseq, /* create sequence */
112 SeqInserter addelem, /* func. to add elem. in seq. */
113 int lineno) /* include line numbers? */
Guido van Rossum47478871996-08-21 14:32:37 +0000114{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000115 if (n == NULL) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000116 Py_INCREF(Py_None);
117 return (Py_None);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000118 }
119 if (ISNONTERMINAL(TYPE(n))) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000120 int i;
121 PyObject *v;
122 PyObject *w;
Fred Drake268397f1998-04-29 14:16:32 +0000123
Fred Drakeff9ea482000-04-19 13:54:15 +0000124 v = mkseq(1 + NCH(n));
125 if (v == NULL)
126 return (v);
127 w = PyInt_FromLong(TYPE(n));
128 if (w == NULL) {
129 Py_DECREF(v);
130 return ((PyObject*) NULL);
131 }
132 (void) addelem(v, 0, w);
133 for (i = 0; i < NCH(n); i++) {
134 w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
135 if (w == NULL) {
136 Py_DECREF(v);
137 return ((PyObject*) NULL);
138 }
139 (void) addelem(v, i+1, w);
140 }
141 return (v);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000142 }
143 else if (ISTERMINAL(TYPE(n))) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000144 PyObject *result = mkseq(2 + lineno);
145 if (result != NULL) {
146 (void) addelem(result, 0, PyInt_FromLong(TYPE(n)));
147 (void) addelem(result, 1, PyString_FromString(STR(n)));
148 if (lineno == 1)
149 (void) addelem(result, 2, PyInt_FromLong(n->n_lineno));
150 }
151 return (result);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000152 }
153 else {
Fred Drakeff9ea482000-04-19 13:54:15 +0000154 PyErr_SetString(PyExc_SystemError,
155 "unrecognized parse tree node type");
156 return ((PyObject*) NULL);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000157 }
Fred Drakeff9ea482000-04-19 13:54:15 +0000158}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000159/*
160 * End of material copyrighted by Stichting Mathematisch Centrum.
161 */
Guido van Rossum52f2c051993-11-10 12:53:24 +0000162
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000163
164
165/* There are two types of intermediate objects we're interested in:
166 * 'eval' and 'exec' types. These constants can be used in the ast_type
167 * field of the object type to identify which any given object represents.
168 * These should probably go in an external header to allow other extensions
169 * to use them, but then, we really should be using C++ too. ;-)
170 *
Guido van Rossum3d602e31996-07-21 02:33:56 +0000171 * The PyAST_FRAGMENT type is not currently supported. Maybe not useful?
172 * Haven't decided yet.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000173 */
174
Fred Drakeff9ea482000-04-19 13:54:15 +0000175#define PyAST_EXPR 1
176#define PyAST_SUITE 2
177#define PyAST_FRAGMENT 3
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000178
179
180/* These are the internal objects and definitions required to implement the
181 * AST type. Most of the internal names are more reminiscent of the 'old'
182 * naming style, but the code uses the new naming convention.
183 */
184
185static PyObject*
186parser_error = 0;
187
188
189typedef struct _PyAST_Object {
Fred Drakeff9ea482000-04-19 13:54:15 +0000190 PyObject_HEAD /* standard object header */
191 node* ast_node; /* the node* returned by the parser */
192 int ast_type; /* EXPR or SUITE ? */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000193} PyAST_Object;
194
195
Fred Drake268397f1998-04-29 14:16:32 +0000196staticforward void
Fred Drakeff9ea482000-04-19 13:54:15 +0000197parser_free(PyAST_Object *ast);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000198
Fred Drake268397f1998-04-29 14:16:32 +0000199staticforward int
Fred Drakeff9ea482000-04-19 13:54:15 +0000200parser_compare(PyAST_Object *left, PyAST_Object *right);
Fred Drake268397f1998-04-29 14:16:32 +0000201
202staticforward PyObject *
Fred Drakeff9ea482000-04-19 13:54:15 +0000203parser_getattr(PyObject *self, char *name);
Fred Drake503d8d61998-04-13 18:45:18 +0000204
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000205
Fred Drake268397f1998-04-29 14:16:32 +0000206static
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000207PyTypeObject PyAST_Type = {
Guido van Rossum3c8c5981998-05-29 02:58:20 +0000208 PyObject_HEAD_INIT(NULL)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000209 0,
Fred Drakeff9ea482000-04-19 13:54:15 +0000210 "ast", /* tp_name */
211 (int) sizeof(PyAST_Object), /* tp_basicsize */
212 0, /* tp_itemsize */
213 (destructor)parser_free, /* tp_dealloc */
214 0, /* tp_print */
215 parser_getattr, /* tp_getattr */
216 0, /* tp_setattr */
217 (cmpfunc)parser_compare, /* tp_compare */
218 0, /* tp_repr */
219 0, /* tp_as_number */
220 0, /* tp_as_sequence */
221 0, /* tp_as_mapping */
222 0, /* tp_hash */
223 0, /* tp_call */
224 0, /* tp_str */
225 0, /* tp_getattro */
226 0, /* tp_setattro */
Fred Drake69b9ae41997-05-23 04:04:17 +0000227
228 /* Functions to access object as input/output buffer */
Fred Drakeff9ea482000-04-19 13:54:15 +0000229 0, /* tp_as_buffer */
Fred Drake69b9ae41997-05-23 04:04:17 +0000230
Fred Drakeff9ea482000-04-19 13:54:15 +0000231 Py_TPFLAGS_DEFAULT, /* tp_flags */
Fred Drake69b9ae41997-05-23 04:04:17 +0000232
233 /* __doc__ */
234 "Intermediate representation of a Python parse tree."
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000235}; /* PyAST_Type */
236
237
238static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000239parser_compare_nodes(node *left, node *right)
Guido van Rossum47478871996-08-21 14:32:37 +0000240{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000241 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000242
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000243 if (TYPE(left) < TYPE(right))
Fred Drakeff9ea482000-04-19 13:54:15 +0000244 return (-1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000245
246 if (TYPE(right) < TYPE(left))
Fred Drakeff9ea482000-04-19 13:54:15 +0000247 return (1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000248
249 if (ISTERMINAL(TYPE(left)))
Fred Drakeff9ea482000-04-19 13:54:15 +0000250 return (strcmp(STR(left), STR(right)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000251
252 if (NCH(left) < NCH(right))
Fred Drakeff9ea482000-04-19 13:54:15 +0000253 return (-1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000254
255 if (NCH(right) < NCH(left))
Fred Drakeff9ea482000-04-19 13:54:15 +0000256 return (1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000257
258 for (j = 0; j < NCH(left); ++j) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000259 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000260
Fred Drakeff9ea482000-04-19 13:54:15 +0000261 if (v != 0)
262 return (v);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000263 }
264 return (0);
Fred Drakeff9ea482000-04-19 13:54:15 +0000265}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000266
267
268/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
269 *
270 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
271 * This really just wraps a call to parser_compare_nodes() with some easy
272 * checks and protection code.
273 *
274 */
275static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000276parser_compare(PyAST_Object *left, PyAST_Object *right)
Guido van Rossum47478871996-08-21 14:32:37 +0000277{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000278 if (left == right)
Fred Drakeff9ea482000-04-19 13:54:15 +0000279 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000280
281 if ((left == 0) || (right == 0))
Fred Drakeff9ea482000-04-19 13:54:15 +0000282 return (-1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000283
284 return (parser_compare_nodes(left->ast_node, right->ast_node));
Fred Drakeff9ea482000-04-19 13:54:15 +0000285}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000286
287
288/* parser_newastobject(node* ast)
289 *
290 * Allocates a new Python object representing an AST. This is simply the
291 * 'wrapper' object that holds a node* and allows it to be passed around in
292 * Python code.
293 *
294 */
295static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000296parser_newastobject(node *ast, int type)
Guido van Rossum47478871996-08-21 14:32:37 +0000297{
Guido van Rossumb18618d2000-05-03 23:44:39 +0000298 PyAST_Object* o = PyObject_New(PyAST_Object, &PyAST_Type);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000299
300 if (o != 0) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000301 o->ast_node = ast;
302 o->ast_type = type;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000303 }
Fred Drake268397f1998-04-29 14:16:32 +0000304 else {
Fred Drakeff9ea482000-04-19 13:54:15 +0000305 PyNode_Free(ast);
Fred Drake268397f1998-04-29 14:16:32 +0000306 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000307 return ((PyObject*)o);
Fred Drakeff9ea482000-04-19 13:54:15 +0000308}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000309
310
311/* void parser_free(PyAST_Object* ast)
312 *
313 * This is called by a del statement that reduces the reference count to 0.
314 *
315 */
316static void
Fred Drakeff9ea482000-04-19 13:54:15 +0000317parser_free(PyAST_Object *ast)
Guido van Rossum47478871996-08-21 14:32:37 +0000318{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000319 PyNode_Free(ast->ast_node);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000320 PyObject_Del(ast);
Fred Drakeff9ea482000-04-19 13:54:15 +0000321}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000322
323
Fred Drake2a6875e1999-09-20 22:32:18 +0000324/* parser_ast2tuple(PyObject* self, PyObject* args, PyObject* kw)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000325 *
326 * This provides conversion from a node* to a tuple object that can be
327 * returned to the Python-level caller. The AST object is not modified.
328 *
329 */
330static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000331parser_ast2tuple(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000332{
Guido van Rossum47478871996-08-21 14:32:37 +0000333 PyObject *line_option = 0;
334 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000335 int ok;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000336
Fred Drake7a15ba51999-09-09 14:21:52 +0000337 static char *keywords[] = {"ast", "line_info", NULL};
338
Fred Drake268397f1998-04-29 14:16:32 +0000339 if (self == NULL) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000340 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:ast2tuple", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000341 &PyAST_Type, &self, &line_option);
Fred Drake268397f1998-04-29 14:16:32 +0000342 }
Fred Drake503d8d61998-04-13 18:45:18 +0000343 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000344 ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:totuple", &keywords[1],
Fred Drake7a15ba51999-09-09 14:21:52 +0000345 &line_option);
Fred Drake268397f1998-04-29 14:16:32 +0000346 if (ok != 0) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000347 int lineno = 0;
348 if (line_option != NULL) {
349 lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0;
350 }
351 /*
352 * Convert AST into a tuple representation. Use Guido's function,
353 * since it's known to work already.
354 */
355 res = node2tuple(((PyAST_Object*)self)->ast_node,
356 PyTuple_New, PyTuple_SetItem, lineno);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000357 }
358 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000359}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000360
361
Fred Drake2a6875e1999-09-20 22:32:18 +0000362/* parser_ast2list(PyObject* self, PyObject* args, PyObject* kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000363 *
Fred Drake2a6875e1999-09-20 22:32:18 +0000364 * This provides conversion from a node* to a list object that can be
Guido van Rossum47478871996-08-21 14:32:37 +0000365 * returned to the Python-level caller. The AST object is not modified.
366 *
367 */
368static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000369parser_ast2list(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000370{
Guido van Rossum47478871996-08-21 14:32:37 +0000371 PyObject *line_option = 0;
372 PyObject *res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000373 int ok;
Guido van Rossum47478871996-08-21 14:32:37 +0000374
Fred Drake7a15ba51999-09-09 14:21:52 +0000375 static char *keywords[] = {"ast", "line_info", NULL};
376
Fred Drake503d8d61998-04-13 18:45:18 +0000377 if (self == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000378 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:ast2list", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000379 &PyAST_Type, &self, &line_option);
Fred Drake503d8d61998-04-13 18:45:18 +0000380 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000381 ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1],
Fred Drake7a15ba51999-09-09 14:21:52 +0000382 &line_option);
Fred Drake503d8d61998-04-13 18:45:18 +0000383 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000384 int lineno = 0;
385 if (line_option != 0) {
386 lineno = PyObject_IsTrue(line_option) ? 1 : 0;
387 }
388 /*
389 * Convert AST into a tuple representation. Use Guido's function,
390 * since it's known to work already.
391 */
392 res = node2tuple(self->ast_node,
393 PyList_New, PyList_SetItem, lineno);
Guido van Rossum47478871996-08-21 14:32:37 +0000394 }
395 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000396}
Guido van Rossum47478871996-08-21 14:32:37 +0000397
398
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000399/* parser_compileast(PyObject* self, PyObject* args)
400 *
401 * This function creates code objects from the parse tree represented by
402 * the passed-in data object. An optional file name is passed in as well.
403 *
404 */
405static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000406parser_compileast(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 Drakeff9ea482000-04-19 13:54:15 +0000409 char* str = "<ast>";
Fred Drake503d8d61998-04-13 18:45:18 +0000410 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000411
Fred Drake7a15ba51999-09-09 14:21:52 +0000412 static char *keywords[] = {"ast", "filename", NULL};
413
Fred Drake503d8d61998-04-13 18:45:18 +0000414 if (self == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000415 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compileast", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000416 &PyAST_Type, &self, &str);
Fred Drake503d8d61998-04-13 18:45:18 +0000417 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000418 ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1],
Fred Drake7a15ba51999-09-09 14:21:52 +0000419 &str);
Fred Drake503d8d61998-04-13 18:45:18 +0000420
421 if (ok)
Fred Drakeff9ea482000-04-19 13:54:15 +0000422 res = (PyObject *)PyNode_Compile(self->ast_node, str);
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
428/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
429 * PyObject* parser_issuite(PyObject* self, PyObject* args)
430 *
431 * Checks the passed-in AST object to determine if it is an expression or
432 * a statement suite, respectively. The return is a Python truth value.
433 *
434 */
435static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000436parser_isexpr(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000437{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000438 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000439 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000440
Fred Drake7a15ba51999-09-09 14:21:52 +0000441 static char *keywords[] = {"ast", NULL};
442
Fred Drake503d8d61998-04-13 18:45:18 +0000443 if (self == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000444 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000445 &PyAST_Type, &self);
Fred Drake503d8d61998-04-13 18:45:18 +0000446 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000447 ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]);
Fred Drake503d8d61998-04-13 18:45:18 +0000448
449 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000450 /* Check to see if the AST represents an expression or not. */
451 res = (self->ast_type == PyAST_EXPR) ? Py_True : Py_False;
452 Py_INCREF(res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000453 }
454 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000455}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000456
457
458static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000459parser_issuite(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000460{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000461 PyObject* res = 0;
Fred Drake503d8d61998-04-13 18:45:18 +0000462 int ok;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000463
Fred Drake7a15ba51999-09-09 14:21:52 +0000464 static char *keywords[] = {"ast", NULL};
465
Fred Drake503d8d61998-04-13 18:45:18 +0000466 if (self == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000467 ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
Fred Drake7a15ba51999-09-09 14:21:52 +0000468 &PyAST_Type, &self);
Fred Drake503d8d61998-04-13 18:45:18 +0000469 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000470 ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]);
Fred Drake503d8d61998-04-13 18:45:18 +0000471
472 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000473 /* Check to see if the AST represents an expression or not. */
474 res = (self->ast_type == PyAST_EXPR) ? Py_False : Py_True;
475 Py_INCREF(res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000476 }
477 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000478}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000479
480
Fred Drake7a15ba51999-09-09 14:21:52 +0000481#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS)
482
Fred Drake503d8d61998-04-13 18:45:18 +0000483static PyMethodDef
484parser_methods[] = {
Fred Drakeff9ea482000-04-19 13:54:15 +0000485 {"compile", (PyCFunction)parser_compileast, PUBLIC_METHOD_TYPE,
486 "Compile this AST object into a code object."},
487 {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
488 "Determines if this AST object was created from an expression."},
489 {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
490 "Determines if this AST object was created from a suite."},
491 {"tolist", (PyCFunction)parser_ast2list, PUBLIC_METHOD_TYPE,
492 "Creates a list-tree representation of this AST."},
493 {"totuple", (PyCFunction)parser_ast2tuple, PUBLIC_METHOD_TYPE,
494 "Creates a tuple-tree representation of this AST."},
Fred Drake503d8d61998-04-13 18:45:18 +0000495
Fred Drake268397f1998-04-29 14:16:32 +0000496 {NULL, NULL, 0, NULL}
Fred Drake503d8d61998-04-13 18:45:18 +0000497};
498
Fred Drake503d8d61998-04-13 18:45:18 +0000499
500static PyObject*
501parser_getattr(self, name)
502 PyObject *self;
503 char *name;
504{
Fred Drake503d8d61998-04-13 18:45:18 +0000505 return (Py_FindMethod(parser_methods, self, name));
Fred Drakeff9ea482000-04-19 13:54:15 +0000506}
Fred Drake503d8d61998-04-13 18:45:18 +0000507
508
Guido van Rossum3d602e31996-07-21 02:33:56 +0000509/* err_string(char* message)
510 *
511 * Sets the error string for an exception of type ParserError.
512 *
513 */
514static void
515err_string(message)
516 char *message;
Guido van Rossum47478871996-08-21 14:32:37 +0000517{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000518 PyErr_SetString(parser_error, message);
Fred Drakeff9ea482000-04-19 13:54:15 +0000519}
Guido van Rossum3d602e31996-07-21 02:33:56 +0000520
521
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000522/* PyObject* parser_do_parse(PyObject* args, int type)
523 *
524 * Internal function to actually execute the parse and return the result if
525 * successful, or set an exception if not.
526 *
527 */
528static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000529parser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type)
Guido van Rossum47478871996-08-21 14:32:37 +0000530{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000531 char* string = 0;
532 PyObject* res = 0;
533
Fred Drake7a15ba51999-09-09 14:21:52 +0000534 static char *keywords[] = {"source", NULL};
535
536 if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000537 node* n = PyParser_SimpleParseString(string,
538 (type == PyAST_EXPR)
539 ? eval_input : file_input);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000540
Fred Drakeff9ea482000-04-19 13:54:15 +0000541 if (n != 0)
542 res = parser_newastobject(n, type);
543 else
544 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000545 }
546 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000547}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000548
549
550/* PyObject* parser_expr(PyObject* self, PyObject* args)
551 * PyObject* parser_suite(PyObject* self, PyObject* args)
552 *
553 * External interfaces to the parser itself. Which is called determines if
554 * the parser attempts to recognize an expression ('eval' form) or statement
555 * suite ('exec' form). The real work is done by parser_do_parse() above.
556 *
557 */
558static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000559parser_expr(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000560{
Fred Drake268397f1998-04-29 14:16:32 +0000561 NOTE(ARGUNUSED(self))
Fred Drake7a15ba51999-09-09 14:21:52 +0000562 return (parser_do_parse(args, kw, "s:expr", PyAST_EXPR));
Fred Drakeff9ea482000-04-19 13:54:15 +0000563}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000564
565
566static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000567parser_suite(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000568{
Fred Drake268397f1998-04-29 14:16:32 +0000569 NOTE(ARGUNUSED(self))
Fred Drake7a15ba51999-09-09 14:21:52 +0000570 return (parser_do_parse(args, kw, "s:suite", PyAST_SUITE));
Fred Drakeff9ea482000-04-19 13:54:15 +0000571}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000572
573
574
575/* This is the messy part of the code. Conversion from a tuple to an AST
576 * object requires that the input tuple be valid without having to rely on
577 * catching an exception from the compiler. This is done to allow the
578 * compiler itself to remain fast, since most of its input will come from
579 * the parser directly, and therefore be known to be syntactically correct.
580 * This validation is done to ensure that we don't core dump the compile
581 * phase, returning an exception instead.
582 *
583 * Two aspects can be broken out in this code: creating a node tree from
584 * the tuple passed in, and verifying that it is indeed valid. It may be
585 * advantageous to expand the number of AST types to include funcdefs and
586 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
587 * here. They are not necessary, and not quite as useful in a raw form.
588 * For now, let's get expressions and suites working reliably.
589 */
590
591
Fred Drakeff9ea482000-04-19 13:54:15 +0000592staticforward node* build_node_tree(PyObject *tuple);
593staticforward int validate_expr_tree(node *tree);
594staticforward int validate_file_input(node *tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000595
596
597/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
598 *
599 * This is the public function, called from the Python code. It receives a
600 * single tuple object from the caller, and creates an AST object if the
601 * tuple can be validated. It does this by checking the first code of the
602 * tuple, and, if acceptable, builds the internal representation. If this
603 * step succeeds, the internal representation is validated as fully as
604 * possible with the various validate_*() routines defined below.
605 *
606 * This function must be changed if support is to be added for PyAST_FRAGMENT
607 * AST objects.
608 *
609 */
610static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +0000611parser_tuple2ast(PyAST_Object *self, PyObject *args, PyObject *kw)
Guido van Rossum47478871996-08-21 14:32:37 +0000612{
Fred Drake268397f1998-04-29 14:16:32 +0000613 NOTE(ARGUNUSED(self))
Guido van Rossum47478871996-08-21 14:32:37 +0000614 PyObject *ast = 0;
615 PyObject *tuple = 0;
616 PyObject *temp = 0;
617 int ok;
Guido van Rossuma376cc51996-12-05 23:43:35 +0000618 int start_sym = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000619
Fred Drake7a15ba51999-09-09 14:21:52 +0000620 static char *keywords[] = {"sequence", NULL};
621
622 if (!PyArg_ParseTupleAndKeywords(args, kw, "O:tuple2ast", keywords,
623 &tuple))
Fred Drakeff9ea482000-04-19 13:54:15 +0000624 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000625 if (!PySequence_Check(tuple)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000626 PyErr_SetString(PyExc_ValueError,
627 "tuple2ast() requires a single sequence argument");
628 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000629 }
630 /*
Fred Drakeff9ea482000-04-19 13:54:15 +0000631 * This mess of tests is written this way so we can use the abstract
632 * object interface (AOI). Unfortunately, the AOI increments reference
633 * counts, which requires that we store a pointer to retrieved object
634 * so we can DECREF it after the check. But we really should accept
635 * lists as well as tuples at the very least.
Guido van Rossum47478871996-08-21 14:32:37 +0000636 */
637 ok = PyObject_Length(tuple) >= 2;
638 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000639 temp = PySequence_GetItem(tuple, 0);
640 ok = (temp != NULL) && PyInt_Check(temp);
641 if (ok)
642 /* this is used after the initial checks: */
643 start_sym = PyInt_AS_LONG(temp);
644 Py_XDECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000645 }
646 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000647 temp = PySequence_GetItem(tuple, 1);
648 ok = (temp != NULL) && PySequence_Check(temp);
649 Py_XDECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000650 }
651 if (ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000652 temp = PySequence_GetItem(tuple, 1);
653 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
654 if (ok) {
655 PyObject *temp2 = PySequence_GetItem(temp, 0);
656 if (temp2 != NULL) {
657 ok = PyInt_Check(temp2);
658 Py_DECREF(temp2);
659 }
660 }
661 Py_XDECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000662 }
663 /* If we've failed at some point, get out of here. */
664 if (!ok) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000665 err_string("malformed sequence for tuple2ast()");
666 return (0);
Guido van Rossum47478871996-08-21 14:32:37 +0000667 }
668 /*
669 * This might be a valid parse tree, but let's do a quick check
670 * before we jump the gun.
671 */
672 if (start_sym == eval_input) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000673 /* Might be an eval form. */
674 node* expression = build_node_tree(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000675
Fred Drakeff9ea482000-04-19 13:54:15 +0000676 if ((expression != 0) && validate_expr_tree(expression))
677 ast = parser_newastobject(expression, PyAST_EXPR);
Guido van Rossum47478871996-08-21 14:32:37 +0000678 }
679 else if (start_sym == file_input) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000680 /* This looks like an exec form so far. */
681 node* suite_tree = build_node_tree(tuple);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000682
Fred Drakeff9ea482000-04-19 13:54:15 +0000683 if ((suite_tree != 0) && validate_file_input(suite_tree))
684 ast = parser_newastobject(suite_tree, PyAST_SUITE);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000685 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000686 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000687 /* This is a fragment, and is not yet supported. Maybe they
688 * will be if I find a use for them.
689 */
690 err_string("Fragmentary parse trees not supported.");
Guido van Rossum47478871996-08-21 14:32:37 +0000691
692 /* Make sure we throw an exception on all errors. We should never
693 * get this, but we'd do well to be sure something is done.
694 */
695 if ((ast == 0) && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +0000696 err_string("Unspecified ast error occurred.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000697
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000698 return (ast);
Fred Drakeff9ea482000-04-19 13:54:15 +0000699}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000700
701
702/* int check_terminal_tuple()
703 *
Guido van Rossum47478871996-08-21 14:32:37 +0000704 * Check a tuple to determine that it is indeed a valid terminal
705 * node. The node is known to be required as a terminal, so we throw
706 * an exception if there is a failure.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000707 *
Guido van Rossum47478871996-08-21 14:32:37 +0000708 * The format of an acceptable terminal tuple is "(is[i])": the fact
709 * that elem is a tuple and the integer is a valid terminal symbol
710 * has been established before this function is called. We must
711 * check the length of the tuple and the type of the second element
712 * and optional third element. We do *NOT* check the actual text of
713 * the string element, which we could do in many cases. This is done
714 * by the validate_*() functions which operate on the internal
715 * representation.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000716 */
717static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000718check_terminal_tuple(PyObject *elem)
Guido van Rossum47478871996-08-21 14:32:37 +0000719{
720 int len = PyObject_Length(elem);
721 int res = 1;
722 char* str = "Illegal terminal symbol; bad node length.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000723
Guido van Rossum47478871996-08-21 14:32:37 +0000724 if ((len == 2) || (len == 3)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000725 PyObject *temp = PySequence_GetItem(elem, 1);
726 res = PyString_Check(temp);
727 str = "Illegal terminal symbol; expected a string.";
728 if (res && (len == 3)) {
729 PyObject* third = PySequence_GetItem(elem, 2);
730 res = PyInt_Check(third);
731 str = "Invalid third element of terminal node.";
732 Py_XDECREF(third);
733 }
734 Py_XDECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000735 }
736 else {
Fred Drakeff9ea482000-04-19 13:54:15 +0000737 res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000738 }
739 if (!res) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000740 elem = Py_BuildValue("(os)", elem, str);
741 PyErr_SetObject(parser_error, elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000742 }
743 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000744}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000745
746
747/* node* build_node_children()
748 *
749 * Iterate across the children of the current non-terminal node and build
750 * their structures. If successful, return the root of this portion of
751 * the tree, otherwise, 0. Any required exception will be specified already,
752 * and no memory will have been deallocated.
753 *
754 */
755static node*
Fred Drakeff9ea482000-04-19 13:54:15 +0000756build_node_children(PyObject *tuple, node *root, int *line_num)
Guido van Rossum47478871996-08-21 14:32:37 +0000757{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000758 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000759 int i;
760
761 for (i = 1; i < len; ++i) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000762 /* elem must always be a tuple, however simple */
763 PyObject* elem = PySequence_GetItem(tuple, i);
764 int ok = elem != NULL;
765 long type = 0;
766 char *strn = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000767
Fred Drakeff9ea482000-04-19 13:54:15 +0000768 if (ok)
769 ok = PySequence_Check(elem);
770 if (ok) {
771 PyObject *temp = PySequence_GetItem(elem, 0);
772 if (temp == NULL)
773 ok = 0;
774 else {
775 ok = PyInt_Check(temp);
776 if (ok)
777 type = PyInt_AS_LONG(temp);
778 Py_DECREF(temp);
779 }
780 }
781 if (!ok) {
782 PyErr_SetObject(parser_error,
783 Py_BuildValue("(os)", elem,
784 "Illegal node construct."));
785 Py_XDECREF(elem);
786 return (0);
787 }
788 if (ISTERMINAL(type)) {
789 if (check_terminal_tuple(elem)) {
790 PyObject *temp = PySequence_GetItem(elem, 1);
Guido van Rossum47478871996-08-21 14:32:37 +0000791
Fred Drakeff9ea482000-04-19 13:54:15 +0000792 /* check_terminal_tuple() already verified it's a string */
Guido van Rossumb18618d2000-05-03 23:44:39 +0000793 strn = (char *)PyMem_MALLOC(PyString_GET_SIZE(temp) + 1);
Fred Drakeff9ea482000-04-19 13:54:15 +0000794 if (strn != NULL)
795 (void) strcpy(strn, PyString_AS_STRING(temp));
Guido van Rossumb18618d2000-05-03 23:44:39 +0000796 Py_DECREF(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000797
Fred Drakeff9ea482000-04-19 13:54:15 +0000798 if (PyObject_Length(elem) == 3) {
799 PyObject* temp = PySequence_GetItem(elem, 2);
800 *line_num = PyInt_AsLong(temp);
801 Py_DECREF(temp);
802 }
803 }
804 else {
805 Py_XDECREF(elem);
806 return (0);
807 }
808 }
809 else if (!ISNONTERMINAL(type)) {
810 /*
811 * It has to be one or the other; this is an error.
812 * Throw an exception.
813 */
814 PyErr_SetObject(parser_error,
815 Py_BuildValue("(os)", elem,
816 "Unknown node type."));
817 Py_XDECREF(elem);
818 return (0);
819 }
820 PyNode_AddChild(root, type, strn, *line_num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000821
Fred Drakeff9ea482000-04-19 13:54:15 +0000822 if (ISNONTERMINAL(type)) {
823 node* new_child = CHILD(root, i - 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000824
Fred Drakeff9ea482000-04-19 13:54:15 +0000825 if (new_child != build_node_children(elem, new_child, line_num)) {
826 Py_XDECREF(elem);
827 return (0);
828 }
829 }
830 else if (type == NEWLINE) { /* It's true: we increment the */
831 ++(*line_num); /* line number *after* the newline! */
832 }
833 Py_XDECREF(elem);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000834 }
835 return (root);
Fred Drakeff9ea482000-04-19 13:54:15 +0000836}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000837
838
839static node*
Fred Drakeff9ea482000-04-19 13:54:15 +0000840build_node_tree(PyObject *tuple)
Guido van Rossum47478871996-08-21 14:32:37 +0000841{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000842 node* res = 0;
Guido van Rossum47478871996-08-21 14:32:37 +0000843 PyObject *temp = PySequence_GetItem(tuple, 0);
844 long num = -1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000845
Guido van Rossum47478871996-08-21 14:32:37 +0000846 if (temp != NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +0000847 num = PyInt_AsLong(temp);
Guido van Rossum47478871996-08-21 14:32:37 +0000848 Py_XDECREF(temp);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000849 if (ISTERMINAL(num)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000850 /*
851 * The tuple is simple, but it doesn't start with a start symbol.
852 * Throw an exception now and be done with it.
853 */
854 tuple = Py_BuildValue("(os)", tuple,
855 "Illegal ast tuple; cannot start with terminal symbol.");
856 PyErr_SetObject(parser_error, tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000857 }
858 else if (ISNONTERMINAL(num)) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000859 /*
860 * Not efficient, but that can be handled later.
861 */
862 int line_num = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000863
Fred Drakeff9ea482000-04-19 13:54:15 +0000864 res = PyNode_New(num);
865 if (res != build_node_children(tuple, res, &line_num)) {
866 PyNode_Free(res);
867 res = 0;
868 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000869 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000870 else
Fred Drakeff9ea482000-04-19 13:54:15 +0000871 /* The tuple is illegal -- if the number is neither TERMINAL nor
872 * NONTERMINAL, we can't use it.
873 */
874 PyErr_SetObject(parser_error,
875 Py_BuildValue("(os)", tuple,
876 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000877
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000878 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000879}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000880
881
Guido van Rossum360a9341996-08-21 19:04:10 +0000882#ifdef HAVE_OLD_CPP
Fred Drakeff9ea482000-04-19 13:54:15 +0000883#define VALIDATER(n) static int validate_/**/n(node *tree)
Guido van Rossum360a9341996-08-21 19:04:10 +0000884#else
Fred Drakeff9ea482000-04-19 13:54:15 +0000885#define VALIDATER(n) static int validate_##n(node *tree)
Guido van Rossum360a9341996-08-21 19:04:10 +0000886#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000887
888
889/*
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000890 * Validation routines used within the validation section:
891 */
Fred Drakeff9ea482000-04-19 13:54:15 +0000892staticforward int validate_terminal(node *terminal, int type, char *string);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000893
Fred Drakeff9ea482000-04-19 13:54:15 +0000894#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
895#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
896#define validate_colon(ch) validate_terminal(ch, COLON, ":")
897#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
898#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
899#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
900#define validate_indent(ch) validate_terminal(ch, INDENT, (char*)NULL)
901#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
902#define validate_newline(ch) validate_terminal(ch, NEWLINE, (char*)NULL)
903#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
904#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
905#define validate_star(ch) validate_terminal(ch, STAR, "*")
906#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
907#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
908#define validate_dot(ch) validate_terminal(ch, DOT, ".")
909#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000910
Fred Drakeff9ea482000-04-19 13:54:15 +0000911VALIDATER(node); VALIDATER(small_stmt);
912VALIDATER(class); VALIDATER(node);
913VALIDATER(parameters); VALIDATER(suite);
914VALIDATER(testlist); VALIDATER(varargslist);
915VALIDATER(fpdef); VALIDATER(fplist);
916VALIDATER(stmt); VALIDATER(simple_stmt);
917VALIDATER(expr_stmt); VALIDATER(power);
918VALIDATER(print_stmt); VALIDATER(del_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000919VALIDATER(return_stmt);
Fred Drakeff9ea482000-04-19 13:54:15 +0000920VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum2a288461996-08-21 21:55:43 +0000921VALIDATER(global_stmt);
Guido van Rossum925e5471997-04-02 05:32:13 +0000922VALIDATER(assert_stmt);
Fred Drakeff9ea482000-04-19 13:54:15 +0000923VALIDATER(exec_stmt); VALIDATER(compound_stmt);
924VALIDATER(while); VALIDATER(for);
925VALIDATER(try); VALIDATER(except_clause);
926VALIDATER(test); VALIDATER(and_test);
927VALIDATER(not_test); VALIDATER(comparison);
928VALIDATER(comp_op); VALIDATER(expr);
929VALIDATER(xor_expr); VALIDATER(and_expr);
930VALIDATER(shift_expr); VALIDATER(arith_expr);
931VALIDATER(term); VALIDATER(factor);
932VALIDATER(atom); VALIDATER(lambdef);
933VALIDATER(trailer); VALIDATER(subscript);
934VALIDATER(subscriptlist); VALIDATER(sliceop);
935VALIDATER(exprlist); VALIDATER(dictmaker);
936VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000937
938
Fred Drakeff9ea482000-04-19 13:54:15 +0000939#define is_even(n) (((n) & 1) == 0)
940#define is_odd(n) (((n) & 1) == 1)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000941
942
943static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000944validate_ntype(node *n, int t)
Guido van Rossum47478871996-08-21 14:32:37 +0000945{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000946 int res = (TYPE(n) == t);
947
948 if (!res) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000949 char buffer[128];
950 (void) sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
951 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000952 }
953 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000954}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000955
956
Fred Drakee7ab64e2000-04-25 04:14:46 +0000957/* Verifies that the number of child nodes is exactly 'num', raising
958 * an exception if it isn't. The exception message does not indicate
959 * the exact number of nodes, allowing this to be used to raise the
960 * "right" exception when the wrong number of nodes is present in a
961 * specific variant of a statement's syntax. This is commonly used
962 * in that fashion.
963 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000964static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000965validate_numnodes(node *n, int num, const char *const name)
Guido van Rossum47478871996-08-21 14:32:37 +0000966{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000967 if (NCH(n) != num) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000968 char buff[60];
969 (void) sprintf(buff, "Illegal number of children for %s node.", name);
970 err_string(buff);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000971 }
972 return (NCH(n) == num);
Fred Drakeff9ea482000-04-19 13:54:15 +0000973}
Guido van Rossum3d602e31996-07-21 02:33:56 +0000974
975
976static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000977validate_terminal(node *terminal, int type, char *string)
Guido van Rossum47478871996-08-21 14:32:37 +0000978{
Guido van Rossum3d602e31996-07-21 02:33:56 +0000979 int res = (validate_ntype(terminal, type)
Fred Drakeff9ea482000-04-19 13:54:15 +0000980 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000981
982 if (!res && !PyErr_Occurred()) {
Fred Drakeff9ea482000-04-19 13:54:15 +0000983 char buffer[60];
984 (void) sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
985 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000986 }
987 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +0000988}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000989
990
Guido van Rossum47478871996-08-21 14:32:37 +0000991/* X (',' X) [',']
992 */
993static int
Fred Drakeff9ea482000-04-19 13:54:15 +0000994validate_repeating_list(node *tree, int ntype, int (*vfunc)(),
995 const char *const name)
Guido van Rossum47478871996-08-21 14:32:37 +0000996{
997 int nch = NCH(tree);
998 int res = (nch && validate_ntype(tree, ntype)
Fred Drakeff9ea482000-04-19 13:54:15 +0000999 && vfunc(CHILD(tree, 0)));
Guido van Rossum47478871996-08-21 14:32:37 +00001000
1001 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00001002 (void) validate_numnodes(tree, 1, name);
Guido van Rossum47478871996-08-21 14:32:37 +00001003 else {
Fred Drakeff9ea482000-04-19 13:54:15 +00001004 if (is_even(nch))
1005 res = validate_comma(CHILD(tree, --nch));
1006 if (res && nch > 1) {
1007 int pos = 1;
1008 for ( ; res && pos < nch; pos += 2)
1009 res = (validate_comma(CHILD(tree, pos))
1010 && vfunc(CHILD(tree, pos + 1)));
1011 }
Guido van Rossum47478871996-08-21 14:32:37 +00001012 }
1013 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001014}
Guido van Rossum47478871996-08-21 14:32:37 +00001015
1016
Guido van Rossum3d602e31996-07-21 02:33:56 +00001017/* VALIDATE(class)
1018 *
1019 * classdef:
Fred Drakeff9ea482000-04-19 13:54:15 +00001020 * 'class' NAME ['(' testlist ')'] ':' suite
Guido van Rossum3d602e31996-07-21 02:33:56 +00001021 */
Guido van Rossum47478871996-08-21 14:32:37 +00001022static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001023validate_class(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001024{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001025 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001026 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001027
Guido van Rossum3d602e31996-07-21 02:33:56 +00001028 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001029 res = (validate_name(CHILD(tree, 0), "class")
1030 && validate_ntype(CHILD(tree, 1), NAME)
1031 && validate_colon(CHILD(tree, nch - 2))
1032 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001033 }
1034 else
Fred Drakeff9ea482000-04-19 13:54:15 +00001035 (void) validate_numnodes(tree, 4, "class");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001036 if (res && (nch == 7)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001037 res = (validate_lparen(CHILD(tree, 2))
1038 && validate_testlist(CHILD(tree, 3))
1039 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001040 }
1041 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001042}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001043
1044
Guido van Rossum3d602e31996-07-21 02:33:56 +00001045/* if_stmt:
Fred Drakeff9ea482000-04-19 13:54:15 +00001046 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001047 */
Guido van Rossum47478871996-08-21 14:32:37 +00001048static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001049validate_if(node *tree)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001050{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001051 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001052 int res = (validate_ntype(tree, if_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001053 && (nch >= 4)
1054 && validate_name(CHILD(tree, 0), "if")
1055 && validate_test(CHILD(tree, 1))
1056 && validate_colon(CHILD(tree, 2))
1057 && validate_suite(CHILD(tree, 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001058
1059 if (res && ((nch % 4) == 3)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001060 /* ... 'else' ':' suite */
1061 res = (validate_name(CHILD(tree, nch - 3), "else")
1062 && validate_colon(CHILD(tree, nch - 2))
1063 && validate_suite(CHILD(tree, nch - 1)));
1064 nch -= 3;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001065 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001066 else if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00001067 (void) validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001068 if ((nch % 4) != 0)
Fred Drakeff9ea482000-04-19 13:54:15 +00001069 /* Will catch the case for nch < 4 */
1070 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001071 else if (res && (nch > 4)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001072 /* ... ('elif' test ':' suite)+ ... */
1073 int j = 4;
1074 while ((j < nch) && res) {
1075 res = (validate_name(CHILD(tree, j), "elif")
1076 && validate_colon(CHILD(tree, j + 2))
1077 && validate_test(CHILD(tree, j + 1))
1078 && validate_suite(CHILD(tree, j + 3)));
1079 j += 4;
1080 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001081 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001082 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001083}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001084
1085
Guido van Rossum3d602e31996-07-21 02:33:56 +00001086/* parameters:
Fred Drakeff9ea482000-04-19 13:54:15 +00001087 * '(' [varargslist] ')'
Guido van Rossum3d602e31996-07-21 02:33:56 +00001088 *
1089 */
Guido van Rossum47478871996-08-21 14:32:37 +00001090static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001091validate_parameters(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001092{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001093 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001094 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001095
Guido van Rossum3d602e31996-07-21 02:33:56 +00001096 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001097 res = (validate_lparen(CHILD(tree, 0))
1098 && validate_rparen(CHILD(tree, nch - 1)));
1099 if (res && (nch == 3))
1100 res = validate_varargslist(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001101 }
Fred Drakeff9ea482000-04-19 13:54:15 +00001102 else {
1103 (void) validate_numnodes(tree, 2, "parameters");
1104 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001105 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001106}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001107
1108
Guido van Rossum3d602e31996-07-21 02:33:56 +00001109/* VALIDATE(suite)
1110 *
1111 * suite:
Fred Drakeff9ea482000-04-19 13:54:15 +00001112 * simple_stmt
Guido van Rossum3d602e31996-07-21 02:33:56 +00001113 * | NEWLINE INDENT stmt+ DEDENT
1114 */
Guido van Rossum47478871996-08-21 14:32:37 +00001115static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001116validate_suite(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001117{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001118 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001119 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001120
Guido van Rossum3d602e31996-07-21 02:33:56 +00001121 if (res && (nch == 1))
Fred Drakeff9ea482000-04-19 13:54:15 +00001122 res = validate_simple_stmt(CHILD(tree, 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001123 else if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001124 /* NEWLINE INDENT stmt+ DEDENT */
1125 res = (validate_newline(CHILD(tree, 0))
1126 && validate_indent(CHILD(tree, 1))
1127 && validate_stmt(CHILD(tree, 2))
1128 && validate_dedent(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001129
Fred Drakeff9ea482000-04-19 13:54:15 +00001130 if (res && (nch > 4)) {
1131 int i = 3;
1132 --nch; /* forget the DEDENT */
1133 for ( ; res && (i < nch); ++i)
1134 res = validate_stmt(CHILD(tree, i));
1135 }
1136 else if (nch < 4)
1137 res = validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001138 }
1139 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001140}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001141
1142
Guido van Rossum47478871996-08-21 14:32:37 +00001143static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001144validate_testlist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001145{
Guido van Rossum47478871996-08-21 14:32:37 +00001146 return (validate_repeating_list(tree, testlist,
Fred Drakeff9ea482000-04-19 13:54:15 +00001147 validate_test, "testlist"));
1148}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001149
1150
Guido van Rossum3d602e31996-07-21 02:33:56 +00001151/* VALIDATE(varargslist)
1152 *
1153 * varargslist:
Fred Drakeff9ea482000-04-19 13:54:15 +00001154 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001155 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1156 *
1157 * (fpdef ['=' test] ',')*
1158 * ('*' NAME [',' ('**'|'*' '*') NAME]
1159 * | ('**'|'*' '*') NAME)
1160 * | 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);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001168
Guido van Rossum3d602e31996-07-21 02:33:56 +00001169 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001170 /* (fpdef ['=' test] ',')*
1171 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1172 */
1173 int pos = 0;
1174 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001175
Fred Drakeff9ea482000-04-19 13:54:15 +00001176 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1177 res = validate_fpdef(CHILD(tree, pos));
1178 if (res) {
1179 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1180 res = validate_test(CHILD(tree, pos + 2));
1181 pos += 2;
1182 }
1183 res = res && validate_comma(CHILD(tree, pos + 1));
1184 pos += 2;
1185 }
1186 }
1187 if (res) {
1188 remaining = nch - pos;
1189 res = ((remaining == 2) || (remaining == 3)
1190 || (remaining == 5) || (remaining == 6));
1191 if (!res)
1192 (void) validate_numnodes(tree, 2, "varargslist");
1193 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1194 return ((remaining == 2)
1195 && validate_ntype(CHILD(tree, pos+1), NAME));
1196 else {
1197 res = validate_star(CHILD(tree, pos++));
1198 --remaining;
1199 }
1200 }
1201 if (res) {
1202 if (remaining == 2) {
1203 res = (validate_star(CHILD(tree, pos))
1204 && validate_ntype(CHILD(tree, pos + 1), NAME));
1205 }
1206 else {
1207 res = validate_ntype(CHILD(tree, pos++), NAME);
1208 if (res && (remaining >= 4)) {
1209 res = validate_comma(CHILD(tree, pos));
1210 if (--remaining == 3)
1211 res = (validate_star(CHILD(tree, pos + 1))
1212 && validate_star(CHILD(tree, pos + 2)));
1213 else
1214 res = validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1215 }
1216 }
1217 }
1218 if (!res && !PyErr_Occurred())
1219 err_string("Incorrect validation of variable arguments list.");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001220 }
1221 else if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001222 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1223 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1224 --nch;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001225
Fred Drakeff9ea482000-04-19 13:54:15 +00001226 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1227 res = (is_odd(nch)
1228 && validate_fpdef(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001229
Fred Drakeff9ea482000-04-19 13:54:15 +00001230 if (res && (nch > 1)) {
1231 int pos = 1;
1232 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1233 res = validate_test(CHILD(tree, 2));
1234 pos += 2;
1235 }
1236 /* ... (',' fpdef ['=' test])* */
1237 for ( ; res && (pos < nch); pos += 2) {
1238 /* ',' fpdef */
1239 res = (validate_comma(CHILD(tree, pos))
1240 && validate_fpdef(CHILD(tree, pos + 1)));
1241 if (res
1242 && ((nch - pos) > 2)
1243 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1244 /* ['=' test] */
1245 res = validate_test(CHILD(tree, pos + 3));
1246 pos += 2;
1247 }
1248 }
1249 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001250 }
Fred Drakeff9ea482000-04-19 13:54:15 +00001251 else {
1252 err_string("Improperly formed argument list.");
1253 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001254 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001255}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001256
1257
Guido van Rossum3d602e31996-07-21 02:33:56 +00001258/* VALIDATE(fpdef)
1259 *
1260 * fpdef:
Fred Drakeff9ea482000-04-19 13:54:15 +00001261 * NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00001262 * | '(' fplist ')'
1263 */
Guido van Rossum47478871996-08-21 14:32:37 +00001264static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001265validate_fpdef(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001266{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001267 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001268 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001269
Guido van Rossum3d602e31996-07-21 02:33:56 +00001270 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001271 if (nch == 1)
1272 res = validate_ntype(CHILD(tree, 0), NAME);
1273 else if (nch == 3)
1274 res = (validate_lparen(CHILD(tree, 0))
1275 && validate_fplist(CHILD(tree, 1))
1276 && validate_rparen(CHILD(tree, 2)));
1277 else
1278 res = validate_numnodes(tree, 1, "fpdef");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001279 }
1280 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001281}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001282
1283
Guido van Rossum47478871996-08-21 14:32:37 +00001284static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001285validate_fplist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001286{
Guido van Rossum47478871996-08-21 14:32:37 +00001287 return (validate_repeating_list(tree, fplist,
Fred Drakeff9ea482000-04-19 13:54:15 +00001288 validate_fpdef, "fplist"));
1289}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001290
1291
Guido van Rossum3d602e31996-07-21 02:33:56 +00001292/* simple_stmt | compound_stmt
1293 *
1294 */
Guido van Rossum47478871996-08-21 14:32:37 +00001295static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001296validate_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001297{
1298 int res = (validate_ntype(tree, stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001299 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001300
Guido van Rossum3d602e31996-07-21 02:33:56 +00001301 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001302 tree = CHILD(tree, 0);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001303
Fred Drakeff9ea482000-04-19 13:54:15 +00001304 if (TYPE(tree) == simple_stmt)
1305 res = validate_simple_stmt(tree);
1306 else
1307 res = validate_compound_stmt(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001308 }
1309 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001310}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001311
1312
Guido van Rossum3d602e31996-07-21 02:33:56 +00001313/* small_stmt (';' small_stmt)* [';'] NEWLINE
1314 *
1315 */
Guido van Rossum47478871996-08-21 14:32:37 +00001316static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001317validate_simple_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001318{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001319 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001320 int res = (validate_ntype(tree, simple_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001321 && (nch >= 2)
1322 && validate_small_stmt(CHILD(tree, 0))
1323 && validate_newline(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001324
Guido van Rossum3d602e31996-07-21 02:33:56 +00001325 if (nch < 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001326 res = validate_numnodes(tree, 2, "simple_stmt");
1327 --nch; /* forget the NEWLINE */
Guido van Rossum3d602e31996-07-21 02:33:56 +00001328 if (res && is_even(nch))
Fred Drakeff9ea482000-04-19 13:54:15 +00001329 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001330 if (res && (nch > 2)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001331 int i;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001332
Fred Drakeff9ea482000-04-19 13:54:15 +00001333 for (i = 1; res && (i < nch); i += 2)
1334 res = (validate_semi(CHILD(tree, i))
1335 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001336 }
1337 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001338}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001339
1340
Guido van Rossum47478871996-08-21 14:32:37 +00001341static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001342validate_small_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001343{
1344 int nch = NCH(tree);
Fred Drakeff9ea482000-04-19 13:54:15 +00001345 int res = (validate_numnodes(tree, 1, "small_stmt")
1346 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1347 || (TYPE(CHILD(tree, 0)) == print_stmt)
1348 || (TYPE(CHILD(tree, 0)) == del_stmt)
1349 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1350 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1351 || (TYPE(CHILD(tree, 0)) == import_stmt)
1352 || (TYPE(CHILD(tree, 0)) == global_stmt)
1353 || (TYPE(CHILD(tree, 0)) == assert_stmt)
1354 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001355
1356 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001357 res = validate_node(CHILD(tree, 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001358 else if (nch == 1) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001359 char buffer[60];
1360 (void) sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1361 TYPE(CHILD(tree, 0)));
1362 err_string(buffer);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001363 }
1364 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001365}
Guido van Rossum3d602e31996-07-21 02:33:56 +00001366
1367
1368/* compound_stmt:
Fred Drakeff9ea482000-04-19 13:54:15 +00001369 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
Guido van Rossum3d602e31996-07-21 02:33:56 +00001370 */
Guido van Rossum47478871996-08-21 14:32:37 +00001371static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001372validate_compound_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001373{
1374 int res = (validate_ntype(tree, compound_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001375 && validate_numnodes(tree, 1, "compound_stmt"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001376
1377 if (!res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001378 return (0);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001379
1380 tree = CHILD(tree, 0);
1381 res = ((TYPE(tree) == if_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001382 || (TYPE(tree) == while_stmt)
1383 || (TYPE(tree) == for_stmt)
1384 || (TYPE(tree) == try_stmt)
1385 || (TYPE(tree) == funcdef)
1386 || (TYPE(tree) == classdef));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001387 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001388 res = validate_node(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001389 else {
Fred Drakeff9ea482000-04-19 13:54:15 +00001390 char buffer[60];
1391 (void) sprintf(buffer, "Illegal compound statement type: %d.",
1392 TYPE(tree));
1393 err_string(buffer);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001394 }
1395 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001396}
Guido van Rossum3d602e31996-07-21 02:33:56 +00001397
1398
Guido van Rossum47478871996-08-21 14:32:37 +00001399static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001400validate_expr_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001401{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001402 int j;
1403 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001404 int res = (validate_ntype(tree, expr_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001405 && is_odd(nch)
1406 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001407
Guido van Rossum3d602e31996-07-21 02:33:56 +00001408 for (j = 1; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001409 res = (validate_equal(CHILD(tree, j))
1410 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001411
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001412 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001413}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001414
1415
Guido van Rossum3d602e31996-07-21 02:33:56 +00001416/* print_stmt:
1417 *
Fred Drakeff9ea482000-04-19 13:54:15 +00001418 * 'print' (test ',')* [test]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001419 *
1420 */
Guido van Rossum47478871996-08-21 14:32:37 +00001421static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001422validate_print_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001423{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001424 int j;
1425 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001426 int res = (validate_ntype(tree, print_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001427 && (nch != 0)
1428 && validate_name(CHILD(tree, 0), "print"));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001429
1430 if (res && is_even(nch)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001431 res = validate_test(CHILD(tree, nch - 1));
1432 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001433 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001434 else if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00001435 (void) validate_numnodes(tree, 1, "print_stmt");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001436 for (j = 1; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001437 res = (validate_test(CHILD(tree, j))
1438 && validate_ntype(CHILD(tree, j + 1), COMMA));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001439
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001440 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001441}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001442
1443
Guido van Rossum47478871996-08-21 14:32:37 +00001444static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001445validate_del_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001446{
1447 return (validate_numnodes(tree, 2, "del_stmt")
Fred Drakeff9ea482000-04-19 13:54:15 +00001448 && validate_name(CHILD(tree, 0), "del")
1449 && validate_exprlist(CHILD(tree, 1)));
1450}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001451
1452
Guido van Rossum47478871996-08-21 14:32:37 +00001453static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001454validate_return_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001455{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001456 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001457 int res = (validate_ntype(tree, return_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001458 && ((nch == 1) || (nch == 2))
1459 && validate_name(CHILD(tree, 0), "return"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001460
Guido van Rossum3d602e31996-07-21 02:33:56 +00001461 if (res && (nch == 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00001462 res = validate_testlist(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001463
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001464 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001465}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001466
1467
Guido van Rossum47478871996-08-21 14:32:37 +00001468static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001469validate_raise_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001470{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001471 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001472 int res = (validate_ntype(tree, raise_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001473 && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001474
Guido van Rossum3d602e31996-07-21 02:33:56 +00001475 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001476 res = validate_name(CHILD(tree, 0), "raise");
1477 if (res && (nch >= 2))
1478 res = validate_test(CHILD(tree, 1));
1479 if (res && nch > 2) {
1480 res = (validate_comma(CHILD(tree, 2))
1481 && validate_test(CHILD(tree, 3)));
1482 if (res && (nch > 4))
1483 res = (validate_comma(CHILD(tree, 4))
1484 && validate_test(CHILD(tree, 5)));
1485 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001486 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001487 else
Fred Drakeff9ea482000-04-19 13:54:15 +00001488 (void) validate_numnodes(tree, 2, "raise");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001489 if (res && (nch == 4))
Fred Drakeff9ea482000-04-19 13:54:15 +00001490 res = (validate_comma(CHILD(tree, 2))
1491 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001492
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001493 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001494}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001495
1496
Guido van Rossum3d602e31996-07-21 02:33:56 +00001497/* import_stmt:
1498 *
1499 * 'import' dotted_name (',' dotted_name)*
1500 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1501 */
Guido van Rossum47478871996-08-21 14:32:37 +00001502static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001503validate_import_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001504{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001505 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001506 int res = (validate_ntype(tree, import_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001507 && (nch >= 2) && is_even(nch)
1508 && validate_ntype(CHILD(tree, 0), NAME)
1509 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001510
1511 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001512 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001513
Fred Drakeff9ea482000-04-19 13:54:15 +00001514 for (j = 2; res && (j < nch); j += 2)
1515 res = (validate_comma(CHILD(tree, j))
1516 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001517 }
1518 else if (res && validate_name(CHILD(tree, 0), "from")) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001519 res = ((nch >= 4) && is_even(nch)
1520 && validate_name(CHILD(tree, 2), "import"));
1521 if (nch == 4) {
1522 res = ((TYPE(CHILD(tree, 3)) == NAME)
1523 || (TYPE(CHILD(tree, 3)) == STAR));
1524 if (!res)
1525 err_string("Illegal import statement.");
1526 }
1527 else {
1528 /* 'from' NAME 'import' NAME (',' NAME)+ */
1529 int j;
1530 res = validate_ntype(CHILD(tree, 3), NAME);
1531 for (j = 4; res && (j < nch); j += 2)
1532 res = (validate_comma(CHILD(tree, j))
1533 && validate_ntype(CHILD(tree, j + 1), NAME));
1534 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001535 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001536 else
Fred Drakeff9ea482000-04-19 13:54:15 +00001537 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001538
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001539 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001540}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001541
1542
Guido van Rossum47478871996-08-21 14:32:37 +00001543static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001544validate_global_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001545{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001546 int j;
1547 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001548 int res = (validate_ntype(tree, global_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001549 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001550
Guido van Rossum3d602e31996-07-21 02:33:56 +00001551 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001552 res = (validate_name(CHILD(tree, 0), "global")
1553 && validate_ntype(CHILD(tree, 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001554 for (j = 2; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001555 res = (validate_comma(CHILD(tree, j))
1556 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001557
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001558 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001559}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001560
1561
Guido van Rossum3d602e31996-07-21 02:33:56 +00001562/* exec_stmt:
1563 *
1564 * 'exec' expr ['in' test [',' test]]
1565 */
Guido van Rossum47478871996-08-21 14:32:37 +00001566static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001567validate_exec_stmt(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001568{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001569 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001570 int res = (validate_ntype(tree, exec_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001571 && ((nch == 2) || (nch == 4) || (nch == 6))
1572 && validate_name(CHILD(tree, 0), "exec")
1573 && validate_expr(CHILD(tree, 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001574
Guido van Rossum3d602e31996-07-21 02:33:56 +00001575 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00001576 err_string("Illegal exec statement.");
Guido van Rossum3d602e31996-07-21 02:33:56 +00001577 if (res && (nch > 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00001578 res = (validate_name(CHILD(tree, 2), "in")
1579 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001580 if (res && (nch == 6))
Fred Drakeff9ea482000-04-19 13:54:15 +00001581 res = (validate_comma(CHILD(tree, 4))
1582 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001583
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001584 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001585}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001586
1587
Guido van Rossum925e5471997-04-02 05:32:13 +00001588/* assert_stmt:
1589 *
1590 * 'assert' test [',' test]
1591 */
1592static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001593validate_assert_stmt(node *tree)
Guido van Rossum925e5471997-04-02 05:32:13 +00001594{
1595 int nch = NCH(tree);
1596 int res = (validate_ntype(tree, assert_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001597 && ((nch == 2) || (nch == 4))
1598 && (validate_name(CHILD(tree, 0), "__assert__") ||
1599 validate_name(CHILD(tree, 0), "assert"))
1600 && validate_test(CHILD(tree, 1)));
Guido van Rossum925e5471997-04-02 05:32:13 +00001601
1602 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00001603 err_string("Illegal assert statement.");
Guido van Rossum925e5471997-04-02 05:32:13 +00001604 if (res && (nch > 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00001605 res = (validate_comma(CHILD(tree, 2))
1606 && validate_test(CHILD(tree, 3)));
Guido van Rossum925e5471997-04-02 05:32:13 +00001607
1608 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001609}
Guido van Rossum925e5471997-04-02 05:32:13 +00001610
1611
Guido van Rossum47478871996-08-21 14:32:37 +00001612static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001613validate_while(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001614{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001615 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001616 int res = (validate_ntype(tree, while_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001617 && ((nch == 4) || (nch == 7))
1618 && validate_name(CHILD(tree, 0), "while")
1619 && validate_test(CHILD(tree, 1))
1620 && validate_colon(CHILD(tree, 2))
1621 && validate_suite(CHILD(tree, 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001622
Guido van Rossum3d602e31996-07-21 02:33:56 +00001623 if (res && (nch == 7))
Fred Drakeff9ea482000-04-19 13:54:15 +00001624 res = (validate_name(CHILD(tree, 4), "else")
1625 && validate_colon(CHILD(tree, 5))
1626 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001627
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001628 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001629}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001630
1631
Guido van Rossum47478871996-08-21 14:32:37 +00001632static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001633validate_for(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001634{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001635 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001636 int res = (validate_ntype(tree, for_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001637 && ((nch == 6) || (nch == 9))
1638 && validate_name(CHILD(tree, 0), "for")
1639 && validate_exprlist(CHILD(tree, 1))
1640 && validate_name(CHILD(tree, 2), "in")
1641 && validate_testlist(CHILD(tree, 3))
1642 && validate_colon(CHILD(tree, 4))
1643 && validate_suite(CHILD(tree, 5)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001644
Guido van Rossum3d602e31996-07-21 02:33:56 +00001645 if (res && (nch == 9))
Fred Drakeff9ea482000-04-19 13:54:15 +00001646 res = (validate_name(CHILD(tree, 6), "else")
1647 && validate_colon(CHILD(tree, 7))
1648 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001649
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001650 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001651}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001652
1653
Guido van Rossum3d602e31996-07-21 02:33:56 +00001654/* try_stmt:
Fred Drakeff9ea482000-04-19 13:54:15 +00001655 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001656 * | 'try' ':' suite 'finally' ':' suite
1657 *
1658 */
Guido van Rossum47478871996-08-21 14:32:37 +00001659static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001660validate_try(tree)
1661 node *tree;
1662{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001663 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001664 int pos = 3;
1665 int res = (validate_ntype(tree, try_stmt)
Fred Drakeff9ea482000-04-19 13:54:15 +00001666 && (nch >= 6) && ((nch % 3) == 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001667
1668 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00001669 res = (validate_name(CHILD(tree, 0), "try")
1670 && validate_colon(CHILD(tree, 1))
1671 && validate_suite(CHILD(tree, 2))
1672 && validate_colon(CHILD(tree, nch - 2))
1673 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001674 else {
Fred Drakeff9ea482000-04-19 13:54:15 +00001675 const char* name = "execpt";
1676 char buffer[60];
1677 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1678 name = STR(CHILD(tree, nch - 3));
1679 (void) sprintf(buffer,
1680 "Illegal number of children for try/%s node.", name);
1681 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001682 }
Fred Drakeff9ea482000-04-19 13:54:15 +00001683 /* Skip past except_clause sections: */
Guido van Rossum3d602e31996-07-21 02:33:56 +00001684 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001685 res = (validate_except_clause(CHILD(tree, pos))
1686 && validate_colon(CHILD(tree, pos + 1))
1687 && validate_suite(CHILD(tree, pos + 2)));
1688 pos += 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001689 }
1690 if (res && (pos < nch)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001691 res = validate_ntype(CHILD(tree, pos), NAME);
1692 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1693 res = (validate_numnodes(tree, 6, "try/finally")
1694 && validate_colon(CHILD(tree, 4))
1695 && validate_suite(CHILD(tree, 5)));
1696 else if (res) {
1697 if (nch == (pos + 3)) {
1698 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1699 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1700 if (!res)
1701 err_string("Illegal trailing triple in try statement.");
1702 }
1703 else if (nch == (pos + 6)) {
1704 res = (validate_name(CHILD(tree, pos), "except")
1705 && validate_colon(CHILD(tree, pos + 1))
1706 && validate_suite(CHILD(tree, pos + 2))
1707 && validate_name(CHILD(tree, pos + 3), "else"));
1708 }
1709 else
1710 res = validate_numnodes(tree, pos + 3, "try/except");
1711 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001712 }
1713 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001714}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001715
1716
Guido van Rossum47478871996-08-21 14:32:37 +00001717static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001718validate_except_clause(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001719{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001720 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001721 int res = (validate_ntype(tree, except_clause)
Fred Drakeff9ea482000-04-19 13:54:15 +00001722 && ((nch == 1) || (nch == 2) || (nch == 4))
1723 && validate_name(CHILD(tree, 0), "except"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001724
Guido van Rossum3d602e31996-07-21 02:33:56 +00001725 if (res && (nch > 1))
Fred Drakeff9ea482000-04-19 13:54:15 +00001726 res = validate_test(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001727 if (res && (nch == 4))
Fred Drakeff9ea482000-04-19 13:54:15 +00001728 res = (validate_comma(CHILD(tree, 2))
1729 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001730
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001731 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001732}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001733
1734
Guido van Rossum47478871996-08-21 14:32:37 +00001735static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001736validate_test(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001737{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001738 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001739 int res = validate_ntype(tree, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001740
Guido van Rossum3d602e31996-07-21 02:33:56 +00001741 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Fred Drakeff9ea482000-04-19 13:54:15 +00001742 res = ((nch == 1)
1743 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001744 else if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001745 int pos;
1746 res = validate_and_test(CHILD(tree, 0));
1747 for (pos = 1; res && (pos < nch); pos += 2)
1748 res = (validate_name(CHILD(tree, pos), "or")
1749 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001750 }
1751 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001752}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001753
1754
Guido van Rossum47478871996-08-21 14:32:37 +00001755static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001756validate_and_test(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001757{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001758 int pos;
1759 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001760 int res = (validate_ntype(tree, and_test)
Fred Drakeff9ea482000-04-19 13:54:15 +00001761 && is_odd(nch)
1762 && validate_not_test(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001763
Guido van Rossum3d602e31996-07-21 02:33:56 +00001764 for (pos = 1; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001765 res = (validate_name(CHILD(tree, pos), "and")
1766 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001767
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001768 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001769}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001770
1771
Guido van Rossum47478871996-08-21 14:32:37 +00001772static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001773validate_not_test(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001774{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001775 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001776 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001777
Guido van Rossum3d602e31996-07-21 02:33:56 +00001778 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001779 if (nch == 2)
1780 res = (validate_name(CHILD(tree, 0), "not")
1781 && validate_not_test(CHILD(tree, 1)));
1782 else if (nch == 1)
1783 res = validate_comparison(CHILD(tree, 0));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001784 }
1785 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001786}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001787
1788
Guido van Rossum47478871996-08-21 14:32:37 +00001789static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001790validate_comparison(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001791{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001792 int pos;
1793 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001794 int res = (validate_ntype(tree, comparison)
Fred Drakeff9ea482000-04-19 13:54:15 +00001795 && is_odd(nch)
1796 && validate_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001797
Guido van Rossum3d602e31996-07-21 02:33:56 +00001798 for (pos = 1; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001799 res = (validate_comp_op(CHILD(tree, pos))
1800 && validate_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001801
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001802 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001803}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001804
1805
Guido van Rossum47478871996-08-21 14:32:37 +00001806static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001807validate_comp_op(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001808{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001809 int res = 0;
1810 int nch = NCH(tree);
1811
Guido van Rossum3d602e31996-07-21 02:33:56 +00001812 if (!validate_ntype(tree, comp_op))
Fred Drakeff9ea482000-04-19 13:54:15 +00001813 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001814 if (nch == 1) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001815 /*
1816 * Only child will be a terminal with a well-defined symbolic name
1817 * or a NAME with a string of either 'is' or 'in'
1818 */
1819 tree = CHILD(tree, 0);
1820 switch (TYPE(tree)) {
1821 case LESS:
1822 case GREATER:
1823 case EQEQUAL:
1824 case EQUAL:
1825 case LESSEQUAL:
1826 case GREATEREQUAL:
1827 case NOTEQUAL:
1828 res = 1;
1829 break;
1830 case NAME:
1831 res = ((strcmp(STR(tree), "in") == 0)
1832 || (strcmp(STR(tree), "is") == 0));
1833 if (!res) {
1834 char buff[128];
1835 (void) sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1836 err_string(buff);
1837 }
1838 break;
1839 default:
1840 err_string("Illegal comparison operator type.");
1841 break;
1842 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001843 }
Guido van Rossuma376cc51996-12-05 23:43:35 +00001844 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001845 res = (validate_ntype(CHILD(tree, 0), NAME)
1846 && validate_ntype(CHILD(tree, 1), NAME)
1847 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1848 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1849 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1850 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
1851 if (!res && !PyErr_Occurred())
1852 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001853 }
1854 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001855}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001856
1857
Guido van Rossum47478871996-08-21 14:32:37 +00001858static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001859validate_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001860{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001861 int j;
1862 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001863 int res = (validate_ntype(tree, expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00001864 && is_odd(nch)
1865 && validate_xor_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001866
Guido van Rossum3d602e31996-07-21 02:33:56 +00001867 for (j = 2; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001868 res = (validate_xor_expr(CHILD(tree, j))
1869 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001870
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001871 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001872}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001873
1874
Guido van Rossum47478871996-08-21 14:32:37 +00001875static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001876validate_xor_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001877{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001878 int j;
1879 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001880 int res = (validate_ntype(tree, xor_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00001881 && is_odd(nch)
1882 && validate_and_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001883
Guido van Rossum3d602e31996-07-21 02:33:56 +00001884 for (j = 2; res && (j < nch); j += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001885 res = (validate_circumflex(CHILD(tree, j - 1))
1886 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001887
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001888 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001889}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001890
1891
Guido van Rossum47478871996-08-21 14:32:37 +00001892static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001893validate_and_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001894{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001895 int pos;
1896 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001897 int res = (validate_ntype(tree, and_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00001898 && is_odd(nch)
1899 && validate_shift_expr(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001900
Guido van Rossum3d602e31996-07-21 02:33:56 +00001901 for (pos = 1; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001902 res = (validate_ampersand(CHILD(tree, pos))
1903 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001904
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001905 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001906}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001907
1908
1909static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001910validate_chain_two_ops(tree, termvalid, op1, op2)
1911 node *tree;
1912 int (*termvalid)();
1913 int op1;
1914 int op2;
1915 {
1916 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001917 int nch = NCH(tree);
1918 int res = (is_odd(nch)
Fred Drakeff9ea482000-04-19 13:54:15 +00001919 && (*termvalid)(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001920
Guido van Rossum3d602e31996-07-21 02:33:56 +00001921 for ( ; res && (pos < nch); pos += 2) {
Fred Drakeff9ea482000-04-19 13:54:15 +00001922 if (TYPE(CHILD(tree, pos)) != op1)
1923 res = validate_ntype(CHILD(tree, pos), op2);
1924 if (res)
1925 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001926 }
1927 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001928}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001929
1930
Guido van Rossum47478871996-08-21 14:32:37 +00001931static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001932validate_shift_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001933{
1934 return (validate_ntype(tree, shift_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00001935 && validate_chain_two_ops(tree, validate_arith_expr,
1936 LEFTSHIFT, RIGHTSHIFT));
1937}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001938
1939
Guido van Rossum47478871996-08-21 14:32:37 +00001940static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001941validate_arith_expr(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001942{
1943 return (validate_ntype(tree, arith_expr)
Fred Drakeff9ea482000-04-19 13:54:15 +00001944 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
1945}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001946
1947
Guido van Rossum47478871996-08-21 14:32:37 +00001948static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001949validate_term(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001950{
1951 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001952 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001953 int res = (validate_ntype(tree, term)
Fred Drakeff9ea482000-04-19 13:54:15 +00001954 && is_odd(nch)
1955 && validate_factor(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001956
Guido van Rossum3d602e31996-07-21 02:33:56 +00001957 for ( ; res && (pos < nch); pos += 2)
Fred Drakeff9ea482000-04-19 13:54:15 +00001958 res = (((TYPE(CHILD(tree, pos)) == STAR)
1959 || (TYPE(CHILD(tree, pos)) == SLASH)
1960 || (TYPE(CHILD(tree, pos)) == PERCENT))
1961 && validate_factor(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001962
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001963 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001964}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001965
1966
Guido van Rossum3d602e31996-07-21 02:33:56 +00001967/* factor:
1968 *
1969 * factor: ('+'|'-'|'~') factor | power
1970 */
Guido van Rossum47478871996-08-21 14:32:37 +00001971static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001972validate_factor(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001973{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001974 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001975 int res = (validate_ntype(tree, factor)
Fred Drakeff9ea482000-04-19 13:54:15 +00001976 && (((nch == 2)
1977 && ((TYPE(CHILD(tree, 0)) == PLUS)
1978 || (TYPE(CHILD(tree, 0)) == MINUS)
1979 || (TYPE(CHILD(tree, 0)) == TILDE))
1980 && validate_factor(CHILD(tree, 1)))
1981 || ((nch == 1)
1982 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001983 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00001984}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001985
1986
Guido van Rossum3d602e31996-07-21 02:33:56 +00001987/* power:
1988 *
1989 * power: atom trailer* ('**' factor)*
1990 */
Guido van Rossum47478871996-08-21 14:32:37 +00001991static int
Fred Drakeff9ea482000-04-19 13:54:15 +00001992validate_power(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001993{
1994 int pos = 1;
1995 int nch = NCH(tree);
1996 int res = (validate_ntype(tree, power) && (nch >= 1)
Fred Drakeff9ea482000-04-19 13:54:15 +00001997 && validate_atom(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001998
1999 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
Fred Drakeff9ea482000-04-19 13:54:15 +00002000 res = validate_trailer(CHILD(tree, pos++));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002001 if (res && (pos < nch)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002002 if (!is_even(nch - pos)) {
2003 err_string("Illegal number of nodes for 'power'.");
2004 return (0);
2005 }
2006 for ( ; res && (pos < (nch - 1)); pos += 2)
2007 res = (validate_doublestar(CHILD(tree, pos))
2008 && validate_factor(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002009 }
2010 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002011}
Guido van Rossum3d602e31996-07-21 02:33:56 +00002012
2013
Guido van Rossum47478871996-08-21 14:32:37 +00002014static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002015validate_atom(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002016{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002017 int pos;
2018 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002019 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002020
2021 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002022 switch (TYPE(CHILD(tree, 0))) {
2023 case LPAR:
2024 res = ((nch <= 3)
2025 && (validate_rparen(CHILD(tree, nch - 1))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002026
Fred Drakeff9ea482000-04-19 13:54:15 +00002027 if (res && (nch == 3))
2028 res = validate_testlist(CHILD(tree, 1));
2029 break;
2030 case LSQB:
2031 res = ((nch <= 3)
2032 && validate_ntype(CHILD(tree, nch - 1), RSQB));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002033
Fred Drakeff9ea482000-04-19 13:54:15 +00002034 if (res && (nch == 3))
2035 res = validate_testlist(CHILD(tree, 1));
2036 break;
2037 case LBRACE:
2038 res = ((nch <= 3)
2039 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002040
Fred Drakeff9ea482000-04-19 13:54:15 +00002041 if (res && (nch == 3))
2042 res = validate_dictmaker(CHILD(tree, 1));
2043 break;
2044 case BACKQUOTE:
2045 res = ((nch == 3)
2046 && validate_testlist(CHILD(tree, 1))
2047 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2048 break;
2049 case NAME:
2050 case NUMBER:
2051 res = (nch == 1);
2052 break;
2053 case STRING:
2054 for (pos = 1; res && (pos < nch); ++pos)
2055 res = validate_ntype(CHILD(tree, pos), STRING);
2056 break;
2057 default:
2058 res = 0;
2059 break;
2060 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002061 }
2062 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002063}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002064
2065
Guido van Rossum3d602e31996-07-21 02:33:56 +00002066/* funcdef:
Fred Drakeff9ea482000-04-19 13:54:15 +00002067 * 'def' NAME parameters ':' suite
Guido van Rossum3d602e31996-07-21 02:33:56 +00002068 *
2069 */
Guido van Rossum47478871996-08-21 14:32:37 +00002070static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002071validate_funcdef(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002072{
2073 return (validate_ntype(tree, funcdef)
Fred Drakeff9ea482000-04-19 13:54:15 +00002074 && validate_numnodes(tree, 5, "funcdef")
2075 && validate_name(CHILD(tree, 0), "def")
2076 && validate_ntype(CHILD(tree, 1), NAME)
2077 && validate_colon(CHILD(tree, 3))
2078 && validate_parameters(CHILD(tree, 2))
2079 && validate_suite(CHILD(tree, 4)));
2080}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002081
2082
Guido van Rossum47478871996-08-21 14:32:37 +00002083static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002084validate_lambdef(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002085{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002086 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002087 int res = (validate_ntype(tree, lambdef)
Fred Drakeff9ea482000-04-19 13:54:15 +00002088 && ((nch == 3) || (nch == 4))
2089 && validate_name(CHILD(tree, 0), "lambda")
2090 && validate_colon(CHILD(tree, nch - 2))
2091 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002092
Guido van Rossum3d602e31996-07-21 02:33:56 +00002093 if (res && (nch == 4))
Fred Drakeff9ea482000-04-19 13:54:15 +00002094 res = validate_varargslist(CHILD(tree, 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002095 else if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00002096 (void) validate_numnodes(tree, 3, "lambdef");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002097
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002098 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002099}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002100
2101
Guido van Rossum3d602e31996-07-21 02:33:56 +00002102/* arglist:
2103 *
Fred Drakee7ab64e2000-04-25 04:14:46 +00002104 * (argument ',')* (argument* [','] | '*' test [',' '**' test] | '**' test)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002105 */
Guido van Rossum47478871996-08-21 14:32:37 +00002106static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002107validate_arglist(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002108{
Fred Drakee7ab64e2000-04-25 04:14:46 +00002109 int nch = NCH(tree);
2110 int i, ok;
2111 node *last;
2112
2113 if (nch <= 0)
2114 /* raise the right error from having an invalid number of children */
2115 return validate_numnodes(tree, nch + 1, "arglist");
2116
2117 last = CHILD(tree, nch - 1);
2118 if (TYPE(last) == test) {
2119 /* Extended call syntax introduced in Python 1.6 has been used;
2120 * validate and strip that off and continue;
2121 * adjust nch to perform the cut, and ensure resulting nch is even
2122 * (validation of the first part doesn't require that).
2123 */
2124 if (nch < 2) {
2125 validate_numnodes(tree, nch + 1, "arglist");
2126 return 0;
2127 }
2128 ok = validate_test(last);
2129 if (ok) {
2130 node *prev = CHILD(tree, nch - 2);
2131 /* next must be '*' or '**' */
2132 if (validate_doublestar(prev)) {
2133 nch -= 2;
2134 if (nch >= 3) {
2135 /* may include: '*' test ',' */
2136 last = CHILD(tree, nch - 1);
2137 prev = CHILD(tree, nch - 2);
2138 if (TYPE(prev) == test) {
2139 ok = validate_comma(last)
2140 && validate_test(prev)
2141 && validate_star(CHILD(tree, nch - 3));
2142 if (ok)
2143 nch -= 3;
2144 }
2145 /* otherwise, nothing special */
2146 }
2147 }
2148 else {
2149 /* must be only: '*' test */
2150 PyErr_Clear();
2151 ok = validate_star(prev);
2152 nch -= 2;
2153 }
2154 if (ok && is_odd(nch)) {
2155 /* Illegal number of nodes before extended call syntax;
2156 * validation of the "normal" arguments does not require
2157 * a trailing comma, but requiring an even number of
2158 * children will effect the same requirement.
2159 */
2160 return validate_numnodes(tree, nch + 1, "arglist");
2161 }
2162 }
2163 }
2164 /* what remains must be: (argument ",")* [argument [","]] */
2165 i = 0;
2166 while (ok && nch - i >= 2) {
2167 ok = validate_argument(CHILD(tree, i))
2168 && validate_comma(CHILD(tree, i + 1));
2169 i += 2;
2170 }
2171 if (ok && i < nch) {
2172 ok = validate_comma(CHILD(tree, i));
2173 ++i;
2174 }
2175 if (i != nch) {
2176 /* internal error! */
2177 ok = 0;
2178 err_string("arglist: internal error; nch != i");
2179 }
2180 return (ok);
Fred Drakeff9ea482000-04-19 13:54:15 +00002181}
Guido van Rossum3d602e31996-07-21 02:33:56 +00002182
2183
2184
2185/* argument:
2186 *
2187 * [test '='] test
2188 */
Guido van Rossum47478871996-08-21 14:32:37 +00002189static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002190validate_argument(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002191{
2192 int nch = NCH(tree);
2193 int res = (validate_ntype(tree, argument)
Fred Drakeff9ea482000-04-19 13:54:15 +00002194 && ((nch == 1) || (nch == 3))
2195 && validate_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002196
2197 if (res && (nch == 3))
Fred Drakeff9ea482000-04-19 13:54:15 +00002198 res = (validate_equal(CHILD(tree, 1))
2199 && validate_test(CHILD(tree, 2)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002200
2201 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002202}
Guido van Rossum3d602e31996-07-21 02:33:56 +00002203
2204
2205
2206/* trailer:
2207 *
Guido van Rossum47478871996-08-21 14:32:37 +00002208 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
Guido van Rossum3d602e31996-07-21 02:33:56 +00002209 */
Guido van Rossum47478871996-08-21 14:32:37 +00002210static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002211validate_trailer(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002212{
2213 int nch = NCH(tree);
2214 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002215
2216 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002217 switch (TYPE(CHILD(tree, 0))) {
2218 case LPAR:
2219 res = validate_rparen(CHILD(tree, nch - 1));
2220 if (res && (nch == 3))
2221 res = validate_arglist(CHILD(tree, 1));
2222 break;
2223 case LSQB:
2224 res = (validate_numnodes(tree, 3, "trailer")
2225 && validate_subscriptlist(CHILD(tree, 1))
2226 && validate_ntype(CHILD(tree, 2), RSQB));
2227 break;
2228 case DOT:
2229 res = (validate_numnodes(tree, 2, "trailer")
2230 && validate_ntype(CHILD(tree, 1), NAME));
2231 break;
2232 default:
2233 res = 0;
2234 break;
2235 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002236 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002237 else {
2238 (void) validate_numnodes(tree, 2, "trailer");
2239 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002240 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002241}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002242
2243
Guido van Rossum47478871996-08-21 14:32:37 +00002244/* subscriptlist:
2245 *
2246 * subscript (',' subscript)* [',']
2247 */
2248static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002249validate_subscriptlist(node *tree)
Guido van Rossum47478871996-08-21 14:32:37 +00002250{
2251 return (validate_repeating_list(tree, subscriptlist,
Fred Drakeff9ea482000-04-19 13:54:15 +00002252 validate_subscript, "subscriptlist"));
2253}
Guido van Rossum47478871996-08-21 14:32:37 +00002254
2255
Guido van Rossum3d602e31996-07-21 02:33:56 +00002256/* subscript:
2257 *
Guido van Rossum47478871996-08-21 14:32:37 +00002258 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
Guido van Rossum3d602e31996-07-21 02:33:56 +00002259 */
Guido van Rossum47478871996-08-21 14:32:37 +00002260static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002261validate_subscript(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002262{
Guido van Rossum47478871996-08-21 14:32:37 +00002263 int offset = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002264 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002265 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002266
Guido van Rossum47478871996-08-21 14:32:37 +00002267 if (!res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002268 if (!PyErr_Occurred())
2269 err_string("invalid number of arguments for subscript node");
2270 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002271 }
Guido van Rossum47478871996-08-21 14:32:37 +00002272 if (TYPE(CHILD(tree, 0)) == DOT)
Fred Drakeff9ea482000-04-19 13:54:15 +00002273 /* take care of ('.' '.' '.') possibility */
2274 return (validate_numnodes(tree, 3, "subscript")
2275 && validate_dot(CHILD(tree, 0))
2276 && validate_dot(CHILD(tree, 1))
2277 && validate_dot(CHILD(tree, 2)));
Guido van Rossum47478871996-08-21 14:32:37 +00002278 if (nch == 1) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002279 if (TYPE(CHILD(tree, 0)) == test)
2280 res = validate_test(CHILD(tree, 0));
2281 else
2282 res = validate_colon(CHILD(tree, 0));
2283 return (res);
Guido van Rossum47478871996-08-21 14:32:37 +00002284 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002285 /* Must be [test] ':' [test] [sliceop],
2286 * but at least one of the optional components will
2287 * be present, but we don't know which yet.
Guido van Rossum47478871996-08-21 14:32:37 +00002288 */
2289 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002290 res = validate_test(CHILD(tree, 0));
2291 offset = 1;
Guido van Rossum47478871996-08-21 14:32:37 +00002292 }
2293 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00002294 res = validate_colon(CHILD(tree, offset));
Guido van Rossum47478871996-08-21 14:32:37 +00002295 if (res) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002296 int rem = nch - ++offset;
2297 if (rem) {
2298 if (TYPE(CHILD(tree, offset)) == test) {
2299 res = validate_test(CHILD(tree, offset));
2300 ++offset;
2301 --rem;
2302 }
2303 if (res && rem)
2304 res = validate_sliceop(CHILD(tree, offset));
2305 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002306 }
2307 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002308}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002309
2310
Guido van Rossum47478871996-08-21 14:32:37 +00002311static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002312validate_sliceop(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002313{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002314 int nch = NCH(tree);
Guido van Rossum47478871996-08-21 14:32:37 +00002315 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
Fred Drakeff9ea482000-04-19 13:54:15 +00002316 && validate_ntype(tree, sliceop);
Guido van Rossum47478871996-08-21 14:32:37 +00002317 if (!res && !PyErr_Occurred()) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002318 res = validate_numnodes(tree, 1, "sliceop");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002319 }
Guido van Rossum47478871996-08-21 14:32:37 +00002320 if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00002321 res = validate_colon(CHILD(tree, 0));
Guido van Rossum47478871996-08-21 14:32:37 +00002322 if (res && (nch == 2))
Fred Drakeff9ea482000-04-19 13:54:15 +00002323 res = validate_test(CHILD(tree, 1));
Guido van Rossum47478871996-08-21 14:32:37 +00002324
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002325 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002326}
Guido van Rossum47478871996-08-21 14:32:37 +00002327
2328
2329static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002330validate_exprlist(node *tree)
Guido van Rossum47478871996-08-21 14:32:37 +00002331{
2332 return (validate_repeating_list(tree, exprlist,
Fred Drakeff9ea482000-04-19 13:54:15 +00002333 validate_expr, "exprlist"));
2334}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002335
2336
Guido van Rossum47478871996-08-21 14:32:37 +00002337static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002338validate_dictmaker(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002339{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002340 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002341 int res = (validate_ntype(tree, dictmaker)
Fred Drakeff9ea482000-04-19 13:54:15 +00002342 && (nch >= 3)
2343 && validate_test(CHILD(tree, 0))
2344 && validate_colon(CHILD(tree, 1))
2345 && validate_test(CHILD(tree, 2)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002346
Guido van Rossum3d602e31996-07-21 02:33:56 +00002347 if (res && ((nch % 4) == 0))
Fred Drakeff9ea482000-04-19 13:54:15 +00002348 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002349 else if (res)
Fred Drakeff9ea482000-04-19 13:54:15 +00002350 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002351
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002352 if (res && (nch > 3)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002353 int pos = 3;
2354 /* ( ',' test ':' test )* */
2355 while (res && (pos < nch)) {
2356 res = (validate_comma(CHILD(tree, pos))
2357 && validate_test(CHILD(tree, pos + 1))
2358 && validate_colon(CHILD(tree, pos + 2))
2359 && validate_test(CHILD(tree, pos + 3)));
2360 pos += 4;
2361 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002362 }
2363 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002364}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002365
2366
Guido van Rossum47478871996-08-21 14:32:37 +00002367static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002368validate_eval_input(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002369{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002370 int pos;
2371 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002372 int res = (validate_ntype(tree, eval_input)
Fred Drakeff9ea482000-04-19 13:54:15 +00002373 && (nch >= 2)
2374 && validate_testlist(CHILD(tree, 0))
2375 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002376
Guido van Rossum3d602e31996-07-21 02:33:56 +00002377 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Fred Drakeff9ea482000-04-19 13:54:15 +00002378 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002379
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002380 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002381}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002382
2383
Guido van Rossum47478871996-08-21 14:32:37 +00002384static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002385validate_node(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002386{
Fred Drakeff9ea482000-04-19 13:54:15 +00002387 int nch = 0; /* num. children on current node */
2388 int res = 1; /* result value */
2389 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002390
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002391 while (res & (tree != 0)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002392 nch = NCH(tree);
2393 next = 0;
2394 switch (TYPE(tree)) {
2395 /*
2396 * Definition nodes.
2397 */
2398 case funcdef:
2399 res = validate_funcdef(tree);
2400 break;
2401 case classdef:
2402 res = validate_class(tree);
2403 break;
2404 /*
2405 * "Trivial" parse tree nodes.
2406 * (Why did I call these trivial?)
2407 */
2408 case stmt:
2409 res = validate_stmt(tree);
2410 break;
2411 case small_stmt:
2412 /*
2413 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
2414 * | import_stmt | global_stmt | exec_stmt | assert_stmt
2415 */
2416 res = validate_small_stmt(tree);
2417 break;
2418 case flow_stmt:
2419 res = (validate_numnodes(tree, 1, "flow_stmt")
2420 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2421 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2422 || (TYPE(CHILD(tree, 0)) == return_stmt)
2423 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2424 if (res)
2425 next = CHILD(tree, 0);
2426 else if (nch == 1)
2427 err_string("Illegal flow_stmt type.");
2428 break;
2429 /*
2430 * Compound statements.
2431 */
2432 case simple_stmt:
2433 res = validate_simple_stmt(tree);
2434 break;
2435 case compound_stmt:
2436 res = validate_compound_stmt(tree);
2437 break;
2438 /*
2439 * Fundemental statements.
2440 */
2441 case expr_stmt:
2442 res = validate_expr_stmt(tree);
2443 break;
2444 case print_stmt:
2445 res = validate_print_stmt(tree);
2446 break;
2447 case del_stmt:
2448 res = validate_del_stmt(tree);
2449 break;
2450 case pass_stmt:
2451 res = (validate_numnodes(tree, 1, "pass")
2452 && validate_name(CHILD(tree, 0), "pass"));
2453 break;
2454 case break_stmt:
2455 res = (validate_numnodes(tree, 1, "break")
2456 && validate_name(CHILD(tree, 0), "break"));
2457 break;
2458 case continue_stmt:
2459 res = (validate_numnodes(tree, 1, "continue")
2460 && validate_name(CHILD(tree, 0), "continue"));
2461 break;
2462 case return_stmt:
2463 res = validate_return_stmt(tree);
2464 break;
2465 case raise_stmt:
2466 res = validate_raise_stmt(tree);
2467 break;
2468 case import_stmt:
2469 res = validate_import_stmt(tree);
2470 break;
2471 case global_stmt:
2472 res = validate_global_stmt(tree);
2473 break;
2474 case exec_stmt:
2475 res = validate_exec_stmt(tree);
2476 break;
2477 case assert_stmt:
2478 res = validate_assert_stmt(tree);
2479 break;
2480 case if_stmt:
2481 res = validate_if(tree);
2482 break;
2483 case while_stmt:
2484 res = validate_while(tree);
2485 break;
2486 case for_stmt:
2487 res = validate_for(tree);
2488 break;
2489 case try_stmt:
2490 res = validate_try(tree);
2491 break;
2492 case suite:
2493 res = validate_suite(tree);
2494 break;
2495 /*
2496 * Expression nodes.
2497 */
2498 case testlist:
2499 res = validate_testlist(tree);
2500 break;
2501 case test:
2502 res = validate_test(tree);
2503 break;
2504 case and_test:
2505 res = validate_and_test(tree);
2506 break;
2507 case not_test:
2508 res = validate_not_test(tree);
2509 break;
2510 case comparison:
2511 res = validate_comparison(tree);
2512 break;
2513 case exprlist:
2514 res = validate_exprlist(tree);
2515 break;
2516 case comp_op:
2517 res = validate_comp_op(tree);
2518 break;
2519 case expr:
2520 res = validate_expr(tree);
2521 break;
2522 case xor_expr:
2523 res = validate_xor_expr(tree);
2524 break;
2525 case and_expr:
2526 res = validate_and_expr(tree);
2527 break;
2528 case shift_expr:
2529 res = validate_shift_expr(tree);
2530 break;
2531 case arith_expr:
2532 res = validate_arith_expr(tree);
2533 break;
2534 case term:
2535 res = validate_term(tree);
2536 break;
2537 case factor:
2538 res = validate_factor(tree);
2539 break;
2540 case power:
2541 res = validate_power(tree);
2542 break;
2543 case atom:
2544 res = validate_atom(tree);
2545 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002546
Fred Drakeff9ea482000-04-19 13:54:15 +00002547 default:
2548 /* Hopefully never reached! */
2549 err_string("Unrecogniged node type.");
2550 res = 0;
2551 break;
2552 }
2553 tree = next;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002554 }
2555 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002556}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002557
2558
Guido van Rossum47478871996-08-21 14:32:37 +00002559static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002560validate_expr_tree(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002561{
2562 int res = validate_eval_input(tree);
2563
2564 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00002565 err_string("Could not validate expression tuple.");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002566
2567 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002568}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002569
2570
Guido van Rossum3d602e31996-07-21 02:33:56 +00002571/* file_input:
Fred Drakeff9ea482000-04-19 13:54:15 +00002572 * (NEWLINE | stmt)* ENDMARKER
Guido van Rossum3d602e31996-07-21 02:33:56 +00002573 */
Guido van Rossum47478871996-08-21 14:32:37 +00002574static int
Fred Drakeff9ea482000-04-19 13:54:15 +00002575validate_file_input(node *tree)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002576{
2577 int j = 0;
2578 int nch = NCH(tree) - 1;
2579 int res = ((nch >= 0)
Fred Drakeff9ea482000-04-19 13:54:15 +00002580 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002581
Guido van Rossum3d602e31996-07-21 02:33:56 +00002582 for ( ; res && (j < nch); ++j) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002583 if (TYPE(CHILD(tree, j)) == stmt)
2584 res = validate_stmt(CHILD(tree, j));
2585 else
2586 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002587 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002588 /* This stays in to prevent any internal failues from getting to the
2589 * user. Hopefully, this won't be needed. If a user reports getting
2590 * this, we have some debugging to do.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002591 */
2592 if (!res && !PyErr_Occurred())
Fred Drakeff9ea482000-04-19 13:54:15 +00002593 err_string("VALIDATION FAILURE: report this to the maintainer!.");
Guido van Rossum3d602e31996-07-21 02:33:56 +00002594
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002595 return (res);
Fred Drakeff9ea482000-04-19 13:54:15 +00002596}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002597
2598
Fred Drake43f8f9b1998-04-13 16:25:46 +00002599static PyObject*
2600pickle_constructor = NULL;
2601
2602
2603static PyObject*
Fred Drakeff9ea482000-04-19 13:54:15 +00002604parser__pickler(PyObject *self, PyObject *args)
Fred Drake43f8f9b1998-04-13 16:25:46 +00002605{
Fred Drake268397f1998-04-29 14:16:32 +00002606 NOTE(ARGUNUSED(self))
Fred Drake43f8f9b1998-04-13 16:25:46 +00002607 PyObject *result = NULL;
2608 PyObject *ast = NULL;
Fred Drake2a6875e1999-09-20 22:32:18 +00002609 PyObject *empty_dict = NULL;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002610
2611 if (PyArg_ParseTuple(args, "O!:_pickler", &PyAST_Type, &ast)) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002612 PyObject *newargs;
2613 PyObject *tuple;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002614
Fred Drake2a6875e1999-09-20 22:32:18 +00002615 if ((empty_dict = PyDict_New()) == NULL)
2616 goto finally;
2617 if ((newargs = Py_BuildValue("Oi", ast, 1)) == NULL)
Fred Drakeff9ea482000-04-19 13:54:15 +00002618 goto finally;
2619 tuple = parser_ast2tuple((PyAST_Object*)NULL, newargs, empty_dict);
2620 if (tuple != NULL) {
2621 result = Py_BuildValue("O(O)", pickle_constructor, tuple);
2622 Py_DECREF(tuple);
2623 }
Fred Drake2a6875e1999-09-20 22:32:18 +00002624 Py_DECREF(empty_dict);
Fred Drakeff9ea482000-04-19 13:54:15 +00002625 Py_DECREF(newargs);
Fred Drake43f8f9b1998-04-13 16:25:46 +00002626 }
2627 finally:
Fred Drake2a6875e1999-09-20 22:32:18 +00002628 Py_XDECREF(empty_dict);
2629
Fred Drake43f8f9b1998-04-13 16:25:46 +00002630 return (result);
Fred Drakeff9ea482000-04-19 13:54:15 +00002631}
Fred Drake43f8f9b1998-04-13 16:25:46 +00002632
2633
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002634/* Functions exported by this module. Most of this should probably
2635 * be converted into an AST object with methods, but that is better
2636 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002637 * We'd really have to write a wrapper around it all anyway to allow
2638 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002639 */
2640static PyMethodDef parser_functions[] = {
Fred Drakeff9ea482000-04-19 13:54:15 +00002641 {"ast2tuple", (PyCFunction)parser_ast2tuple, PUBLIC_METHOD_TYPE,
2642 "Creates a tuple-tree representation of an AST."},
2643 {"ast2list", (PyCFunction)parser_ast2list, PUBLIC_METHOD_TYPE,
2644 "Creates a list-tree representation of an AST."},
2645 {"compileast", (PyCFunction)parser_compileast, PUBLIC_METHOD_TYPE,
2646 "Compiles an AST object into a code object."},
2647 {"expr", (PyCFunction)parser_expr, PUBLIC_METHOD_TYPE,
2648 "Creates an AST object from an expression."},
2649 {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
2650 "Determines if an AST object was created from an expression."},
2651 {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
2652 "Determines if an AST object was created from a suite."},
2653 {"suite", (PyCFunction)parser_suite, PUBLIC_METHOD_TYPE,
2654 "Creates an AST object from a suite."},
2655 {"sequence2ast", (PyCFunction)parser_tuple2ast, PUBLIC_METHOD_TYPE,
2656 "Creates an AST object from a tree representation."},
2657 {"tuple2ast", (PyCFunction)parser_tuple2ast, PUBLIC_METHOD_TYPE,
2658 "Creates an AST object from a tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002659
Fred Drake43f8f9b1998-04-13 16:25:46 +00002660 /* private stuff: support pickle module */
Fred Drakeff9ea482000-04-19 13:54:15 +00002661 {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS,
Fred Drake43f8f9b1998-04-13 16:25:46 +00002662 "Returns the pickle magic to allow ast objects to be pickled."},
2663
Fred Drake268397f1998-04-29 14:16:32 +00002664 {NULL, NULL, 0, NULL}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002665 };
2666
2667
Guido van Rossum3886bb61998-12-04 18:50:17 +00002668DL_EXPORT(void)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002669initparser()
2670 {
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002671 PyObject* module;
2672 PyObject* dict;
Fred Drakeff9ea482000-04-19 13:54:15 +00002673
Guido van Rossumf2b2dac1997-01-23 23:29:44 +00002674 PyAST_Type.ob_type = &PyType_Type;
2675 module = Py_InitModule("parser", parser_functions);
2676 dict = PyModule_GetDict(module);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002677
Fred Drake7a15ba51999-09-09 14:21:52 +00002678 if (parser_error == 0)
2679 parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
2680 else
2681 puts("parser module initialized more than once!");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002682
2683 if ((parser_error == 0)
Fred Drakeff9ea482000-04-19 13:54:15 +00002684 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2685 /*
2686 * This is serious.
2687 */
2688 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002689 }
2690 /*
2691 * Nice to have, but don't cry if we fail.
2692 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002693 Py_INCREF(&PyAST_Type);
2694 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2695
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002696 PyDict_SetItemString(dict, "__copyright__",
Fred Drakeff9ea482000-04-19 13:54:15 +00002697 PyString_FromString(parser_copyright_string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002698 PyDict_SetItemString(dict, "__doc__",
Fred Drakeff9ea482000-04-19 13:54:15 +00002699 PyString_FromString(parser_doc_string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002700 PyDict_SetItemString(dict, "__version__",
Fred Drakeff9ea482000-04-19 13:54:15 +00002701 PyString_FromString(parser_version_string));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002702
Fred Drake43f8f9b1998-04-13 16:25:46 +00002703 /* register to support pickling */
2704 module = PyImport_ImportModule("copy_reg");
2705 if (module != NULL) {
Fred Drakeff9ea482000-04-19 13:54:15 +00002706 PyObject *func, *pickler;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002707
Fred Drakeff9ea482000-04-19 13:54:15 +00002708 func = PyObject_GetAttrString(module, "pickle");
2709 pickle_constructor = PyDict_GetItemString(dict, "sequence2ast");
2710 pickler = PyDict_GetItemString(dict, "_pickler");
2711 Py_XINCREF(pickle_constructor);
2712 if ((func != NULL) && (pickle_constructor != NULL)
2713 && (pickler != NULL)) {
2714 PyObject *res;
Fred Drake43f8f9b1998-04-13 16:25:46 +00002715
Fred Drakeff9ea482000-04-19 13:54:15 +00002716 res = PyObject_CallFunction(
2717 func, "OOO", &PyAST_Type, pickler, pickle_constructor);
2718 Py_XDECREF(res);
2719 }
2720 Py_XDECREF(func);
2721 Py_DECREF(module);
Fred Drake43f8f9b1998-04-13 16:25:46 +00002722 }
Fred Drakeff9ea482000-04-19 13:54:15 +00002723}