blob: bc6f5162d8730aaaad56362b51e11b11eefd761b [file] [log] [blame]
Guido van Rossum3d602e31996-07-21 02:33:56 +00001/* parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002 *
3 * Copyright 1995 by Fred L. Drake, Jr. and Virginia Polytechnic Institute
4 * and State University, Blacksburg, Virginia, USA. Portions copyright
5 * 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, The Netherlands.
6 * Copying is permitted under the terms associated with the main Python
7 * distribution, with the additional restriction that this additional notice
8 * be included and maintained on all distributed copies.
9 *
10 * This module serves to replace the original parser module written by
11 * Guido. The functionality is not matched precisely, but the original
12 * may be implemented on top of this. This is desirable since the source
13 * of the text to be parsed is now divorced from this interface.
14 *
15 * Unlike the prior interface, the ability to give a parse tree produced
16 * by Python code as a tuple to the compiler is enabled by this module.
17 * See the documentation for more details.
18 *
19 */
20
21#include "Python.h" /* general Python API */
22#include "graminit.h" /* symbols defined in the grammar */
23#include "node.h" /* internal parser structure */
24#include "token.h" /* token definitions */
25 /* ISTERMINAL() / ISNONTERMINAL() */
Guido van Rossum3d602e31996-07-21 02:33:56 +000026#include "compile.h" /* PyNode_Compile() */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000027
28/*
29 * All the "fudge" declarations are here:
Guido van Rossum3d602e31996-07-21 02:33:56 +000030 *
31 * This isn't part of the Python runtime, but it's in the library somewhere.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000032 * Where it is varies a bit, so just declare it.
33 */
Guido van Rossum3d602e31996-07-21 02:33:56 +000034extern char* strdup();
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000035
36
37
38/* String constants used to initialize module attributes.
39 *
40 */
41static char*
42parser_copyright_string
43= "Copyright 1995 by Virginia Polytechnic Institute & State University and\n"
44 "Fred L. Drake, Jr., Blacksburg, Virginia, USA. Portions copyright\n"
45 "1991-1995 by Stichting Mathematisch Centrum, Amsterdam, The Netherlands.";
46
47
48static char*
49parser_doc_string
50= "This is an interface to Python's internal parser.";
51
52static char*
Guido van Rossum3d602e31996-07-21 02:33:56 +000053parser_version_string = "0.3"; /* changed to match python version */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000054
55
Guido van Rossum3d602e31996-07-21 02:33:56 +000056/* The function below is copyrigthed by Stichting Mathematisch Centrum. The
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000057 * original copyright statement is included below, and continues to apply
58 * in full to the function immediately following. All other material is
59 * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
60 * Institute and State University. Changes were made to comply with the
61 * new naming conventions.
62 */
63
Guido van Rossum52f2c051993-11-10 12:53:24 +000064/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +000065Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
66The Netherlands.
Guido van Rossum52f2c051993-11-10 12:53:24 +000067
68 All Rights Reserved
69
Guido van Rossum3d602e31996-07-21 02:33:56 +000070Permission to use, copy, modify, and distribute this software and its
71documentation for any purpose and without fee is hereby granted,
Guido van Rossum52f2c051993-11-10 12:53:24 +000072provided that the above copyright notice appear in all copies and that
Guido van Rossum3d602e31996-07-21 02:33:56 +000073both that copyright notice and this permission notice appear in
Guido van Rossum52f2c051993-11-10 12:53:24 +000074supporting documentation, and that the names of Stichting Mathematisch
75Centrum or CWI not be used in advertising or publicity pertaining to
76distribution of the software without specific, written prior permission.
77
78STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
79THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
80FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
81FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
82WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
83ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
84OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
85
86******************************************************************/
87
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +000088static PyObject*
Guido van Rossum52f2c051993-11-10 12:53:24 +000089node2tuple(n)
Guido van Rossum3d602e31996-07-21 02:33:56 +000090 node *n;
91 {
92 if (n == NULL) {
93 Py_INCREF(Py_None);
94 return Py_None;
95 }
96 if (ISNONTERMINAL(TYPE(n))) {
97 int i;
98 PyObject *v, *w;
99 v = PyTuple_New(1 + NCH(n));
100 if (v == NULL)
101 return v;
102 w = PyInt_FromLong(TYPE(n));
103 if (w == NULL) {
104 Py_DECREF(v);
105 return NULL;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000106 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000107 PyTuple_SetItem(v, 0, w);
108 for (i = 0; i < NCH(n); i++) {
109 w = node2tuple(CHILD(n, i));
110 if (w == NULL) {
111 Py_DECREF(v);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000112 return NULL;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000113 }
114 PyTuple_SetItem(v, i+1, w);
Guido van Rossum52f2c051993-11-10 12:53:24 +0000115 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000116 return v;
117 }
118 else if (ISTERMINAL(TYPE(n))) {
119 return Py_BuildValue("(is)", TYPE(n), STR(n));
120 }
121 else {
122 PyErr_SetString(PyExc_SystemError,
123 "unrecognized parse tree node type");
124 return NULL;
125 }
Guido van Rossum52f2c051993-11-10 12:53:24 +0000126}
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000127/*
128 * End of material copyrighted by Stichting Mathematisch Centrum.
129 */
Guido van Rossum52f2c051993-11-10 12:53:24 +0000130
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000131
132
133/* There are two types of intermediate objects we're interested in:
134 * 'eval' and 'exec' types. These constants can be used in the ast_type
135 * field of the object type to identify which any given object represents.
136 * These should probably go in an external header to allow other extensions
137 * to use them, but then, we really should be using C++ too. ;-)
138 *
Guido van Rossum3d602e31996-07-21 02:33:56 +0000139 * The PyAST_FRAGMENT type is not currently supported. Maybe not useful?
140 * Haven't decided yet.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000141 */
142
143#define PyAST_EXPR 1
144#define PyAST_SUITE 2
145#define PyAST_FRAGMENT 3
146
147
148/* These are the internal objects and definitions required to implement the
149 * AST type. Most of the internal names are more reminiscent of the 'old'
150 * naming style, but the code uses the new naming convention.
151 */
152
153static PyObject*
154parser_error = 0;
155
156
157typedef struct _PyAST_Object {
158
159 PyObject_HEAD /* standard object header */
160 node* ast_node; /* the node* returned by the parser */
161 int ast_type; /* EXPR or SUITE ? */
162
163} PyAST_Object;
164
165
Guido van Rossum3d602e31996-07-21 02:33:56 +0000166staticforward void parser_free();
167staticforward int parser_compare();
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000168
169
170/* static */
171PyTypeObject PyAST_Type = {
172
173 PyObject_HEAD_INIT(&PyType_Type)
174 0,
175 "ast", /* tp_name */
176 sizeof(PyAST_Object), /* tp_basicsize */
177 0, /* tp_itemsize */
178 (destructor)parser_free, /* tp_dealloc */
179 0, /* tp_print */
180 0, /* tp_getattr */
181 0, /* tp_setattr */
182 (cmpfunc)parser_compare, /* tp_compare */
183 0, /* tp_repr */
184 0, /* tp_as_number */
185 0, /* tp_as_sequence */
186 0, /* tp_as_mapping */
187 0, /* tp_hash */
188 0, /* tp_call */
189 0 /* tp_str */
190
191}; /* PyAST_Type */
192
193
194static int
195parser_compare_nodes(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000196 node *left;
197 node *right;
198 {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000199 int j;
Guido van Rossum52f2c051993-11-10 12:53:24 +0000200
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000201 if (TYPE(left) < TYPE(right))
202 return (-1);
203
204 if (TYPE(right) < TYPE(left))
205 return (1);
206
207 if (ISTERMINAL(TYPE(left)))
208 return (strcmp(STR(left), STR(right)));
209
210 if (NCH(left) < NCH(right))
211 return (-1);
212
213 if (NCH(right) < NCH(left))
214 return (1);
215
216 for (j = 0; j < NCH(left); ++j) {
217 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
218
219 if (v)
220 return (v);
221 }
222 return (0);
223
224} /* parser_compare_nodes() */
225
226
227/* int parser_compare(PyAST_Object* left, PyAST_Object* right)
228 *
229 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
230 * This really just wraps a call to parser_compare_nodes() with some easy
231 * checks and protection code.
232 *
233 */
234static int
235parser_compare(left, right)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000236 PyAST_Object *left;
237 PyAST_Object *right;
238 {
239
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000240 if (left == right)
241 return (0);
242
243 if ((left == 0) || (right == 0))
244 return (-1);
245
246 return (parser_compare_nodes(left->ast_node, right->ast_node));
247
248} /* parser_compare() */
249
250
251/* parser_newastobject(node* ast)
252 *
253 * Allocates a new Python object representing an AST. This is simply the
254 * 'wrapper' object that holds a node* and allows it to be passed around in
255 * Python code.
256 *
257 */
258static PyObject*
259parser_newastobject(ast, type)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000260 node *ast;
261 int type;
262 {
263
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000264 PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
265
266 if (o != 0) {
267 o->ast_node = ast;
268 o->ast_type = type;
269 }
270 return ((PyObject*)o);
271
272} /* parser_newastobject() */
273
274
275/* void parser_free(PyAST_Object* ast)
276 *
277 * This is called by a del statement that reduces the reference count to 0.
278 *
279 */
280static void
281parser_free(ast)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000282 PyAST_Object *ast;
283 {
284
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000285 PyNode_Free(ast->ast_node);
286 PyMem_DEL(ast);
287
288} /* parser_free() */
289
290
291/* parser_ast2tuple(PyObject* self, PyObject* args)
292 *
293 * This provides conversion from a node* to a tuple object that can be
294 * returned to the Python-level caller. The AST object is not modified.
295 *
296 */
297static PyObject*
298parser_ast2tuple(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000299 PyObject *self;
300 PyObject *args;
301 {
302
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000303 PyObject* ast;
304 PyObject* res = 0;
305
306 if (PyArg_ParseTuple(args, "O!:ast2tuple", &PyAST_Type, &ast)) {
307 /*
308 * Convert AST into a tuple representation. Use Guido's function,
309 * since it's known to work already.
310 */
311 res = node2tuple(((PyAST_Object*)ast)->ast_node);
312 }
313 return (res);
314
315} /* parser_ast2tuple() */
316
317
318/* parser_compileast(PyObject* self, PyObject* args)
319 *
320 * This function creates code objects from the parse tree represented by
321 * the passed-in data object. An optional file name is passed in as well.
322 *
323 */
324static PyObject*
325parser_compileast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000326 PyObject *self;
327 PyObject *args;
328 {
329
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000330 PyAST_Object* ast;
331 PyObject* res = 0;
332 char* str = "<ast>";
333
334 if (PyArg_ParseTuple(args, "O!|s", &PyAST_Type, &ast, &str))
Guido van Rossum3d602e31996-07-21 02:33:56 +0000335 res = (PyObject*) PyNode_Compile(ast->ast_node, str);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000336
337 return (res);
338
339} /* parser_compileast() */
340
341
342/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
343 * PyObject* parser_issuite(PyObject* self, PyObject* args)
344 *
345 * Checks the passed-in AST object to determine if it is an expression or
346 * a statement suite, respectively. The return is a Python truth value.
347 *
348 */
349static PyObject*
350parser_isexpr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000351 PyObject *self;
352 PyObject *args;
353 {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000354 PyAST_Object* ast;
355 PyObject* res = 0;
356
357 if (PyArg_ParseTuple(args, "O!:isexpr", &PyAST_Type, &ast)) {
358 /*
359 * Check to see if the AST represents an expression or not.
360 */
361 res = (ast->ast_type == PyAST_EXPR) ? Py_True : Py_False;
362 Py_INCREF(res);
363 }
364 return (res);
365
366} /* parser_isexpr() */
367
368
369static PyObject*
370parser_issuite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000371 PyObject *self;
372 PyObject *args;
373 {
374
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000375 PyAST_Object* ast;
376 PyObject* res = 0;
377
Guido van Rossum3d602e31996-07-21 02:33:56 +0000378 if (PyArg_ParseTuple(args, "O!:issuite", &PyAST_Type, &ast)) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000379 /*
380 * Check to see if the AST represents an expression or not.
381 */
382 res = (ast->ast_type == PyAST_EXPR) ? Py_False : Py_True;
383 Py_INCREF(res);
384 }
385 return (res);
386
387} /* parser_issuite() */
388
389
Guido van Rossum3d602e31996-07-21 02:33:56 +0000390/* err_string(char* message)
391 *
392 * Sets the error string for an exception of type ParserError.
393 *
394 */
395static void
396err_string(message)
397 char *message;
398 {
399 PyErr_SetString(parser_error, message);
400
401} /* err_string() */
402
403
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000404/* PyObject* parser_do_parse(PyObject* args, int type)
405 *
406 * Internal function to actually execute the parse and return the result if
407 * successful, or set an exception if not.
408 *
409 */
410static PyObject*
411parser_do_parse(args, type)
412 PyObject *args;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000413 int type;
414 {
415
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000416 char* string = 0;
417 PyObject* res = 0;
418
419 if (PyArg_ParseTuple(args, "s", &string)) {
420 node* n = PyParser_SimpleParseString(string,
421 (type == PyAST_EXPR)
422 ? eval_input : file_input);
423
424 if (n != 0)
425 res = parser_newastobject(n, type);
426 else
Guido van Rossum3d602e31996-07-21 02:33:56 +0000427 err_string("Could not parse string.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000428 }
429 return (res);
430
431} /* parser_do_parse() */
432
433
434/* PyObject* parser_expr(PyObject* self, PyObject* args)
435 * PyObject* parser_suite(PyObject* self, PyObject* args)
436 *
437 * External interfaces to the parser itself. Which is called determines if
438 * the parser attempts to recognize an expression ('eval' form) or statement
439 * suite ('exec' form). The real work is done by parser_do_parse() above.
440 *
441 */
442static PyObject*
443parser_expr(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000444 PyObject *self;
445 PyObject *args;
446 {
447
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000448 return (parser_do_parse(args, PyAST_EXPR));
449
450} /* parser_expr() */
451
452
453static PyObject*
454parser_suite(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000455 PyObject *self;
456 PyObject *args;
457 {
458
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000459 return (parser_do_parse(args, PyAST_SUITE));
460
461} /* parser_suite() */
462
463
464
465/* This is the messy part of the code. Conversion from a tuple to an AST
466 * object requires that the input tuple be valid without having to rely on
467 * catching an exception from the compiler. This is done to allow the
468 * compiler itself to remain fast, since most of its input will come from
469 * the parser directly, and therefore be known to be syntactically correct.
470 * This validation is done to ensure that we don't core dump the compile
471 * phase, returning an exception instead.
472 *
473 * Two aspects can be broken out in this code: creating a node tree from
474 * the tuple passed in, and verifying that it is indeed valid. It may be
475 * advantageous to expand the number of AST types to include funcdefs and
476 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
477 * here. They are not necessary, and not quite as useful in a raw form.
478 * For now, let's get expressions and suites working reliably.
479 */
480
481
Guido van Rossum3d602e31996-07-21 02:33:56 +0000482staticforward node* build_node_tree();
483staticforward int validate_expr_tree();
484staticforward int validate_file_input();
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000485
486
487/* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
488 *
489 * This is the public function, called from the Python code. It receives a
490 * single tuple object from the caller, and creates an AST object if the
491 * tuple can be validated. It does this by checking the first code of the
492 * tuple, and, if acceptable, builds the internal representation. If this
493 * step succeeds, the internal representation is validated as fully as
494 * possible with the various validate_*() routines defined below.
495 *
496 * This function must be changed if support is to be added for PyAST_FRAGMENT
497 * AST objects.
498 *
499 */
500static PyObject*
501parser_tuple2ast(self, args)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000502 PyObject *self;
503 PyObject *args;
504 {
505
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000506 PyObject* ast = 0;
507 PyObject* tuple = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000508
Guido van Rossum3d602e31996-07-21 02:33:56 +0000509 if ((PyObject_Length(args) == 1)
510 && (tuple = PySequence_GetItem(args, 0))
511 && PySequence_Check(tuple)
512 && (PyObject_Length(tuple) >= 2)
513 && PyInt_Check(PySequence_GetItem(tuple, 0))
514 && PySequence_Check(PySequence_GetItem(tuple, 1))
515 && (PyObject_Length(PySequence_GetItem(tuple, 1)) >= 2)
516 && PyInt_Check(PySequence_GetItem(PySequence_GetItem(tuple, 1), 0))) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000517
518 /*
519 * This might be a valid parse tree, but let's do a quick check
520 * before we jump the gun.
521 */
522
Guido van Rossum3d602e31996-07-21 02:33:56 +0000523 int start_sym = PyInt_AsLong(PySequence_GetItem(tuple, 0));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000524
Guido van Rossum3d602e31996-07-21 02:33:56 +0000525 if (start_sym == eval_input) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000526 /*
Guido van Rossum3d602e31996-07-21 02:33:56 +0000527 * Might be an eval form.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000528 */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000529 node* expression = build_node_tree(PySequence_GetItem(args, 0));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000530
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000531 if ((expression != 0) && validate_expr_tree(expression))
532 ast = parser_newastobject(expression, PyAST_EXPR);
533 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000534 else if (start_sym == file_input) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000535 /*
Guido van Rossum3d602e31996-07-21 02:33:56 +0000536 * This looks like an exec form so far.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000537 */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000538 node* suite_tree = build_node_tree(PySequence_GetItem(args, 0));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000539
Guido van Rossum3d602e31996-07-21 02:33:56 +0000540 if ((suite_tree != 0) && validate_file_input(suite_tree))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000541 ast = parser_newastobject(suite_tree, PyAST_SUITE);
542 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000543 else
544 /* This is a fragment, and is not yet supported. Maybe they
545 * will be if I find a use for them.
546 */
547 err_string("Fragmentary parse trees not supported.");
548
549 /* Make sure we throw an exception on all errors. We should never
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000550 * get this, but we'd do well to be sure something is done.
551 */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000552 if ((ast == 0) && !PyErr_Occurred())
553 err_string("Unspecified ast error occurred.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000554 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000555 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000556 PyErr_SetString(PyExc_TypeError,
557 "parser.tuple2ast(): expected single tuple.");
Guido van Rossum3d602e31996-07-21 02:33:56 +0000558
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000559 return (ast);
560
561} /* parser_tuple2ast() */
562
563
564/* int check_terminal_tuple()
565 *
566 * Check a tuple to determine that it is indeed a valid terminal node. The
567 * node is known to be required as a terminal, so we throw an exception if
568 * there is a failure. The portion of the resulting node tree already built
569 * is passed in so we can deallocate it in the event of a failure.
570 *
571 * The format of an acceptable terminal tuple is "(is)": the fact that elem
572 * is a tuple and the integer is a valid terminal symbol has been established
573 * before this function is called. We must check the length of the tuple and
574 * the type of the second element. We do *NOT* check the actual text of the
575 * string element, which we could do in many cases. This is done by the
576 * validate_*() functions which operate on the internal representation.
577 *
578 */
579static int
580check_terminal_tuple(elem, result)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000581 PyObject *elem;
582 node *result;
583 {
584
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000585 int res = 0;
586 char* str = 0;
587
Guido van Rossum3d602e31996-07-21 02:33:56 +0000588 if (PyObject_Length(elem) != 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000589 str = "Illegal terminal symbol; node too long.";
Guido van Rossum3d602e31996-07-21 02:33:56 +0000590 else if (!PyString_Check(PySequence_GetItem(elem, 1)))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000591 str = "Illegal terminal symbol; expected a string.";
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000592 else
593 res = 1;
594
595 if ((res == 0) && (result != 0)) {
596 elem = Py_BuildValue("(os)", elem, str);
597 PyErr_SetObject(parser_error, elem);
598 }
599 return (res);
600
601} /* check_terminal_tuple() */
602
603
604/* node* build_node_children()
605 *
606 * Iterate across the children of the current non-terminal node and build
607 * their structures. If successful, return the root of this portion of
608 * the tree, otherwise, 0. Any required exception will be specified already,
609 * and no memory will have been deallocated.
610 *
611 */
612static node*
613build_node_children(tuple, root, line_num)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000614 PyObject *tuple;
615 node *root;
616 int *line_num;
617 {
618
619 int len = PyObject_Length(tuple);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000620 int i;
621
622 for (i = 1; i < len; ++i) {
623 /* elem must always be a tuple, however simple */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000624 PyObject* elem = PySequence_GetItem(tuple, i);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000625 long type = 0;
626 char* strn = 0;
627
Guido van Rossum3d602e31996-07-21 02:33:56 +0000628 if ((!PySequence_Check(elem))
629 || !PyInt_Check(PySequence_GetItem(elem, 0))) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000630 PyErr_SetObject(parser_error,
631 Py_BuildValue("(os)", elem,
632 "Illegal node construct."));
633 return (0);
634 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000635 type = PyInt_AsLong(PySequence_GetItem(elem, 0));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000636
637 if (ISTERMINAL(type)) {
638 if (check_terminal_tuple(elem, root))
Guido van Rossum3d602e31996-07-21 02:33:56 +0000639 strn = strdup(PyString_AsString(PySequence_GetItem(elem, 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000640 else
641 return (0);
642 }
643 else if (!ISNONTERMINAL(type)) {
644 /*
645 * It has to be one or the other; this is an error.
646 * Throw an exception.
647 */
648 PyErr_SetObject(parser_error,
649 Py_BuildValue("(os)", elem,
650 "Unknown node type."));
651 return (0);
652 }
653 PyNode_AddChild(root, type, strn, *line_num);
654
655 if (ISNONTERMINAL(type)) {
656 node* new_child = CHILD(root, i - 1);
657
Guido van Rossumc0fd1c01996-01-12 01:37:02 +0000658 if (new_child != build_node_children(elem, new_child, line_num))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000659 return (0);
660 }
661 else if (type == NEWLINE) /* It's true: we increment the */
662 ++(*line_num); /* line number *after* the newline! */
663 }
664 return (root);
665
666} /* build_node_children() */
667
668
669static node*
670build_node_tree(tuple)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000671 PyObject *tuple;
672 {
673
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000674 node* res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000675 long num = PyInt_AsLong(PySequence_GetItem(tuple, 0));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000676
677 if (ISTERMINAL(num)) {
678 /*
679 * The tuple is simple, but it doesn't start with a start symbol.
680 * Throw an exception now and be done with it.
681 */
682 tuple = Py_BuildValue("(os)", tuple,
Guido van Rossum3d602e31996-07-21 02:33:56 +0000683 "Illegal ast tuple; cannot start with terminal symbol.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000684 PyErr_SetObject(parser_error, tuple);
685 }
686 else if (ISNONTERMINAL(num)) {
687 /*
688 * Not efficient, but that can be handled later.
689 */
690 int line_num = 0;
691
692 res = PyNode_New(num);
693 if (res != build_node_children(tuple, res, &line_num)) {
694 PyNode_Free(res);
695 res = 0;
696 }
697 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000698 else
699 /* The tuple is illegal -- if the number is neither TERMINAL nor
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000700 * NONTERMINAL, we can't use it.
701 */
702 PyErr_SetObject(parser_error,
703 Py_BuildValue("(os)", tuple,
704 "Illegal component tuple."));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000705
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000706 return (res);
707
708} /* build_node_tree() */
709
710
Guido van Rossum3d602e31996-07-21 02:33:56 +0000711#define VALIDATER(n) static int validate_##n()
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000712
713
714/*
715 * Validation for the code above:
716 */
717VALIDATER(expr_tree);
718VALIDATER(suite_tree);
719
720
721/*
722 * Validation routines used within the validation section:
723 */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000724staticforward int validate_terminal();
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000725
726#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
727#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
728#define validate_colon(ch) validate_terminal(ch, COLON, ":")
729#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
730#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
731#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000732#define validate_indent(ch) validate_terminal(ch, INDENT, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000733#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000734#define validate_newline(ch) validate_terminal(ch, NEWLINE, 0)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000735#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
736#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
737#define validate_star(ch) validate_terminal(ch, STAR, "*")
738#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000739#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
740#define validate_name(ch, str) validate_terminal(ch, NAME, str)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000741
Guido van Rossum3d602e31996-07-21 02:33:56 +0000742#if defined(access_stmt) && defined(accesstype)
743VALIDATER(access_stmt); VALIDATER(accesstype);
744#endif
745VALIDATER(node); VALIDATER(small_stmt);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000746VALIDATER(class); VALIDATER(node);
747VALIDATER(parameters); VALIDATER(suite);
748VALIDATER(testlist); VALIDATER(varargslist);
749VALIDATER(fpdef); VALIDATER(fplist);
750VALIDATER(stmt); VALIDATER(simple_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000751VALIDATER(expr_stmt); VALIDATER(power);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000752VALIDATER(print_stmt); VALIDATER(del_stmt);
753VALIDATER(return_stmt);
754VALIDATER(raise_stmt); VALIDATER(import_stmt);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000755VALIDATER(global_stmt); VALIDATER(file_input);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000756VALIDATER(exec_stmt); VALIDATER(compound_stmt);
757VALIDATER(while); VALIDATER(for);
758VALIDATER(try); VALIDATER(except_clause);
759VALIDATER(test); VALIDATER(and_test);
760VALIDATER(not_test); VALIDATER(comparison);
761VALIDATER(comp_op); VALIDATER(expr);
762VALIDATER(xor_expr); VALIDATER(and_expr);
763VALIDATER(shift_expr); VALIDATER(arith_expr);
764VALIDATER(term); VALIDATER(factor);
765VALIDATER(atom); VALIDATER(lambdef);
766VALIDATER(trailer); VALIDATER(subscript);
767VALIDATER(exprlist); VALIDATER(dictmaker);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000768VALIDATER(arglist); VALIDATER(argument);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000769
770
771#define is_even(n) (((n) & 1) == 0)
772#define is_odd(n) (((n) & 1) == 1)
773
774
775static int
776validate_ntype(n, t)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000777 node *n;
778 int t;
779 {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000780 int res = (TYPE(n) == t);
781
782 if (!res) {
783 char buffer[128];
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000784 sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000785 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000786 }
787 return (res);
788
789} /* validate_ntype() */
790
791
792static int
Guido van Rossum3d602e31996-07-21 02:33:56 +0000793validate_numnodes(n, num, name)
794 node *n;
795 int num;
796 const char *const name;
797 {
798 if (NCH(n) != num) {
799 char buff[60];
800 sprintf(buff, "Illegal number of children for %s node.", name);
801 err_string(buff);
802 }
803 return (NCH(n) == num);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000804
Guido van Rossum3d602e31996-07-21 02:33:56 +0000805} /* validate_numnodes() */
806
807
808static int
809validate_terminal(terminal, type, string)
810 node *terminal;
811 int type;
812 char *string;
813 {
814 int res = (validate_ntype(terminal, type)
815 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
816
817 if (!res && !PyErr_Occurred()) {
818 char buffer[60];
819 sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
820 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000821 }
822 return (res);
823
824} /* validate_terminal() */
825
826
Guido van Rossum3d602e31996-07-21 02:33:56 +0000827/* VALIDATE(class)
828 *
829 * classdef:
830 * 'class' NAME ['(' testlist ')'] ':' suite
831 */
832validate_class(tree)
833 node *tree;
834{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000835 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000836 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000837
Guido van Rossum3d602e31996-07-21 02:33:56 +0000838 if (res) {
839 res = (validate_name(CHILD(tree, 0), "class")
840 && validate_ntype(CHILD(tree, 1), NAME)
841 && validate_colon(CHILD(tree, nch - 2))
842 && validate_suite(CHILD(tree, nch - 1)));
843 }
844 else
845 validate_numnodes(tree, 4, "class");
846 if (res && (nch == 7)) {
847 res = (validate_lparen(CHILD(tree, 2))
848 && validate_testlist(CHILD(tree, 3))
849 && validate_rparen(CHILD(tree, 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000850 }
851 return (res);
852
853} /* validate_class() */
854
855
Guido van Rossum3d602e31996-07-21 02:33:56 +0000856/* if_stmt:
857 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
858 */
859validate_if(tree)
860 node *tree;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000861{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000862 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000863 int res = (validate_ntype(tree, if_stmt)
864 && (nch >= 4)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000865 && validate_name(CHILD(tree, 0), "if")
Guido van Rossum3d602e31996-07-21 02:33:56 +0000866 && validate_test(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000867 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000868 && validate_suite(CHILD(tree, 3)));
869
870 if (res && ((nch % 4) == 3)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +0000871 /* ... 'else' ':' suite */
872 res = (validate_name(CHILD(tree, nch - 3), "else")
873 && validate_colon(CHILD(tree, nch - 2))
874 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000875 nch -= 3;
876 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000877 else if (!res && !PyErr_Occurred())
878 validate_numnodes(tree, 4, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000879 if ((nch % 4) != 0)
Guido van Rossum3d602e31996-07-21 02:33:56 +0000880 /* Will catch the case for nch < 4 */
881 res = validate_numnodes(tree, 0, "if");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000882 else if (res && (nch > 4)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +0000883 /* ... ('elif' test ':' suite)+ ... */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000884 int j = 4;
885 while ((j < nch) && res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +0000886 res = (validate_name(CHILD(tree, j), "elif")
887 && validate_colon(CHILD(tree, j + 2))
888 && validate_test(CHILD(tree, j + 1))
889 && validate_suite(CHILD(tree, j + 3)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000890 j += 4;
891 }
892 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000893 return (res);
894
895} /* validate_if() */
896
897
Guido van Rossum3d602e31996-07-21 02:33:56 +0000898/* parameters:
899 * '(' [varargslist] ')'
900 *
901 */
902validate_parameters(tree)
903 node *tree;
904{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000905 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000906 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000907
Guido van Rossum3d602e31996-07-21 02:33:56 +0000908 if (res) {
909 res = (validate_lparen(CHILD(tree, 0))
910 && validate_rparen(CHILD(tree, nch - 1)));
911 if (res && (nch == 3))
912 res = validate_varargslist(CHILD(tree, 1));
913 }
914 else
915 validate_numnodes(tree, 2, "parameters");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000916
917 return (res);
918
919} /* validate_parameters() */
920
921
Guido van Rossum3d602e31996-07-21 02:33:56 +0000922/* VALIDATE(suite)
923 *
924 * suite:
925 * simple_stmt
926 * | NEWLINE INDENT stmt+ DEDENT
927 */
928validate_suite(tree)
929 node *tree;
930{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000931 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000932 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000933
Guido van Rossum3d602e31996-07-21 02:33:56 +0000934 if (res && (nch == 1))
935 res = validate_simple_stmt(CHILD(tree, 0));
936 else if (res) {
937 /* NEWLINE INDENT stmt+ DEDENT */
938 res = (validate_newline(CHILD(tree, 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000939 && validate_indent(CHILD(tree, 1))
Guido van Rossum3d602e31996-07-21 02:33:56 +0000940 && validate_stmt(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000941 && validate_dedent(CHILD(tree, nch - 1)));
942
Guido van Rossum3d602e31996-07-21 02:33:56 +0000943 if (res && (nch > 4)) {
944 int i = 3;
945 --nch; /* forget the DEDENT */
946 for ( ; res && (i < nch); ++i)
947 res = validate_stmt(CHILD(tree, i));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000948 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000949 else if (nch < 4)
950 validate_numnodes(tree, 4, "suite");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000951 }
952 return (res);
953
954} /* validate_suite() */
955
956
Guido van Rossum3d602e31996-07-21 02:33:56 +0000957validate_testlist(tree)
958 node *tree;
959{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000960 int i;
961 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +0000962 int res = validate_ntype(tree, testlist) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000963
Guido van Rossum3d602e31996-07-21 02:33:56 +0000964 /* If there are an even, non-zero number of children, the last one
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000965 * absolutely must be a comma. Why the trailing comma is allowed,
966 * I have no idea!
967 */
Guido van Rossum3d602e31996-07-21 02:33:56 +0000968 if (res && is_even(nch))
969 res = validate_comma(CHILD(tree, --nch));
970
971 if (res) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000972 /*
973 * If the number is odd, the last is a test, and can be
974 * verified. What's left, if anything, can be verified
975 * as a list of [test, comma] pairs.
976 */
977 --nch;
Guido van Rossum3d602e31996-07-21 02:33:56 +0000978 res = validate_test(CHILD(tree, nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000979 }
Guido van Rossum3d602e31996-07-21 02:33:56 +0000980 for (i = 0; res && (i < nch); i += 2)
981 res = (validate_test(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000982 && validate_comma(CHILD(tree, i + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +0000983
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +0000984 return (res);
985
986} /* validate_testlist() */
987
988
Guido van Rossum3d602e31996-07-21 02:33:56 +0000989/* VALIDATE(varargslist)
990 *
991 * varargslist:
992 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
993 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
994 *
995 * (fpdef ['=' test] ',')*
996 * ('*' NAME [',' ('**'|'*' '*') NAME]
997 * | ('**'|'*' '*') NAME)
998 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
999 *
1000 */
1001validate_varargslist(tree)
1002 node *tree;
1003{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001004 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001005 int res = validate_ntype(tree, varargslist) && (nch != 0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001006
Guido van Rossum3d602e31996-07-21 02:33:56 +00001007 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1008 /* (fpdef ['=' test] ',')*
1009 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1010 */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001011 int pos = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001012 int remaining = nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001013
Guido van Rossum3d602e31996-07-21 02:33:56 +00001014 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1015 res = validate_fpdef(CHILD(tree, pos));
1016 if (res) {
1017 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1018 res = validate_test(CHILD(tree, pos + 2));
1019 pos += 2;
1020 }
1021 res = res && validate_comma(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001022 pos += 2;
1023 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001024 }
1025 if (res) {
1026 remaining = nch - pos;
1027 res = ((remaining == 2) || (remaining == 3)
1028 || (remaining == 5) || (remaining == 6));
1029 if (!res)
1030 validate_numnodes(tree, 2, "varargslist");
1031 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1032 return ((remaining == 2)
1033 && validate_ntype(CHILD(tree, pos+1), NAME));
1034 else {
1035 res = validate_star(CHILD(tree, pos++));
1036 --remaining;
1037 }
1038 }
1039 if (res) {
1040 if (remaining == 2) {
1041 res = (validate_star(CHILD(tree, pos))
1042 && validate_ntype(CHILD(tree, pos + 1), NAME));
1043 }
1044 else {
1045 res = validate_ntype(CHILD(tree, pos++), NAME);
1046 if (res && (remaining >= 4)) {
1047 res = validate_comma(CHILD(tree, pos));
1048 if (--remaining == 3)
1049 res == (validate_star(CHILD(tree, pos + 1))
1050 && validate_star(CHILD(tree, pos + 2)));
1051 else
1052 validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1053 }
1054 }
1055 }
1056 if (!res && !PyErr_Occurred())
1057 err_string("Incorrect validation of variable arguments list.");
1058 }
1059 else if (res) {
1060 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1061 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1062 --nch;
1063
1064 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1065 res = (is_odd(nch)
1066 && validate_fpdef(CHILD(tree, 0)));
1067
1068 if (res && (nch > 1)) {
1069 int pos = 1;
1070 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1071 res = validate_test(CHILD(tree, 2));
1072 pos += 2;
1073 }
1074 /* ... (',' fpdef ['=' test])* */
1075 for ( ; res && (pos < nch); pos += 2) {
1076 /* ',' fpdef */
1077 res = (validate_comma(CHILD(tree, pos))
1078 && validate_fpdef(CHILD(tree, pos + 1)));
1079 if (res
1080 && ((nch - pos) > 2)
1081 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1082 /* ['=' test] */
1083 res = validate_test(CHILD(tree, pos + 3));
1084 pos += 2;
1085 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001086 }
1087 }
1088 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001089 else
1090 err_string("Improperly formed argument list.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001091
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001092 return (res);
1093
1094} /* validate_varargslist() */
1095
1096
Guido van Rossum3d602e31996-07-21 02:33:56 +00001097/* VALIDATE(fpdef)
1098 *
1099 * fpdef:
1100 * NAME
1101 * | '(' fplist ')'
1102 */
1103validate_fpdef(tree)
1104 node *tree;
1105{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001106 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001107 int res = validate_ntype(tree, fpdef);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001108
Guido van Rossum3d602e31996-07-21 02:33:56 +00001109 if (res) {
1110 if (nch == 1)
1111 res = validate_ntype(CHILD(tree, 0), NAME);
1112 else if (nch == 3)
1113 res = (validate_lparen(CHILD(tree, 0))
1114 && validate_fplist(CHILD(tree, 1))
1115 && validate_rparen(CHILD(tree, 2)));
1116 else
1117 validate_numnodes(tree, 1, "fpdef");
1118 }
1119 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001120
1121} /* validate_fpdef() */
1122
1123
Guido van Rossum3d602e31996-07-21 02:33:56 +00001124validate_fplist(tree)
1125 node *tree;
1126{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001127 int j;
1128 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001129 int res = (validate_ntype(tree, fplist)
1130 && (nch != 0) && validate_fpdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001131
Guido van Rossum3d602e31996-07-21 02:33:56 +00001132 if (res && is_even(nch))
1133 res = validate_comma(CHILD(tree, --nch));
1134
1135 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001136 res = (validate_comma(CHILD(tree, j))
1137 && validate_fpdef(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001138
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001139 return (res);
1140
1141} /* validate_fplist() */
1142
1143
Guido van Rossum3d602e31996-07-21 02:33:56 +00001144/* simple_stmt | compound_stmt
1145 *
1146 */
1147validate_stmt(tree)
1148 node *tree;
1149{
1150 int res = (validate_ntype(tree, stmt)
1151 && validate_numnodes(tree, 1, "stmt"));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001152
Guido van Rossum3d602e31996-07-21 02:33:56 +00001153 if (res) {
1154 tree = CHILD(tree, 0);
1155
1156 if (TYPE(tree) == simple_stmt)
1157 res = validate_simple_stmt(tree);
1158 else
1159 res = validate_compound_stmt(tree);
1160 }
1161 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001162
1163} /* validate_stmt() */
1164
1165
Guido van Rossum3d602e31996-07-21 02:33:56 +00001166/* small_stmt (';' small_stmt)* [';'] NEWLINE
1167 *
1168 */
1169validate_simple_stmt(tree)
1170 node *tree;
1171{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001172 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001173 int res = (validate_ntype(tree, simple_stmt)
1174 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001175 && validate_small_stmt(CHILD(tree, 0))
1176 && validate_newline(CHILD(tree, nch - 1)));
1177
Guido van Rossum3d602e31996-07-21 02:33:56 +00001178 if (nch < 2)
1179 res = validate_numnodes(tree, 2, "simple_stmt");
1180 --nch; /* forget the NEWLINE */
1181 if (res && is_even(nch))
1182 res = validate_semi(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001183 if (res && (nch > 2)) {
1184 int i;
1185
Guido van Rossum3d602e31996-07-21 02:33:56 +00001186 for (i = 1; res && (i < nch); i += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001187 res = (validate_semi(CHILD(tree, i))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001188 && validate_small_stmt(CHILD(tree, i + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001189 }
1190 return (res);
1191
1192} /* validate_simple_stmt() */
1193
1194
Guido van Rossum3d602e31996-07-21 02:33:56 +00001195validate_small_stmt(tree)
1196 node *tree;
1197{
1198 int nch = NCH(tree);
1199 int res = (validate_numnodes(tree, 1, "small_stmt")
1200 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1201 || (TYPE(CHILD(tree, 0)) == print_stmt)
1202 || (TYPE(CHILD(tree, 0)) == del_stmt)
1203 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1204 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1205 || (TYPE(CHILD(tree, 0)) == import_stmt)
1206 || (TYPE(CHILD(tree, 0)) == global_stmt)
1207#if defined(access_stmt) && defined(accesstype)
1208 || (TYPE(CHILD(tree, 0)) == access_stmt)
1209#endif
1210 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1211
1212 if (res)
1213 res = validate_node(CHILD(tree, 0));
1214 else if (nch == 1) {
1215 char buffer[60];
1216 sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1217 TYPE(CHILD(tree, 0)));
1218 err_string(buffer);
1219 }
1220 return (res);
1221
1222} /* validate_small_stmt */
1223
1224
1225/* compound_stmt:
1226 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1227 */
1228validate_compound_stmt(tree)
1229 node *tree;
1230{
1231 int res = (validate_ntype(tree, compound_stmt)
1232 && validate_numnodes(tree, 1, "compound_stmt"));
1233
1234 if (!res)
1235 return (0);
1236
1237 tree = CHILD(tree, 0);
1238 res = ((TYPE(tree) == if_stmt)
1239 || (TYPE(tree) == while_stmt)
1240 || (TYPE(tree) == for_stmt)
1241 || (TYPE(tree) == try_stmt)
1242 || (TYPE(tree) == funcdef)
1243 || (TYPE(tree) == classdef));
1244 if (res)
1245 res = validate_node(tree);
1246 else {
1247 char buffer[60];
1248 sprintf(buffer, "Illegal compound statement type: %d.", TYPE(tree));
1249 err_string(buffer);
1250 }
1251 return (res);
1252
1253} /* validate_compound_stmt() */
1254
1255
1256validate_expr_stmt(tree)
1257 node *tree;
1258{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001259 int j;
1260 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001261 int res = (validate_ntype(tree, expr_stmt)
1262 && is_odd(nch)
1263 && validate_testlist(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001264
Guido van Rossum3d602e31996-07-21 02:33:56 +00001265 for (j = 1; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001266 res = (validate_equal(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001267 && validate_testlist(CHILD(tree, j + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001268
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001269 return (res);
1270
1271} /* validate_expr_stmt() */
1272
1273
Guido van Rossum3d602e31996-07-21 02:33:56 +00001274/* print_stmt:
1275 *
1276 * 'print' (test ',')* [test]
1277 *
1278 */
1279validate_print_stmt(tree)
1280 node *tree;
1281{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001282 int j;
1283 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001284 int res = (validate_ntype(tree, print_stmt)
1285 && (nch != 0)
1286 && validate_name(CHILD(tree, 0), "print"));
1287
1288 if (res && is_even(nch)) {
1289 res = validate_test(CHILD(tree, nch - 1));
1290 --nch;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001291 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001292 else if (!res && !PyErr_Occurred())
1293 validate_numnodes(tree, 1, "print_stmt");
1294 for (j = 1; res && (j < nch); j += 2)
1295 res = (validate_test(CHILD(tree, j))
1296 && validate_ntype(CHILD(tree, j + 1), COMMA));
1297
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001298 return (res);
1299
1300} /* validate_print_stmt() */
1301
1302
Guido van Rossum3d602e31996-07-21 02:33:56 +00001303validate_del_stmt(tree)
1304 node *tree;
1305{
1306 return (validate_numnodes(tree, 2, "del_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001307 && validate_name(CHILD(tree, 0), "del")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001308 && validate_exprlist(CHILD(tree, 1)));
1309
1310} /* validate_del_stmt() */
1311
1312
Guido van Rossum3d602e31996-07-21 02:33:56 +00001313validate_return_stmt(tree)
1314 node *tree;
1315{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001316 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001317 int res = (validate_ntype(tree, return_stmt)
1318 && ((nch == 1) || (nch == 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001319 && validate_name(CHILD(tree, 0), "return"));
1320
Guido van Rossum3d602e31996-07-21 02:33:56 +00001321 if (res && (nch == 2))
1322 res = validate_testlist(CHILD(tree, 1));
1323
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001324 return (res);
1325
1326} /* validate_return_stmt() */
1327
1328
Guido van Rossum3d602e31996-07-21 02:33:56 +00001329validate_raise_stmt(tree)
1330 node *tree;
1331{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001332 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001333 int res = (validate_ntype(tree, raise_stmt)
1334 && ((nch == 2) || (nch == 4) || (nch == 6)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001335
Guido van Rossum3d602e31996-07-21 02:33:56 +00001336 if (res) {
1337 res = (validate_name(CHILD(tree, 0), "raise")
1338 && validate_test(CHILD(tree, 1)));
1339 if (res && nch > 2) {
1340 res = (validate_comma(CHILD(tree, 2))
1341 && validate_test(CHILD(tree, 3)));
1342 if (res && (nch > 4))
1343 res = (validate_comma(CHILD(tree, 4))
1344 && validate_test(CHILD(tree, 5)));
1345 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001346 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001347 else
1348 validate_numnodes(tree, 2, "raise");
1349 if (res && (nch == 4))
1350 res = (validate_comma(CHILD(tree, 2))
1351 && validate_test(CHILD(tree, 3)));
1352
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001353 return (res);
1354
1355} /* validate_raise_stmt() */
1356
1357
Guido van Rossum3d602e31996-07-21 02:33:56 +00001358/* import_stmt:
1359 *
1360 * 'import' dotted_name (',' dotted_name)*
1361 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1362 */
1363validate_import_stmt(tree)
1364 node *tree;
1365{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001366 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001367 int res = (validate_ntype(tree, import_stmt)
1368 && (nch >= 2) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001369 && validate_ntype(CHILD(tree, 0), NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001370 && validate_ntype(CHILD(tree, 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001371
1372 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001373 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001374
Guido van Rossum3d602e31996-07-21 02:33:56 +00001375 for (j = 2; res && (j < nch); j += 2)
1376 res = (validate_comma(CHILD(tree, j))
1377 && validate_ntype(CHILD(tree, j + 1), dotted_name));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001378 }
1379 else if (res && validate_name(CHILD(tree, 0), "from")) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001380 res = ((nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001381 && validate_name(CHILD(tree, 2), "import"));
1382 if (nch == 4) {
1383 res = ((TYPE(CHILD(tree, 3)) == NAME)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001384 || (TYPE(CHILD(tree, 3)) == STAR));
1385 if (!res)
1386 err_string("Illegal import statement.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001387 }
1388 else {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001389 /* 'from' NAME 'import' NAME (',' NAME)+ */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001390 int j;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001391 res = validate_ntype(CHILD(tree, 3), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001392 for (j = 4; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001393 res = (validate_comma(CHILD(tree, j))
1394 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001395 }
1396 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001397 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001398 res = 0;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001399
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001400 return (res);
1401
1402} /* validate_import_stmt() */
1403
1404
Guido van Rossum3d602e31996-07-21 02:33:56 +00001405validate_global_stmt(tree)
1406 node *tree;
1407{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001408 int j;
1409 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001410 int res = (validate_ntype(tree, global_stmt)
1411 && is_even(nch) && (nch >= 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001412
Guido van Rossum3d602e31996-07-21 02:33:56 +00001413 if (res)
1414 res = (validate_name(CHILD(tree, 0), "global")
1415 && validate_ntype(CHILD(tree, 1), NAME));
1416 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001417 res = (validate_comma(CHILD(tree, j))
1418 && validate_ntype(CHILD(tree, j + 1), NAME));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001419
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001420 return (res);
1421
1422} /* validate_global_stmt() */
1423
1424
Guido van Rossum3d602e31996-07-21 02:33:56 +00001425#if defined(access_stmt) && defined(accesstype)
1426/* VALIDATE(accesstype)
1427 *
1428 * This should be removed as soon as the 'access' statement is actually
1429 * removed from the language. The conditional compilation should help.
1430 */
1431validate_access_stmt(tree)
1432 node *tree;
1433{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001434 int pos = 3;
1435 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001436 int res = (validate_ntype(tree, access_stmt)
1437 && (nch >= 4) && is_even(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001438 && validate_name(CHILD(tree, 0), "access")
1439 && validate_accesstype(CHILD(tree, nch - 1)));
1440
1441 if (res && (TYPE(CHILD(tree, 1)) != STAR)) {
1442 int j;
1443
1444 res = validate_ntype(CHILD(tree, 1), NAME);
1445 for (j = 2; res && (j < (nch - 2)); j += 2) {
1446 if (TYPE(CHILD(tree, j)) == COLON)
1447 break;
1448 res = (validate_comma(CHILD(tree, j))
1449 && validate_ntype(CHILD(tree, j + 1), NAME)
1450 && (pos += 2));
1451 }
1452 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001453 else
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001454 res = validate_star(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001455
Guido van Rossum3d602e31996-07-21 02:33:56 +00001456 res = (res && validate_colon(CHILD(tree, pos - 1)));
1457 for (; res && (pos < (nch - 1)); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001458 res = (validate_accesstype(CHILD(tree, pos))
1459 && validate_comma(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001460
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001461 return (res && (pos == (nch - 1)));
1462
1463} /* validate_access_stmt() */
1464
1465
Guido van Rossum3d602e31996-07-21 02:33:56 +00001466validate_accesstype(tree)
1467 node *tree;
1468{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001469 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001470 int res = validate_ntype(tree, accesstype) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001471 int i;
1472
Guido van Rossum3d602e31996-07-21 02:33:56 +00001473 for (i = 0; res && (i < nch); ++i)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001474 res = validate_ntype(CHILD(tree, i), NAME);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001475
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001476 return (res);
1477
1478} /* validate_accesstype() */
Guido van Rossum3d602e31996-07-21 02:33:56 +00001479#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001480
1481
Guido van Rossum3d602e31996-07-21 02:33:56 +00001482/* exec_stmt:
1483 *
1484 * 'exec' expr ['in' test [',' test]]
1485 */
1486validate_exec_stmt(tree)
1487 node *tree;
1488{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001489 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001490 int res = (validate_ntype(tree, exec_stmt)
1491 && ((nch == 2) || (nch == 4) || (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001492 && validate_name(CHILD(tree, 0), "exec")
1493 && validate_expr(CHILD(tree, 1)));
1494
Guido van Rossum3d602e31996-07-21 02:33:56 +00001495 if (!res && !PyErr_Occurred())
1496 err_string("Illegal exec statement.");
1497 if (res && (nch > 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001498 res = (validate_name(CHILD(tree, 2), "in")
1499 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001500 if (res && (nch == 6))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001501 res = (validate_comma(CHILD(tree, 4))
1502 && validate_test(CHILD(tree, 5)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001503
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001504 return (res);
1505
1506} /* validate_exec_stmt() */
1507
1508
Guido van Rossum3d602e31996-07-21 02:33:56 +00001509validate_while(tree)
1510 node *tree;
1511{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001512 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001513 int res = (validate_ntype(tree, while_stmt)
1514 && ((nch == 4) || (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001515 && validate_name(CHILD(tree, 0), "while")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001516 && validate_test(CHILD(tree, 1))
1517 && validate_colon(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001518 && validate_suite(CHILD(tree, 3)));
1519
Guido van Rossum3d602e31996-07-21 02:33:56 +00001520 if (res && (nch == 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001521 res = (validate_name(CHILD(tree, 4), "else")
1522 && validate_colon(CHILD(tree, 5))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001523 && validate_suite(CHILD(tree, 6)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001524
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001525 return (res);
1526
1527} /* validate_while() */
1528
1529
Guido van Rossum3d602e31996-07-21 02:33:56 +00001530validate_for(tree)
1531 node *tree;
1532{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001533 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001534 int res = (validate_ntype(tree, for_stmt)
1535 && ((nch == 6) || (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001536 && validate_name(CHILD(tree, 0), "for")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001537 && validate_exprlist(CHILD(tree, 1))
1538 && validate_name(CHILD(tree, 2), "in")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001539 && validate_testlist(CHILD(tree, 3))
1540 && validate_colon(CHILD(tree, 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001541 && validate_suite(CHILD(tree, 5)));
1542
Guido van Rossum3d602e31996-07-21 02:33:56 +00001543 if (res && (nch == 9))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001544 res = (validate_name(CHILD(tree, 6), "else")
1545 && validate_colon(CHILD(tree, 7))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001546 && validate_suite(CHILD(tree, 8)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001547
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001548 return (res);
1549
1550} /* validate_for() */
1551
1552
Guido van Rossum3d602e31996-07-21 02:33:56 +00001553/* try_stmt:
1554 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1555 * | 'try' ':' suite 'finally' ':' suite
1556 *
1557 */
1558validate_try(tree)
1559 node *tree;
1560{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001561 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001562 int pos = 3;
1563 int res = (validate_ntype(tree, try_stmt)
1564 && (nch >= 6) && ((nch % 3) == 0));
1565
1566 if (res)
1567 res = (validate_name(CHILD(tree, 0), "try")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001568 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001569 && validate_suite(CHILD(tree, 2))
1570 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001571 && validate_suite(CHILD(tree, nch - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001572 else {
1573 const char* name = "execpt";
1574 char buffer[60];
1575 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1576 name = STR(CHILD(tree, nch - 3));
1577 sprintf(buffer, "Illegal number of children for try/%s node.", name);
1578 err_string(buffer);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001579 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001580 /* Skip past except_clause sections: */
1581 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1582 res = (validate_except_clause(CHILD(tree, pos))
1583 && validate_colon(CHILD(tree, pos + 1))
1584 && validate_suite(CHILD(tree, pos + 2)));
1585 pos += 3;
1586 }
1587 if (res && (pos < nch)) {
1588 res = validate_ntype(CHILD(tree, pos), NAME);
1589 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1590 res = (validate_numnodes(tree, 6, "try/finally")
1591 && validate_colon(CHILD(tree, 4))
1592 && validate_suite(CHILD(tree, 5)));
1593 else if (res)
1594 if (nch == (pos + 3)) {
1595 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1596 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1597 if (!res)
1598 err_string("Illegal trailing triple in try statement.");
1599 }
1600 else if (nch == (pos + 6))
1601 res = (validate_name(CHILD(tree, pos), "except")
1602 && validate_colon(CHILD(tree, pos + 1))
1603 && validate_suite(CHILD(tree, pos + 2))
1604 && validate_name(CHILD(tree, pos + 3), "else"));
1605 else
1606 res = validate_numnodes(tree, pos + 3, "try/except");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001607 }
1608 return (res);
1609
1610} /* validate_try() */
1611
1612
Guido van Rossum3d602e31996-07-21 02:33:56 +00001613validate_except_clause(tree)
1614 node *tree;
1615{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001616 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001617 int res = (validate_ntype(tree, except_clause)
1618 && ((nch == 1) || (nch == 2) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001619 && validate_name(CHILD(tree, 0), "except"));
1620
Guido van Rossum3d602e31996-07-21 02:33:56 +00001621 if (res && (nch > 1))
1622 res = validate_test(CHILD(tree, 1));
1623 if (res && (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001624 res = (validate_comma(CHILD(tree, 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001625 && validate_test(CHILD(tree, 3)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001626
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001627 return (res);
1628
1629} /* validate_except_clause() */
1630
1631
Guido van Rossum3d602e31996-07-21 02:33:56 +00001632validate_test(tree)
1633 node *tree;
1634{
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, test) && is_odd(nch);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001637
Guido van Rossum3d602e31996-07-21 02:33:56 +00001638 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001639 res = ((nch == 1)
1640 && validate_lambdef(CHILD(tree, 0)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001641 else if (res) {
1642 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00001643 res = validate_and_test(CHILD(tree, 0));
1644 for (pos = 1; res && (pos < nch); pos += 2)
1645 res = (validate_name(CHILD(tree, pos), "or")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001646 && validate_and_test(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001647 }
1648 return (res);
1649
1650} /* validate_test() */
1651
1652
Guido van Rossum3d602e31996-07-21 02:33:56 +00001653validate_and_test(tree)
1654 node *tree;
1655{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001656 int pos;
1657 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001658 int res = (validate_ntype(tree, and_test)
1659 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001660 && validate_not_test(CHILD(tree, 0)));
1661
Guido van Rossum3d602e31996-07-21 02:33:56 +00001662 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001663 res = (validate_name(CHILD(tree, pos), "and")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001664 && validate_not_test(CHILD(tree, 0)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001665
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001666 return (res);
1667
1668} /* validate_and_test() */
1669
1670
Guido van Rossum3d602e31996-07-21 02:33:56 +00001671validate_not_test(tree)
1672 node *tree;
1673{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001674 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001675 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001676
Guido van Rossum3d602e31996-07-21 02:33:56 +00001677 if (res) {
1678 if (nch == 2)
1679 res = (validate_name(CHILD(tree, 0), "not")
1680 && validate_not_test(CHILD(tree, 1)));
1681 else if (nch == 1)
1682 res = validate_comparison(CHILD(tree, 0));
1683 }
1684 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001685
1686} /* validate_not_test() */
1687
1688
Guido van Rossum3d602e31996-07-21 02:33:56 +00001689validate_comparison(tree)
1690 node *tree;
1691{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001692 int pos;
1693 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001694 int res = (validate_ntype(tree, comparison)
1695 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001696 && validate_expr(CHILD(tree, 0)));
1697
Guido van Rossum3d602e31996-07-21 02:33:56 +00001698 for (pos = 1; res && (pos < nch); pos += 2)
1699 res = (validate_comp_op(CHILD(tree, pos))
1700 && validate_expr(CHILD(tree, pos + 1)));
1701
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001702 return (res);
1703
1704} /* validate_comparison() */
1705
1706
Guido van Rossum3d602e31996-07-21 02:33:56 +00001707validate_comp_op(tree)
1708 node *tree;
1709{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001710 int res = 0;
1711 int nch = NCH(tree);
1712
Guido van Rossum3d602e31996-07-21 02:33:56 +00001713 if (!validate_ntype(tree, comp_op))
1714 return (0);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001715 if (nch == 1) {
1716 /*
1717 * Only child will be a terminal with a well-defined symbolic name
1718 * or a NAME with a string of either 'is' or 'in'
1719 */
1720 tree = CHILD(tree, 0);
1721 switch (TYPE(tree)) {
1722 case LESS:
1723 case GREATER:
1724 case EQEQUAL:
1725 case EQUAL:
1726 case LESSEQUAL:
1727 case GREATEREQUAL:
1728 case NOTEQUAL:
1729 res = 1;
1730 break;
1731 case NAME:
1732 res = ((strcmp(STR(tree), "in") == 0)
1733 || (strcmp(STR(tree), "is") == 0));
1734 if (!res) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00001735 char buff[128];
1736 sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1737 err_string(buff);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001738 }
1739 break;
1740 default:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001741 err_string("Illegal comparison operator type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001742 break;
1743 }
1744 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00001745 else if (res = validate_numnodes(tree, 2, "comp_op")) {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001746 res = (validate_ntype(CHILD(tree, 0), NAME)
1747 && validate_ntype(CHILD(tree, 1), NAME)
1748 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1749 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1750 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1751 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001752 if (!res && !PyErr_Occurred())
1753 err_string("Unknown comparison operator.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001754 }
1755 return (res);
1756
1757} /* validate_comp_op() */
1758
1759
Guido van Rossum3d602e31996-07-21 02:33:56 +00001760validate_expr(tree)
1761 node *tree;
1762{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001763 int j;
1764 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001765 int res = (validate_ntype(tree, expr)
1766 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001767 && validate_xor_expr(CHILD(tree, 0)));
1768
Guido van Rossum3d602e31996-07-21 02:33:56 +00001769 for (j = 2; res && (j < nch); j += 2)
1770 res = (validate_xor_expr(CHILD(tree, j))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001771 && validate_vbar(CHILD(tree, j - 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001772
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001773 return (res);
1774
1775} /* validate_expr() */
1776
1777
Guido van Rossum3d602e31996-07-21 02:33:56 +00001778validate_xor_expr(tree)
1779 node *tree;
1780{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001781 int j;
1782 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001783 int res = (validate_ntype(tree, xor_expr)
1784 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001785 && validate_and_expr(CHILD(tree, 0)));
1786
Guido van Rossum3d602e31996-07-21 02:33:56 +00001787 for (j = 2; res && (j < nch); j += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001788 res = (validate_circumflex(CHILD(tree, j - 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001789 && validate_and_expr(CHILD(tree, j)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001790
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001791 return (res);
1792
1793} /* validate_xor_expr() */
1794
1795
Guido van Rossum3d602e31996-07-21 02:33:56 +00001796validate_and_expr(tree)
1797 node *tree;
1798{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001799 int pos;
1800 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001801 int res = (validate_ntype(tree, and_expr)
1802 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001803 && validate_shift_expr(CHILD(tree, 0)));
1804
Guido van Rossum3d602e31996-07-21 02:33:56 +00001805 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001806 res = (validate_ampersand(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001807 && validate_shift_expr(CHILD(tree, pos + 1)));
Guido van Rossum3d602e31996-07-21 02:33:56 +00001808
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001809 return (res);
1810
1811} /* validate_and_expr() */
1812
1813
1814static int
Guido van Rossum3d602e31996-07-21 02:33:56 +00001815validate_chain_two_ops(tree, termvalid, op1, op2)
1816 node *tree;
1817 int (*termvalid)();
1818 int op1;
1819 int op2;
1820 {
1821 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001822 int nch = NCH(tree);
1823 int res = (is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001824 && (*termvalid)(CHILD(tree, 0)));
1825
Guido van Rossum3d602e31996-07-21 02:33:56 +00001826 for ( ; res && (pos < nch); pos += 2) {
1827 if (TYPE(CHILD(tree, pos)) != op1)
1828 res = validate_ntype(CHILD(tree, pos), op2);
1829 if (res)
1830 res = (*termvalid)(CHILD(tree, pos + 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001831 }
1832 return (res);
1833
1834} /* validate_chain_two_ops() */
1835
1836
Guido van Rossum3d602e31996-07-21 02:33:56 +00001837validate_shift_expr(tree)
1838 node *tree;
1839{
1840 return (validate_ntype(tree, shift_expr)
1841 && validate_chain_two_ops(tree, validate_arith_expr,
1842 LEFTSHIFT, RIGHTSHIFT));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001843
1844} /* validate_shift_expr() */
1845
1846
Guido van Rossum3d602e31996-07-21 02:33:56 +00001847validate_arith_expr(tree)
1848 node *tree;
1849{
1850 return (validate_ntype(tree, arith_expr)
1851 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001852
1853} /* validate_arith_expr() */
1854
1855
Guido van Rossum3d602e31996-07-21 02:33:56 +00001856validate_term(tree)
1857 node *tree;
1858{
1859 int pos = 1;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001860 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001861 int res = (validate_ntype(tree, term)
1862 && is_odd(nch)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001863 && validate_factor(CHILD(tree, 0)));
1864
Guido van Rossum3d602e31996-07-21 02:33:56 +00001865 for ( ; res && (pos < nch); pos += 2)
1866 res = (((TYPE(CHILD(tree, pos)) == STAR)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001867 || (TYPE(CHILD(tree, pos)) == SLASH)
Guido van Rossum3d602e31996-07-21 02:33:56 +00001868 || (TYPE(CHILD(tree, pos)) == PERCENT))
1869 && validate_factor(CHILD(tree, pos + 1)));
1870
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001871 return (res);
1872
1873} /* validate_term() */
1874
1875
Guido van Rossum3d602e31996-07-21 02:33:56 +00001876/* factor:
1877 *
1878 * factor: ('+'|'-'|'~') factor | power
1879 */
1880validate_factor(tree)
1881 node *tree;
1882{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001883 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001884 int res = (validate_ntype(tree, factor)
1885 && (((nch == 2)
1886 && ((TYPE(CHILD(tree, 0)) == PLUS)
1887 || (TYPE(CHILD(tree, 0)) == MINUS)
1888 || (TYPE(CHILD(tree, 0)) == TILDE))
1889 && validate_factor(CHILD(tree, 1)))
1890 || ((nch == 1)
1891 && validate_power(CHILD(tree, 0)))));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001892 return (res);
1893
1894} /* validate_factor() */
1895
1896
Guido van Rossum3d602e31996-07-21 02:33:56 +00001897/* power:
1898 *
1899 * power: atom trailer* ('**' factor)*
1900 */
1901validate_power(tree)
1902 node *tree;
1903{
1904 int pos = 1;
1905 int nch = NCH(tree);
1906 int res = (validate_ntype(tree, power) && (nch >= 1)
1907 && validate_atom(CHILD(tree, 0)));
1908
1909 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
1910 res = validate_trailer(CHILD(tree, pos++));
1911 if (res && (pos < nch)) {
1912 if (!is_even(nch - pos)) {
1913 err_string("Illegal number of nodes for 'power'.");
1914 return (0);
1915 }
1916 for ( ; res && (pos < (nch - 1)); pos += 2)
1917 res = (validate_doublestar(CHILD(tree, pos))
1918 && validate_factor(CHILD(tree, pos + 1)));
1919 }
1920 return (res);
1921
1922} /* validate_power() */
1923
1924
1925validate_atom(tree)
1926 node *tree;
1927{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001928 int pos;
1929 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00001930 int res = validate_ntype(tree, atom) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001931
1932 if (res) {
1933 switch (TYPE(CHILD(tree, 0))) {
1934 case LPAR:
1935 res = ((nch <= 3)
1936 && (validate_rparen(CHILD(tree, nch - 1))));
1937
Guido van Rossum3d602e31996-07-21 02:33:56 +00001938 if (res && (nch == 3))
1939 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001940 break;
1941 case LSQB:
1942 res = ((nch <= 3)
1943 && validate_ntype(CHILD(tree, nch - 1), RSQB));
1944
Guido van Rossum3d602e31996-07-21 02:33:56 +00001945 if (res && (nch == 3))
1946 res = validate_testlist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001947 break;
1948 case LBRACE:
1949 res = ((nch <= 3)
1950 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
1951
Guido van Rossum3d602e31996-07-21 02:33:56 +00001952 if (res && (nch == 3))
1953 res = validate_dictmaker(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001954 break;
1955 case BACKQUOTE:
1956 res = ((nch == 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001957 && validate_testlist(CHILD(tree, 1))
1958 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
1959 break;
1960 case NAME:
1961 case NUMBER:
1962 res = (nch == 1);
1963 break;
1964 case STRING:
Guido van Rossum3d602e31996-07-21 02:33:56 +00001965 for (pos = 1; res && (pos < nch); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001966 res = validate_ntype(CHILD(tree, pos), STRING);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001967 break;
1968 default:
1969 res = 0;
1970 break;
1971 }
1972 }
1973 return (res);
1974
1975} /* validate_atom() */
1976
1977
Guido van Rossum3d602e31996-07-21 02:33:56 +00001978/* funcdef:
1979 * 'def' NAME parameters ':' suite
1980 *
1981 */
1982validate_funcdef(tree)
1983 node *tree;
1984{
1985 return (validate_ntype(tree, funcdef)
1986 && validate_numnodes(tree, 5, "funcdef")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001987 && validate_name(CHILD(tree, 0), "def")
1988 && validate_ntype(CHILD(tree, 1), NAME)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001989 && validate_colon(CHILD(tree, 3))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001990 && validate_parameters(CHILD(tree, 2))
1991 && validate_suite(CHILD(tree, 4)));
1992
1993} /* validate_funcdef() */
1994
1995
Guido van Rossum3d602e31996-07-21 02:33:56 +00001996validate_lambdef(tree)
1997 node *tree;
1998{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00001999 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002000 int res = (validate_ntype(tree, lambdef)
2001 && ((nch == 3) || (nch == 4))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002002 && validate_name(CHILD(tree, 0), "lambda")
2003 && validate_colon(CHILD(tree, nch - 2))
Guido van Rossum3d602e31996-07-21 02:33:56 +00002004 && validate_test(CHILD(tree, nch - 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002005
Guido van Rossum3d602e31996-07-21 02:33:56 +00002006 if (res && (nch == 4))
2007 res = validate_varargslist(CHILD(tree, 1));
2008 else if (!res && !PyErr_Occurred())
2009 validate_numnodes(tree, 3, "lambdef");
2010
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002011 return (res);
2012
2013} /* validate_lambdef() */
2014
2015
Guido van Rossum3d602e31996-07-21 02:33:56 +00002016/* arglist:
2017 *
2018 * argument (',' argument)* [',']
2019 */
2020validate_arglist(tree)
2021 node *tree;
2022{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002023 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002024 int res = (validate_ntype(tree, arglist)
2025 && (nch > 0)
2026 && validate_argument(CHILD(tree, 0)));
2027
2028 if (res && is_even(nch))
2029 res = validate_comma(CHILD(tree, nch - 1));
2030 if (!res && !PyErr_Occurred())
2031 validate_numnodes(tree, 1, "arglist");
2032 --nch;
2033 if (res && (nch > 1)) {
2034 int j = 1;
2035 for ( ; res && (j < (nch - 2)); j += 2)
2036 res = (validate_comma(CHILD(tree, j))
2037 && validate_argument(CHILD(tree, j + 1)));
2038 }
2039 return (res);
2040
2041} /* validate_arglist() */
2042
2043
2044
2045/* argument:
2046 *
2047 * [test '='] test
2048 */
2049validate_argument(tree)
2050 node *tree;
2051{
2052 int nch = NCH(tree);
2053 int res = (validate_ntype(tree, argument)
2054 && ((nch == 1) || (nch == 3))
2055 && validate_test(CHILD(tree, 0)));
2056
2057 if (res && (nch == 3))
2058 res = (validate_equal(CHILD(tree, 1))
2059 && validate_test(CHILD(tree, 2)));
2060
2061 return (res);
2062
2063} /* validate_argument() */
2064
2065
2066
2067/* trailer:
2068 *
2069 * '(' [arglist] ')' | '[' subscript ']' | '.' NAME
2070 */
2071validate_trailer(tree)
2072 node *tree;
2073{
2074 int nch = NCH(tree);
2075 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002076
2077 if (res) {
2078 switch (TYPE(CHILD(tree, 0))) {
2079 case LPAR:
2080 res = validate_rparen(CHILD(tree, nch - 1));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002081 if (res && (nch == 3))
2082 res = validate_arglist(CHILD(tree, 1));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002083 break;
2084 case LSQB:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002085 res = (validate_numnodes(tree, 3, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002086 && validate_subscript(CHILD(tree, 1))
2087 && validate_ntype(CHILD(tree, 2), RSQB));
2088 break;
2089 case DOT:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002090 res = (validate_numnodes(tree, 2, "trailer")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002091 && validate_ntype(CHILD(tree, 1), NAME));
2092 break;
2093 default:
2094 res = 0;
2095 break;
2096 }
2097 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002098 else
2099 validate_numnodes(tree, 2, "trailer");
2100
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002101 return (res);
2102
2103} /* validate_trailer() */
2104
2105
Guido van Rossum3d602e31996-07-21 02:33:56 +00002106/* subscript:
2107 *
2108 * test (',' test)* [','] | [test] ':' [test]
2109 */
2110validate_subscript(tree)
2111 node *tree;
2112{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002113 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002114 int res = validate_ntype(tree, subscript) && (nch >= 1);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002115
Guido van Rossum3d602e31996-07-21 02:33:56 +00002116 if (res && is_even(nch) && (nch >= 4))
2117 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
2118 --nch;
2119 else
2120 res = 0;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002121 if (res && is_odd(nch)) {
Guido van Rossum3d602e31996-07-21 02:33:56 +00002122 if (TYPE(CHILD(tree, 0)) == COLON)
2123 res = validate_numnodes(tree, 1, "subscript");
2124 else {
2125 res = validate_test(CHILD(tree, 0));
2126 if (res && (nch == 3))
2127 res = ((TYPE(CHILD(tree, 1)) == COMMA)
2128 || validate_colon(CHILD(tree, 1)))
2129 && validate_test(CHILD(tree, 2));
2130 else if ((res && (nch >= 5))) {
2131 int pos = 1;
2132 while (res && (pos <= (nch - 2))) {
2133 res = (validate_comma(CHILD(tree, pos))
2134 && validate_test(CHILD(tree, pos + 1)));
2135 pos += 2;
2136 }
2137 }
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002138 }
2139 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002140 else if (nch == 2) {
2141 if (TYPE(CHILD(tree, 0)) == COLON)
2142 res = validate_test(CHILD(tree, 1));
2143 else if (TYPE(CHILD(tree, 1)) == COLON)
2144 res = validate_test(CHILD(tree, 0));
2145 else
2146 res = (validate_test(CHILD(tree, 0))
2147 && validate_comma(CHILD(tree, 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002148 }
2149 return (res);
2150
2151} /* validate_subscript() */
2152
2153
Guido van Rossum3d602e31996-07-21 02:33:56 +00002154validate_exprlist(tree)
2155 node *tree;
2156{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002157 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002158 int res = (validate_ntype(tree, exprlist)
2159 && (nch >= 1)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002160 && validate_expr(CHILD(tree, 0)));
2161
Guido van Rossum3d602e31996-07-21 02:33:56 +00002162 if (res && is_even(nch))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002163 res = validate_comma(CHILD(tree, --nch));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002164 if (res && (nch > 1)) {
2165 int pos;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002166 for (pos = 1; res && (pos < nch); pos += 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002167 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002168 && validate_expr(CHILD(tree, pos + 1)));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002169 }
2170 return (res);
2171
2172} /* validate_exprlist() */
2173
2174
Guido van Rossum3d602e31996-07-21 02:33:56 +00002175validate_dictmaker(tree)
2176 node *tree;
2177{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002178 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002179 int res = (validate_ntype(tree, dictmaker)
2180 && (nch >= 3)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002181 && validate_test(CHILD(tree, 0))
2182 && validate_colon(CHILD(tree, 1))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002183 && validate_test(CHILD(tree, 2)));
2184
Guido van Rossum3d602e31996-07-21 02:33:56 +00002185 if (res && ((nch % 4) == 0))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002186 res = validate_comma(CHILD(tree, --nch));
Guido van Rossum3d602e31996-07-21 02:33:56 +00002187 else if (res)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002188 res = ((nch % 4) == 3);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002189
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002190 if (res && (nch > 3)) {
2191 int pos = 3;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002192 /* ( ',' test ':' test )* */
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002193 while (res && (pos < nch)) {
2194 res = (validate_comma(CHILD(tree, pos))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002195 && validate_test(CHILD(tree, pos + 1))
2196 && validate_colon(CHILD(tree, pos + 2))
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002197 && validate_test(CHILD(tree, pos + 3)));
2198 pos += 4;
2199 }
2200 }
2201 return (res);
2202
2203} /* validate_dictmaker() */
2204
2205
Guido van Rossum3d602e31996-07-21 02:33:56 +00002206validate_eval_input(tree)
2207 node *tree;
2208{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002209 int pos;
2210 int nch = NCH(tree);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002211 int res = (validate_ntype(tree, eval_input)
2212 && (nch >= 2)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002213 && validate_testlist(CHILD(tree, 0))
2214 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2215
Guido van Rossum3d602e31996-07-21 02:33:56 +00002216 for (pos = 1; res && (pos < (nch - 1)); ++pos)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002217 res = validate_ntype(CHILD(tree, pos), NEWLINE);
Guido van Rossum3d602e31996-07-21 02:33:56 +00002218
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002219 return (res);
2220
2221} /* validate_eval_input() */
2222
2223
Guido van Rossum3d602e31996-07-21 02:33:56 +00002224validate_node(tree)
2225 node *tree;
2226{
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002227 int nch = 0; /* num. children on current node */
2228 int res = 1; /* result value */
2229 node* next = 0; /* node to process after this one */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002230
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002231 while (res & (tree != 0)) {
2232 nch = NCH(tree);
2233 next = 0;
2234 switch (TYPE(tree)) {
2235 /*
2236 * Definition nodes.
2237 */
2238 case funcdef:
2239 res = validate_funcdef(tree);
2240 break;
2241 case classdef:
2242 res = validate_class(tree);
2243 break;
2244 /*
2245 * "Trivial" parse tree nodes.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002246 * (Why did I call these trivial?)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002247 */
2248 case stmt:
2249 res = validate_stmt(tree);
2250 break;
2251 case small_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002252 /*
2253 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
2254 * | import_stmt | global_stmt | access_stmt | exec_stmt
2255 */
2256 res = validate_small_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002257 break;
2258 case flow_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002259 res = (validate_numnodes(tree, 1, "flow_stmt")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002260 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2261 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2262 || (TYPE(CHILD(tree, 0)) == return_stmt)
Guido van Rossum3d602e31996-07-21 02:33:56 +00002263 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2264 if (res)
2265 next = CHILD(tree, 0);
2266 else if (nch == 1)
2267 err_string("Illegal flow_stmt type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002268 break;
2269 /*
2270 * Compound statements.
2271 */
2272 case simple_stmt:
2273 res = validate_simple_stmt(tree);
2274 break;
2275 case compound_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002276 res = validate_compound_stmt(tree);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002277 break;
2278 /*
2279 * Fundemental statements.
2280 */
2281 case expr_stmt:
2282 res = validate_expr_stmt(tree);
2283 break;
2284 case print_stmt:
2285 res = validate_print_stmt(tree);
2286 break;
2287 case del_stmt:
2288 res = validate_del_stmt(tree);
2289 break;
2290 case pass_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002291 res = (validate_numnodes(tree, 1, "pass")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002292 && validate_name(CHILD(tree, 0), "pass"));
2293 break;
2294 case break_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002295 res = (validate_numnodes(tree, 1, "break")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002296 && validate_name(CHILD(tree, 0), "break"));
2297 break;
2298 case continue_stmt:
Guido van Rossum3d602e31996-07-21 02:33:56 +00002299 res = (validate_numnodes(tree, 1, "continue")
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002300 && validate_name(CHILD(tree, 0), "continue"));
2301 break;
2302 case return_stmt:
2303 res = validate_return_stmt(tree);
2304 break;
2305 case raise_stmt:
2306 res = validate_raise_stmt(tree);
2307 break;
2308 case import_stmt:
2309 res = validate_import_stmt(tree);
2310 break;
2311 case global_stmt:
2312 res = validate_global_stmt(tree);
2313 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002314#if defined(access_stmt) && defined(accesstype)
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002315 case access_stmt:
2316 res = validate_access_stmt(tree);
2317 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002318#endif
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002319 case exec_stmt:
2320 res = validate_exec_stmt(tree);
2321 break;
2322 case if_stmt:
2323 res = validate_if(tree);
2324 break;
2325 case while_stmt:
2326 res = validate_while(tree);
2327 break;
2328 case for_stmt:
2329 res = validate_for(tree);
2330 break;
2331 case try_stmt:
2332 res = validate_try(tree);
2333 break;
2334 case suite:
2335 res = validate_suite(tree);
2336 break;
2337 /*
2338 * Expression nodes.
2339 */
2340 case testlist:
2341 res = validate_testlist(tree);
2342 break;
2343 case test:
2344 res = validate_test(tree);
2345 break;
2346 case and_test:
2347 res = validate_and_test(tree);
2348 break;
2349 case not_test:
2350 res = validate_not_test(tree);
2351 break;
2352 case comparison:
2353 res = validate_comparison(tree);
2354 break;
2355 case exprlist:
2356 res = validate_exprlist(tree);
2357 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002358 case comp_op:
2359 res = validate_comp_op(tree);
2360 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002361 case expr:
2362 res = validate_expr(tree);
2363 break;
2364 case xor_expr:
2365 res = validate_xor_expr(tree);
2366 break;
2367 case and_expr:
2368 res = validate_and_expr(tree);
2369 break;
2370 case shift_expr:
2371 res = validate_shift_expr(tree);
2372 break;
2373 case arith_expr:
2374 res = validate_arith_expr(tree);
2375 break;
2376 case term:
2377 res = validate_term(tree);
2378 break;
2379 case factor:
2380 res = validate_factor(tree);
2381 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002382 case power:
2383 res = validate_power(tree);
2384 break;
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002385 case atom:
2386 res = validate_atom(tree);
2387 break;
Guido van Rossum3d602e31996-07-21 02:33:56 +00002388
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002389 default:
2390 /* Hopefully never reached! */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002391 err_string("Unrecogniged node type.");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002392 res = 0;
2393 break;
2394 }
2395 tree = next;
2396 }
2397 return (res);
2398
2399} /* validate_node() */
2400
2401
Guido van Rossum3d602e31996-07-21 02:33:56 +00002402validate_expr_tree(tree)
2403 node *tree;
2404{
2405 int res = validate_eval_input(tree);
2406
2407 if (!res && !PyErr_Occurred())
2408 err_string("Could not validate expression tuple.");
2409
2410 return (res);
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002411
2412} /* validate_expr_tree() */
2413
2414
Guido van Rossum3d602e31996-07-21 02:33:56 +00002415/* file_input:
2416 * (NEWLINE | stmt)* ENDMARKER
2417 */
2418validate_file_input(tree)
2419 node *tree;
2420{
2421 int j = 0;
2422 int nch = NCH(tree) - 1;
2423 int res = ((nch >= 0)
2424 && validate_ntype(CHILD(tree, nch), ENDMARKER));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002425
Guido van Rossum3d602e31996-07-21 02:33:56 +00002426 for ( ; res && (j < nch); ++j) {
2427 if (TYPE(CHILD(tree, j)) == stmt)
2428 res = validate_stmt(CHILD(tree, j));
2429 else
2430 res = validate_newline(CHILD(tree, j));
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002431 }
Guido van Rossum3d602e31996-07-21 02:33:56 +00002432 /* This stays in to prevent any internal failues from getting to the
2433 * user. Hopefully, this won't be needed. If a user reports getting
2434 * this, we have some debugging to do.
2435 */
2436 if (!res && !PyErr_Occurred())
2437 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2438
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002439 return (res);
2440
2441} /* validate_suite_tree() */
2442
2443
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002444/* Functions exported by this module. Most of this should probably
2445 * be converted into an AST object with methods, but that is better
2446 * done directly in Python, allowing subclasses to be created directly.
Guido van Rossum3d602e31996-07-21 02:33:56 +00002447 * We'd really have to write a wrapper around it all anyway to allow
2448 * inheritance.
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002449 */
2450static PyMethodDef parser_functions[] = {
Guido van Rossum3d602e31996-07-21 02:33:56 +00002451 {"ast2tuple", parser_ast2tuple, 1,
2452 "Creates a tuple-tree representation of an AST."},
2453 {"compileast", parser_compileast, 1,
2454 "Compiles an AST object into a code object."},
2455 {"expr", parser_expr, 1,
2456 "Creates an AST object from an expression."},
2457 {"isexpr", parser_isexpr, 1,
2458 "Determines if an AST object was created from an expression."},
2459 {"issuite", parser_issuite, 1,
2460 "Determines if an AST object was created from a suite."},
2461 {"suite", parser_suite, 1,
2462 "Creates an AST object from a suite."},
2463 {"tuple2ast", parser_tuple2ast, 1,
2464 "Creates an AST object from a tuple-tree representation."},
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002465
2466 {0, 0, 0}
2467 };
2468
2469
Guido van Rossum52f2c051993-11-10 12:53:24 +00002470void
Guido van Rossum3d602e31996-07-21 02:33:56 +00002471initparser()
2472 {
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002473 PyObject* module = Py_InitModule("parser", parser_functions);
2474 PyObject* dict = PyModule_GetDict(module);
2475
2476 parser_error = PyString_FromString("parser.ParserError");
2477
2478 if ((parser_error == 0)
2479 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2480 /*
2481 * This is serious.
2482 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002483 Py_FatalError("can't define parser.ParserError");
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002484 }
2485 /*
2486 * Nice to have, but don't cry if we fail.
2487 */
Guido van Rossum3d602e31996-07-21 02:33:56 +00002488 Py_INCREF(&PyAST_Type);
2489 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2490
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002491 PyDict_SetItemString(dict, "__copyright__",
2492 PyString_FromString(parser_copyright_string));
2493 PyDict_SetItemString(dict, "__doc__",
2494 PyString_FromString(parser_doc_string));
2495 PyDict_SetItemString(dict, "__version__",
2496 PyString_FromString(parser_version_string));
2497
2498} /* initparser() */
2499
2500
2501/*
Guido van Rossum3d602e31996-07-21 02:33:56 +00002502 * end of parsermodule.c
Guido van Rossumd9e9f9c1995-10-11 17:35:38 +00002503 */