parsermodule.c revision 69b9ae4e0bd101ad065575c206a2c247d3449a4c
1/*  parsermodule.c
2 *
3 *  Copyright 1995-1996 by Fred L. Drake, Jr. and Virginia Polytechnic
4 *  Institute and State University, Blacksburg, Virginia, USA.
5 *  Portions copyright 1991-1995 by Stichting Mathematisch Centrum,
6 *  Amsterdam, The Netherlands.  Copying is permitted under the terms
7 *  associated with the main Python distribution, with the additional
8 *  restriction that this additional notice be included and maintained
9 *  on all distributed copies.
10 *
11 *  This module serves to replace the original parser module written
12 *  by Guido.  The functionality is not matched precisely, but the
13 *  original may be implemented on top of this.  This is desirable
14 *  since the source of the text to be parsed is now divorced from
15 *  this interface.
16 *
17 *  Unlike the prior interface, the ability to give a parse tree
18 *  produced by Python code as a tuple to the compiler is enabled by
19 *  this module.  See the documentation for more details.
20 */
21
22#include "Python.h"			/* general Python API		  */
23#include "graminit.h"			/* symbols defined in the grammar */
24#include "node.h"			/* internal parser structure	  */
25#include "token.h"			/* token definitions		  */
26					/* ISTERMINAL() / ISNONTERMINAL() */
27#include "compile.h"			/* PyNode_Compile()		  */
28
29/*
30 *  All the "fudge" declarations are here:
31 *
32 *  This isn't part of the Python runtime, but it's in the library somewhere.
33 *  Where it is varies a bit, so just declare it.  Don't use any prototype;
34 *  different systems declare it a little differently, and we don't need the
35 *  extra warnings.
36 */
37extern char* strdup();
38
39
40/*  String constants used to initialize module attributes.
41 *
42 */
43static char*
44parser_copyright_string
45= "Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
46University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
47Virginia, USA.  Portions copyright 1991-1995 by Stichting Mathematisch\n\
48Centrum, Amsterdam, The Netherlands.";
49
50
51static char*
52parser_doc_string
53= "This is an interface to Python's internal parser.";
54
55static char*
56parser_version_string = "0.4";
57
58
59typedef PyObject* (*SeqMaker) Py_PROTO((int length));
60typedef void (*SeqInserter) Py_PROTO((PyObject* sequence,
61				      int index,
62				      PyObject* element));
63
64/*  The function below is copyrigthed by Stichting Mathematisch Centrum.  The
65 *  original copyright statement is included below, and continues to apply
66 *  in full to the function immediately following.  All other material is
67 *  original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
68 *  Institute and State University.  Changes were made to comply with the
69 *  new naming conventions.  Added arguments to provide support for creating
70 *  lists as well as tuples, and optionally including the line numbers.
71 */
72
73/***********************************************************
74Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
75The Netherlands.
76
77                        All Rights Reserved
78
79Permission to use, copy, modify, and distribute this software and its
80documentation for any purpose and without fee is hereby granted,
81provided that the above copyright notice appear in all copies and that
82both that copyright notice and this permission notice appear in
83supporting documentation, and that the names of Stichting Mathematisch
84Centrum or CWI or Corporation for National Research Initiatives or
85CNRI not be used in advertising or publicity pertaining to
86distribution of the software without specific, written prior
87permission.
88
89While CWI is the initial source for this software, a modified version
90is made available by the Corporation for National Research Initiatives
91(CNRI) at the Internet address ftp://ftp.python.org.
92
93STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
94REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
95MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
96CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
97DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
98PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
99TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
100PERFORMANCE OF THIS SOFTWARE.
101
102******************************************************************/
103
104static PyObject*
105node2tuple(n, mkseq, addelem, lineno)
106     node *n;				/* node to convert		 */
107     SeqMaker mkseq;			/* create sequence		 */
108     SeqInserter addelem;		/* func. to add elem. in seq.	 */
109     int lineno;			/* include line numbers?	 */
110{
111    if (n == NULL) {
112	Py_INCREF(Py_None);
113	return Py_None;
114    }
115    if (ISNONTERMINAL(TYPE(n))) {
116	int i;
117	PyObject *v, *w;
118	v = mkseq(1 + NCH(n));
119	if (v == NULL)
120	    return v;
121	w = PyInt_FromLong(TYPE(n));
122	if (w == NULL) {
123	    Py_DECREF(v);
124	    return NULL;
125	}
126	addelem(v, 0, w);
127	for (i = 0; i < NCH(n); i++) {
128	    w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
129	    if (w == NULL) {
130		Py_DECREF(v);
131		return NULL;
132	    }
133	    addelem(v, i+1, w);
134	}
135	return (v);
136    }
137    else if (ISTERMINAL(TYPE(n))) {
138	PyObject *result = mkseq(2 + lineno);
139	if (result != NULL) {
140	    addelem(result, 0, PyInt_FromLong(TYPE(n)));
141	    addelem(result, 1, PyString_FromString(STR(n)));
142	    if (lineno == 1)
143		addelem(result, 2, PyInt_FromLong(n->n_lineno));
144	}
145	return (result);
146    }
147    else {
148	PyErr_SetString(PyExc_SystemError,
149			"unrecognized parse tree node type");
150	return NULL;
151    }
152}   /* node2tuple() */
153/*
154 *  End of material copyrighted by Stichting Mathematisch Centrum.
155 */
156
157
158
159/*  There are two types of intermediate objects we're interested in:
160 *  'eval' and 'exec' types.  These constants can be used in the ast_type
161 *  field of the object type to identify which any given object represents.
162 *  These should probably go in an external header to allow other extensions
163 *  to use them, but then, we really should be using C++ too.  ;-)
164 *
165 *  The PyAST_FRAGMENT type is not currently supported.  Maybe not useful?
166 *  Haven't decided yet.
167 */
168
169#define PyAST_EXPR	1
170#define PyAST_SUITE	2
171#define PyAST_FRAGMENT	3
172
173
174/*  These are the internal objects and definitions required to implement the
175 *  AST type.  Most of the internal names are more reminiscent of the 'old'
176 *  naming style, but the code uses the new naming convention.
177 */
178
179static PyObject*
180parser_error = 0;
181
182
183typedef struct _PyAST_Object {
184
185    PyObject_HEAD			/* standard object header	    */
186    node* ast_node;			/* the node* returned by the parser */
187    int	  ast_type;			/* EXPR or SUITE ?		    */
188
189} PyAST_Object;
190
191
192staticforward void parser_free Py_PROTO((PyAST_Object *ast));
193staticforward int  parser_compare Py_PROTO((PyAST_Object *left,
194					    PyAST_Object *right));
195
196
197/* static */
198PyTypeObject PyAST_Type = {
199
200    PyObject_HEAD_INIT(NULL)
201    0,
202    "ast",				/* tp_name		*/
203    sizeof(PyAST_Object),		/* tp_basicsize		*/
204    0,					/* tp_itemsize		*/
205    (destructor)parser_free,		/* tp_dealloc		*/
206    0,					/* tp_print		*/
207    0,					/* tp_getattr		*/
208    0,					/* tp_setattr		*/
209    (cmpfunc)parser_compare,		/* tp_compare		*/
210    0,					/* tp_repr		*/
211    0,					/* tp_as_number		*/
212    0,					/* tp_as_sequence	*/
213    0,					/* tp_as_mapping	*/
214    0,					/* tp_hash		*/
215    0,					/* tp_call		*/
216    0,					/* tp_str		*/
217    0,					/* tp_getattro		*/
218    0,					/* tp_setattro		*/
219
220    /* Functions to access object as input/output buffer */
221    0,					/* tp_as_buffer		*/
222
223    /* Space for future expansion */
224    0,					/* tp_xxx4		*/
225
226    /* __doc__ */
227    "Intermediate representation of a Python parse tree."
228
229};  /* PyAST_Type */
230
231
232static int
233parser_compare_nodes(left, right)
234     node *left;
235     node *right;
236{
237    int j;
238
239    if (TYPE(left) < TYPE(right))
240	return (-1);
241
242    if (TYPE(right) < TYPE(left))
243	return (1);
244
245    if (ISTERMINAL(TYPE(left)))
246	return (strcmp(STR(left), STR(right)));
247
248    if (NCH(left) < NCH(right))
249	return (-1);
250
251    if (NCH(right) < NCH(left))
252	return (1);
253
254    for (j = 0; j < NCH(left); ++j) {
255	int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
256
257	if (v)
258	    return (v);
259    }
260    return (0);
261
262}   /* parser_compare_nodes() */
263
264
265/*  int parser_compare(PyAST_Object* left, PyAST_Object* right)
266 *
267 *  Comparison function used by the Python operators ==, !=, <, >, <=, >=
268 *  This really just wraps a call to parser_compare_nodes() with some easy
269 *  checks and protection code.
270 *
271 */
272static int
273parser_compare(left, right)
274     PyAST_Object *left;
275     PyAST_Object *right;
276{
277    if (left == right)
278	return (0);
279
280    if ((left == 0) || (right == 0))
281	return (-1);
282
283    return (parser_compare_nodes(left->ast_node, right->ast_node));
284
285}   /* parser_compare() */
286
287
288/*  parser_newastobject(node* ast)
289 *
290 *  Allocates a new Python object representing an AST.  This is simply the
291 *  'wrapper' object that holds a node* and allows it to be passed around in
292 *  Python code.
293 *
294 */
295static PyObject*
296parser_newastobject(ast, type)
297     node *ast;
298     int type;
299{
300    PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
301
302    if (o != 0) {
303	o->ast_node = ast;
304	o->ast_type = type;
305    }
306    return ((PyObject*)o);
307
308}   /* parser_newastobject() */
309
310
311/*  void parser_free(PyAST_Object* ast)
312 *
313 *  This is called by a del statement that reduces the reference count to 0.
314 *
315 */
316static void
317parser_free(ast)
318     PyAST_Object *ast;
319{
320    PyNode_Free(ast->ast_node);
321    PyMem_DEL(ast);
322
323}   /* parser_free() */
324
325
326/*  parser_ast2tuple(PyObject* self, PyObject* args)
327 *
328 *  This provides conversion from a node* to a tuple object that can be
329 *  returned to the Python-level caller.  The AST object is not modified.
330 *
331 */
332static PyObject*
333parser_ast2tuple(self, args)
334     PyObject *self;
335     PyObject *args;
336{
337    PyObject *ast;
338    PyObject *line_option = 0;
339    PyObject *res = 0;
340
341    if (PyArg_ParseTuple(args, "O!|O:ast2tuple", &PyAST_Type, &ast,
342			 &line_option)) {
343	int lineno = 0;
344	if (line_option != 0) {
345	    lineno = PyObject_IsTrue(line_option);
346	    lineno = lineno ? 1 : 0;
347	}
348	/*
349	 *  Convert AST into a tuple representation.  Use Guido's function,
350	 *  since it's known to work already.
351	 */
352	res = node2tuple(((PyAST_Object*)ast)->ast_node,
353			 PyTuple_New, PyTuple_SetItem, lineno);
354    }
355    return (res);
356
357}   /* parser_ast2tuple() */
358
359
360/*  parser_ast2tuple(PyObject* self, PyObject* args)
361 *
362 *  This provides conversion from a node* to a tuple object that can be
363 *  returned to the Python-level caller.  The AST object is not modified.
364 *
365 */
366static PyObject*
367parser_ast2list(self, args)
368     PyObject *self;
369     PyObject *args;
370{
371    PyObject *ast;
372    PyObject *line_option = 0;
373    PyObject *res = 0;
374
375    if (PyArg_ParseTuple(args, "O!|O:ast2list", &PyAST_Type, &ast,
376			 &line_option)) {
377	int lineno = 0;
378	if (line_option != 0) {
379	    lineno = PyObject_IsTrue(line_option);
380	    lineno = lineno ? 1 : 0;
381	}
382	/*
383	 *  Convert AST into a tuple representation.  Use Guido's function,
384	 *  since it's known to work already.
385	 */
386	res = node2tuple(((PyAST_Object*)ast)->ast_node,
387			 PyList_New, PyList_SetItem, lineno);
388    }
389    return (res);
390
391}   /* parser_ast2list() */
392
393
394/*  parser_compileast(PyObject* self, PyObject* args)
395 *
396 *  This function creates code objects from the parse tree represented by
397 *  the passed-in data object.  An optional file name is passed in as well.
398 *
399 */
400static PyObject*
401parser_compileast(self, args)
402     PyObject *self;
403     PyObject *args;
404{
405    PyAST_Object* ast;
406    PyObject*     res = 0;
407    char*	  str = "<ast>";
408
409    if (PyArg_ParseTuple(args, "O!|s", &PyAST_Type, &ast, &str))
410	res = (PyObject*) PyNode_Compile(ast->ast_node, str);
411
412    return (res);
413
414}   /* parser_compileast() */
415
416
417/*  PyObject* parser_isexpr(PyObject* self, PyObject* args)
418 *  PyObject* parser_issuite(PyObject* self, PyObject* args)
419 *
420 *  Checks the passed-in AST object to determine if it is an expression or
421 *  a statement suite, respectively.  The return is a Python truth value.
422 *
423 */
424static PyObject*
425parser_isexpr(self, args)
426     PyObject *self;
427     PyObject *args;
428{
429    PyAST_Object* ast;
430    PyObject* res = 0;
431
432    if (PyArg_ParseTuple(args, "O!:isexpr", &PyAST_Type, &ast)) {
433	/*
434	 *  Check to see if the AST represents an expression or not.
435	 */
436	res = (ast->ast_type == PyAST_EXPR) ? Py_True : Py_False;
437	Py_INCREF(res);
438    }
439    return (res);
440
441}   /* parser_isexpr() */
442
443
444static PyObject*
445parser_issuite(self, args)
446     PyObject *self;
447     PyObject *args;
448{
449    PyAST_Object* ast;
450    PyObject* res = 0;
451
452    if (PyArg_ParseTuple(args, "O!:issuite", &PyAST_Type, &ast)) {
453	/*
454	 *  Check to see if the AST represents an expression or not.
455	 */
456	res = (ast->ast_type == PyAST_EXPR) ? Py_False : Py_True;
457	Py_INCREF(res);
458    }
459    return (res);
460
461}   /* parser_issuite() */
462
463
464/*  err_string(char* message)
465 *
466 *  Sets the error string for an exception of type ParserError.
467 *
468 */
469static void
470err_string(message)
471     char *message;
472{
473    PyErr_SetString(parser_error, message);
474
475}  /* err_string() */
476
477
478/*  PyObject* parser_do_parse(PyObject* args, int type)
479 *
480 *  Internal function to actually execute the parse and return the result if
481 *  successful, or set an exception if not.
482 *
483 */
484static PyObject*
485parser_do_parse(args, type)
486     PyObject *args;
487     int type;
488{
489    char*     string = 0;
490    PyObject* res    = 0;
491
492    if (PyArg_ParseTuple(args, "s", &string)) {
493	node* n = PyParser_SimpleParseString(string,
494					     (type == PyAST_EXPR)
495					     ? eval_input : file_input);
496
497	if (n != 0)
498	    res = parser_newastobject(n, type);
499	else
500	    err_string("Could not parse string.");
501    }
502    return (res);
503
504}  /* parser_do_parse() */
505
506
507/*  PyObject* parser_expr(PyObject* self, PyObject* args)
508 *  PyObject* parser_suite(PyObject* self, PyObject* args)
509 *
510 *  External interfaces to the parser itself.  Which is called determines if
511 *  the parser attempts to recognize an expression ('eval' form) or statement
512 *  suite ('exec' form).  The real work is done by parser_do_parse() above.
513 *
514 */
515static PyObject*
516parser_expr(self, args)
517     PyObject *self;
518     PyObject *args;
519{
520    return (parser_do_parse(args, PyAST_EXPR));
521
522}   /* parser_expr() */
523
524
525static PyObject*
526parser_suite(self, args)
527     PyObject *self;
528     PyObject *args;
529{
530    return (parser_do_parse(args, PyAST_SUITE));
531
532}   /* parser_suite() */
533
534
535
536/*  This is the messy part of the code.  Conversion from a tuple to an AST
537 *  object requires that the input tuple be valid without having to rely on
538 *  catching an exception from the compiler.  This is done to allow the
539 *  compiler itself to remain fast, since most of its input will come from
540 *  the parser directly, and therefore be known to be syntactically correct.
541 *  This validation is done to ensure that we don't core dump the compile
542 *  phase, returning an exception instead.
543 *
544 *  Two aspects can be broken out in this code:  creating a node tree from
545 *  the tuple passed in, and verifying that it is indeed valid.  It may be
546 *  advantageous to expand the number of AST types to include funcdefs and
547 *  lambdadefs to take advantage of the optimizer, recognizing those ASTs
548 *  here.  They are not necessary, and not quite as useful in a raw form.
549 *  For now, let's get expressions and suites working reliably.
550 */
551
552
553staticforward node* build_node_tree Py_PROTO((PyObject *tuple));
554staticforward int   validate_expr_tree Py_PROTO((node *tree));
555staticforward int   validate_file_input Py_PROTO((node *tree));
556
557
558/*  PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
559 *
560 *  This is the public function, called from the Python code.  It receives a
561 *  single tuple object from the caller, and creates an AST object if the
562 *  tuple can be validated.  It does this by checking the first code of the
563 *  tuple, and, if acceptable, builds the internal representation.  If this
564 *  step succeeds, the internal representation is validated as fully as
565 *  possible with the various validate_*() routines defined below.
566 *
567 *  This function must be changed if support is to be added for PyAST_FRAGMENT
568 *  AST objects.
569 *
570 */
571static PyObject*
572parser_tuple2ast(self, args)
573     PyObject *self;
574     PyObject *args;
575{
576    PyObject *ast = 0;
577    PyObject *tuple = 0;
578    PyObject *temp = 0;
579    int ok;
580    int start_sym = 0;
581
582    if (!PyArg_ParseTuple(args, "O:tuple2ast", &tuple))
583	return (0);
584    if (!PySequence_Check(tuple)) {
585	PyErr_SetString(PyExc_ValueError,
586			"tuple2ast() requires a single sequence argument");
587	return (0);
588    }
589    /*
590     *	This mess of tests is written this way so we can use the abstract
591     *	object interface (AOI).  Unfortunately, the AOI increments reference
592     *	counts, which requires that we store a pointer to retrieved object
593     *	so we can DECREF it after the check.  But we really should accept
594     *	lists as well as tuples at the very least.
595     */
596    ok = PyObject_Length(tuple) >= 2;
597    if (ok) {
598	temp = PySequence_GetItem(tuple, 0);
599	ok = (temp != NULL) && PyInt_Check(temp);
600	if (ok)
601	    /* this is used after the initial checks: */
602	    start_sym = PyInt_AsLong(temp);
603	Py_XDECREF(temp);
604    }
605    if (ok) {
606	temp = PySequence_GetItem(tuple, 1);
607	ok = (temp != NULL) && PySequence_Check(temp);
608	Py_XDECREF(temp);
609    }
610    if (ok) {
611	temp = PySequence_GetItem(tuple, 1);
612	ok = (temp != NULL) && PyObject_Length(temp) >= 2;
613	if (ok) {
614	    PyObject *temp2 = PySequence_GetItem(temp, 0);
615	    if (temp2 != NULL) {
616		ok = PyInt_Check(temp2);
617		Py_DECREF(temp2);
618	    }
619	}
620	Py_XDECREF(temp);
621    }
622    /* If we've failed at some point, get out of here. */
623    if (!ok) {
624	err_string("malformed sequence for tuple2ast()");
625	return (0);
626    }
627    /*
628     *  This might be a valid parse tree, but let's do a quick check
629     *  before we jump the gun.
630     */
631    if (start_sym == eval_input) {
632	/*  Might be an eval form.  */
633	node* expression = build_node_tree(tuple);
634
635	if ((expression != 0) && validate_expr_tree(expression))
636	    ast = parser_newastobject(expression, PyAST_EXPR);
637    }
638    else if (start_sym == file_input) {
639	/*  This looks like an exec form so far.  */
640	node* suite_tree = build_node_tree(tuple);
641
642	if ((suite_tree != 0) && validate_file_input(suite_tree))
643	    ast = parser_newastobject(suite_tree, PyAST_SUITE);
644    }
645    else
646	/*  This is a fragment, and is not yet supported.  Maybe they
647	 *  will be if I find a use for them.
648	 */
649	err_string("Fragmentary parse trees not supported.");
650
651    /*  Make sure we throw an exception on all errors.  We should never
652     *  get this, but we'd do well to be sure something is done.
653     */
654    if ((ast == 0) && !PyErr_Occurred())
655	err_string("Unspecified ast error occurred.");
656
657    return (ast);
658
659}   /* parser_tuple2ast() */
660
661
662/*  int check_terminal_tuple()
663 *
664 *  Check a tuple to determine that it is indeed a valid terminal
665 *  node.  The node is known to be required as a terminal, so we throw
666 *  an exception if there is a failure.
667 *
668 *  The format of an acceptable terminal tuple is "(is[i])": the fact
669 *  that elem is a tuple and the integer is a valid terminal symbol
670 *  has been established before this function is called.  We must
671 *  check the length of the tuple and the type of the second element
672 *  and optional third element.  We do *NOT* check the actual text of
673 *  the string element, which we could do in many cases.  This is done
674 *  by the validate_*() functions which operate on the internal
675 *  representation.
676 */
677static int
678check_terminal_tuple(elem)
679     PyObject *elem;
680{
681    int   len = PyObject_Length(elem);
682    int   res = 1;
683    char* str = "Illegal terminal symbol; bad node length.";
684
685    if ((len == 2) || (len == 3)) {
686	PyObject *temp = PySequence_GetItem(elem, 1);
687	res = PyString_Check(temp);
688	str = "Illegal terminal symbol; expected a string.";
689	if (res && (len == 3)) {
690	    PyObject* third = PySequence_GetItem(elem, 2);
691	    res = PyInt_Check(third);
692	    str = "Invalid third element of terminal node.";
693	    Py_XDECREF(third);
694	}
695	Py_XDECREF(temp);
696    }
697    else {
698	res = 0;
699    }
700    if (!res) {
701	elem = Py_BuildValue("(os)", elem, str);
702	PyErr_SetObject(parser_error, elem);
703    }
704    return (res);
705
706}   /* check_terminal_tuple() */
707
708
709/*  node* build_node_children()
710 *
711 *  Iterate across the children of the current non-terminal node and build
712 *  their structures.  If successful, return the root of this portion of
713 *  the tree, otherwise, 0.  Any required exception will be specified already,
714 *  and no memory will have been deallocated.
715 *
716 */
717static node*
718build_node_children(tuple, root, line_num)
719     PyObject *tuple;
720     node *root;
721     int *line_num;
722{
723    int len = PyObject_Length(tuple);
724    int i;
725
726    for (i = 1; i < len; ++i) {
727	/* elem must always be a tuple, however simple */
728	PyObject* elem = PySequence_GetItem(tuple, i);
729	int ok = elem != NULL;
730	long  type = 0;
731	char *strn = 0;
732
733	if (ok)
734	    ok = PySequence_Check(elem);
735	if (ok) {
736	    PyObject *temp = PySequence_GetItem(elem, 0);
737	    if (temp == NULL)
738		ok = 0;
739	    else {
740		ok = PyInt_Check(temp);
741		if (ok)
742		    type = PyInt_AsLong(temp);
743		Py_DECREF(temp);
744	    }
745	}
746	if (!ok) {
747	    PyErr_SetObject(parser_error,
748			    Py_BuildValue("(os)", elem,
749					  "Illegal node construct."));
750	    Py_XDECREF(elem);
751	    return (0);
752	}
753	if (ISTERMINAL(type)) {
754	    if (check_terminal_tuple(elem)) {
755		PyObject *temp = PySequence_GetItem(elem, 1);
756
757		strn = strdup(PyString_AsString(temp));
758		Py_XDECREF(temp);
759
760		if (PyObject_Length(elem) == 3) {
761		    PyObject* temp = PySequence_GetItem(elem, 2);
762		    *line_num = PyInt_AsLong(temp);
763		    Py_DECREF(temp);
764		}
765	    }
766	    else {
767		Py_XDECREF(elem);
768		return (0);
769	    }
770	}
771	else if (!ISNONTERMINAL(type)) {
772	    /*
773	     *  It has to be one or the other; this is an error.
774	     *  Throw an exception.
775	     */
776	    PyErr_SetObject(parser_error,
777			    Py_BuildValue("(os)", elem,
778					  "Unknown node type."));
779	    Py_XDECREF(elem);
780	    return (0);
781	}
782	PyNode_AddChild(root, type, strn, *line_num);
783
784	if (ISNONTERMINAL(type)) {
785	    node* new_child = CHILD(root, i - 1);
786
787	    if (new_child != build_node_children(elem, new_child, line_num)) {
788		Py_XDECREF(elem);
789		return (0);
790	    }
791	}
792	else if (type == NEWLINE) {	/* It's true:  we increment the     */
793	    ++(*line_num);		/* line number *after* the newline! */
794	}
795	Py_XDECREF(elem);
796    }
797    return (root);
798
799}   /* build_node_children() */
800
801
802static node*
803build_node_tree(tuple)
804     PyObject *tuple;
805{
806    node* res = 0;
807    PyObject *temp = PySequence_GetItem(tuple, 0);
808    long  num = -1;
809
810    if (temp != NULL)
811	num = PyInt_AsLong(temp);
812    Py_XDECREF(temp);
813    if (ISTERMINAL(num)) {
814	/*
815	 *  The tuple is simple, but it doesn't start with a start symbol.
816	 *  Throw an exception now and be done with it.
817	 */
818	tuple = Py_BuildValue("(os)", tuple,
819		    "Illegal ast tuple; cannot start with terminal symbol.");
820	PyErr_SetObject(parser_error, tuple);
821    }
822    else if (ISNONTERMINAL(num)) {
823	/*
824	 *  Not efficient, but that can be handled later.
825	 */
826	int line_num = 0;
827
828	res = PyNode_New(num);
829	if (res != build_node_children(tuple, res, &line_num)) {
830	    PyNode_Free(res);
831	    res = 0;
832	}
833    }
834    else
835	/*  The tuple is illegal -- if the number is neither TERMINAL nor
836	 *  NONTERMINAL, we can't use it.
837	 */
838	PyErr_SetObject(parser_error,
839			Py_BuildValue("(os)", tuple,
840				      "Illegal component tuple."));
841
842    return (res);
843
844}   /* build_node_tree() */
845
846
847#ifdef HAVE_OLD_CPP
848#define VALIDATER(n)    static int validate_/**/n Py_PROTO((node *tree))
849#else
850#define	VALIDATER(n)	static int validate_##n Py_PROTO((node *tree))
851#endif
852
853
854/*
855 *  Validation routines used within the validation section:
856 */
857staticforward int validate_terminal Py_PROTO((node *terminal,
858					      int type, char *string));
859
860#define	validate_ampersand(ch)	validate_terminal(ch,	   AMPER, "&")
861#define	validate_circumflex(ch)	validate_terminal(ch, CIRCUMFLEX, "^")
862#define validate_colon(ch)	validate_terminal(ch,	   COLON, ":")
863#define validate_comma(ch)	validate_terminal(ch,	   COMMA, ",")
864#define validate_dedent(ch)	validate_terminal(ch,	  DEDENT, "")
865#define	validate_equal(ch)	validate_terminal(ch,	   EQUAL, "=")
866#define validate_indent(ch)	validate_terminal(ch,	  INDENT, 0)
867#define validate_lparen(ch)	validate_terminal(ch,	    LPAR, "(")
868#define	validate_newline(ch)	validate_terminal(ch,	 NEWLINE, 0)
869#define validate_rparen(ch)	validate_terminal(ch,	    RPAR, ")")
870#define validate_semi(ch)	validate_terminal(ch,	    SEMI, ";")
871#define	validate_star(ch)	validate_terminal(ch,	    STAR, "*")
872#define	validate_vbar(ch)	validate_terminal(ch,	    VBAR, "|")
873#define validate_doublestar(ch)	validate_terminal(ch, DOUBLESTAR, "**")
874#define validate_dot(ch)	validate_terminal(ch,	     DOT, ".")
875#define	validate_name(ch, str)	validate_terminal(ch,	    NAME, str)
876
877VALIDATER(node);		VALIDATER(small_stmt);
878VALIDATER(class);		VALIDATER(node);
879VALIDATER(parameters);		VALIDATER(suite);
880VALIDATER(testlist);		VALIDATER(varargslist);
881VALIDATER(fpdef);		VALIDATER(fplist);
882VALIDATER(stmt);		VALIDATER(simple_stmt);
883VALIDATER(expr_stmt);		VALIDATER(power);
884VALIDATER(print_stmt);		VALIDATER(del_stmt);
885VALIDATER(return_stmt);
886VALIDATER(raise_stmt);		VALIDATER(import_stmt);
887VALIDATER(global_stmt);
888VALIDATER(assert_stmt);
889VALIDATER(exec_stmt);		VALIDATER(compound_stmt);
890VALIDATER(while);		VALIDATER(for);
891VALIDATER(try);			VALIDATER(except_clause);
892VALIDATER(test);		VALIDATER(and_test);
893VALIDATER(not_test);		VALIDATER(comparison);
894VALIDATER(comp_op);		VALIDATER(expr);
895VALIDATER(xor_expr);		VALIDATER(and_expr);
896VALIDATER(shift_expr);		VALIDATER(arith_expr);
897VALIDATER(term);		VALIDATER(factor);
898VALIDATER(atom);		VALIDATER(lambdef);
899VALIDATER(trailer);		VALIDATER(subscript);
900VALIDATER(subscriptlist);	VALIDATER(sliceop);
901VALIDATER(exprlist);		VALIDATER(dictmaker);
902VALIDATER(arglist);		VALIDATER(argument);
903
904
905#define	is_even(n)	(((n) & 1) == 0)
906#define	is_odd(n)	(((n) & 1) == 1)
907
908
909static int
910validate_ntype(n, t)
911     node *n;
912     int t;
913{
914    int res = (TYPE(n) == t);
915
916    if (!res) {
917	char buffer[128];
918	sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
919	err_string(buffer);
920    }
921    return (res);
922
923}   /* validate_ntype() */
924
925
926static int
927validate_numnodes(n, num, name)
928     node *n;
929     int num;
930     const char *const name;
931{
932    if (NCH(n) != num) {
933	char buff[60];
934	sprintf(buff, "Illegal number of children for %s node.", name);
935	err_string(buff);
936    }
937    return (NCH(n) == num);
938
939}   /* validate_numnodes() */
940
941
942static int
943validate_terminal(terminal, type, string)
944     node *terminal;
945     int type;
946     char *string;
947{
948    int res = (validate_ntype(terminal, type)
949	       && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
950
951    if (!res && !PyErr_Occurred()) {
952	char buffer[60];
953	sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
954	err_string(buffer);
955    }
956    return (res);
957
958}   /* validate_terminal() */
959
960
961/*  X (',' X) [',']
962 */
963static int
964validate_repeating_list(tree, ntype, vfunc, name)
965    node *tree;
966    int ntype;
967    int (*vfunc)();
968    const char *const name;
969{
970    int nch = NCH(tree);
971    int res = (nch && validate_ntype(tree, ntype)
972	       && vfunc(CHILD(tree, 0)));
973
974    if (!res && !PyErr_Occurred())
975	validate_numnodes(tree, 1, name);
976    else {
977	if (is_even(nch))
978	    res = validate_comma(CHILD(tree, --nch));
979	if (res && nch > 1) {
980	    int pos = 1;
981	    for ( ; res && pos < nch; pos += 2)
982		res = (validate_comma(CHILD(tree, pos))
983		       && vfunc(CHILD(tree, pos + 1)));
984	}
985    }
986    return (res);
987
988}   /* validate_repeating_list() */
989
990
991/*  VALIDATE(class)
992 *
993 *  classdef:
994 *	'class' NAME ['(' testlist ')'] ':' suite
995 */
996static int
997validate_class(tree)
998    node *tree;
999{
1000    int nch = NCH(tree);
1001    int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
1002
1003    if (res) {
1004	res = (validate_name(CHILD(tree, 0), "class")
1005	       && validate_ntype(CHILD(tree, 1), NAME)
1006	       && validate_colon(CHILD(tree, nch - 2))
1007	       && validate_suite(CHILD(tree, nch - 1)));
1008    }
1009    else
1010	validate_numnodes(tree, 4, "class");
1011    if (res && (nch == 7)) {
1012	res = (validate_lparen(CHILD(tree, 2))
1013	       && validate_testlist(CHILD(tree, 3))
1014	       && validate_rparen(CHILD(tree, 4)));
1015    }
1016    return (res);
1017
1018}   /* validate_class() */
1019
1020
1021/*  if_stmt:
1022 *	'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1023 */
1024static int
1025validate_if(tree)
1026    node *tree;
1027{
1028    int nch = NCH(tree);
1029    int res = (validate_ntype(tree, if_stmt)
1030	       && (nch >= 4)
1031	       && validate_name(CHILD(tree, 0), "if")
1032	       && validate_test(CHILD(tree, 1))
1033	       && validate_colon(CHILD(tree, 2))
1034	       && validate_suite(CHILD(tree, 3)));
1035
1036    if (res && ((nch % 4) == 3)) {
1037	/*  ... 'else' ':' suite  */
1038	res = (validate_name(CHILD(tree, nch - 3), "else")
1039	       && validate_colon(CHILD(tree, nch - 2))
1040	       && validate_suite(CHILD(tree, nch - 1)));
1041	nch -= 3;
1042    }
1043    else if (!res && !PyErr_Occurred())
1044	validate_numnodes(tree, 4, "if");
1045    if ((nch % 4) != 0)
1046	/* Will catch the case for nch < 4 */
1047	res = validate_numnodes(tree, 0, "if");
1048    else if (res && (nch > 4)) {
1049	/*  ... ('elif' test ':' suite)+ ...  */
1050	int j = 4;
1051	while ((j < nch) && res) {
1052	    res = (validate_name(CHILD(tree, j), "elif")
1053		   && validate_colon(CHILD(tree, j + 2))
1054		   && validate_test(CHILD(tree, j + 1))
1055		   && validate_suite(CHILD(tree, j + 3)));
1056	    j += 4;
1057	}
1058    }
1059    return (res);
1060
1061}   /* validate_if() */
1062
1063
1064/*  parameters:
1065 *	'(' [varargslist] ')'
1066 *
1067 */
1068static int
1069validate_parameters(tree)
1070    node *tree;
1071{
1072    int nch = NCH(tree);
1073    int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
1074
1075    if (res) {
1076	res = (validate_lparen(CHILD(tree, 0))
1077	       && validate_rparen(CHILD(tree, nch - 1)));
1078	if (res && (nch == 3))
1079	    res = validate_varargslist(CHILD(tree, 1));
1080    }
1081    else
1082	validate_numnodes(tree, 2, "parameters");
1083
1084    return (res);
1085
1086}   /* validate_parameters() */
1087
1088
1089/*  VALIDATE(suite)
1090 *
1091 *  suite:
1092 *	simple_stmt
1093 *    | NEWLINE INDENT stmt+ DEDENT
1094 */
1095static int
1096validate_suite(tree)
1097    node *tree;
1098{
1099    int nch = NCH(tree);
1100    int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
1101
1102    if (res && (nch == 1))
1103	res = validate_simple_stmt(CHILD(tree, 0));
1104    else if (res) {
1105	/*  NEWLINE INDENT stmt+ DEDENT  */
1106	res = (validate_newline(CHILD(tree, 0))
1107	       && validate_indent(CHILD(tree, 1))
1108	       && validate_stmt(CHILD(tree, 2))
1109	       && validate_dedent(CHILD(tree, nch - 1)));
1110
1111	if (res && (nch > 4)) {
1112	    int i = 3;
1113	    --nch;			/* forget the DEDENT	 */
1114	    for ( ; res && (i < nch); ++i)
1115		res = validate_stmt(CHILD(tree, i));
1116	}
1117	else if (nch < 4)
1118	    validate_numnodes(tree, 4, "suite");
1119    }
1120    return (res);
1121
1122}   /* validate_suite() */
1123
1124
1125static int
1126validate_testlist(tree)
1127    node *tree;
1128{
1129    return (validate_repeating_list(tree, testlist,
1130				    validate_test, "testlist"));
1131
1132}   /* validate_testlist() */
1133
1134
1135/*  VALIDATE(varargslist)
1136 *
1137 *  varargslist:
1138 *	(fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1139 *    | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1140 *
1141 *      (fpdef ['=' test] ',')*
1142 *           ('*' NAME [',' ('**'|'*' '*') NAME]
1143 *         | ('**'|'*' '*') NAME)
1144 *    | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1145 *
1146 */
1147static int
1148validate_varargslist(tree)
1149    node *tree;
1150{
1151    int nch = NCH(tree);
1152    int res = validate_ntype(tree, varargslist) && (nch != 0);
1153
1154    if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1155	/*  (fpdef ['=' test] ',')*
1156	 *  ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1157	 */
1158	int pos = 0;
1159	int remaining = nch;
1160
1161	while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1162	    res = validate_fpdef(CHILD(tree, pos));
1163	    if (res) {
1164		if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1165		    res = validate_test(CHILD(tree, pos + 2));
1166		    pos += 2;
1167		}
1168		res = res && validate_comma(CHILD(tree, pos + 1));
1169		pos += 2;
1170	    }
1171	}
1172	if (res) {
1173	    remaining = nch - pos;
1174	    res = ((remaining == 2) || (remaining == 3)
1175		   || (remaining == 5) || (remaining == 6));
1176	    if (!res)
1177		validate_numnodes(tree, 2, "varargslist");
1178	    else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1179		return ((remaining == 2)
1180			&& validate_ntype(CHILD(tree, pos+1), NAME));
1181	    else {
1182		res = validate_star(CHILD(tree, pos++));
1183		--remaining;
1184	    }
1185	}
1186	if (res) {
1187	    if (remaining == 2) {
1188		res = (validate_star(CHILD(tree, pos))
1189		       && validate_ntype(CHILD(tree, pos + 1), NAME));
1190	    }
1191	    else {
1192		res = validate_ntype(CHILD(tree, pos++), NAME);
1193		if (res && (remaining >= 4)) {
1194		    res = validate_comma(CHILD(tree, pos));
1195		    if (--remaining == 3)
1196			res = (validate_star(CHILD(tree, pos + 1))
1197			       && validate_star(CHILD(tree, pos + 2)));
1198		    else
1199			validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1200		}
1201	    }
1202	}
1203	if (!res && !PyErr_Occurred())
1204	    err_string("Incorrect validation of variable arguments list.");
1205    }
1206    else if (res) {
1207	/*  fpdef ['=' test] (',' fpdef ['=' test])* [',']  */
1208	if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1209	    --nch;
1210
1211	/*  fpdef ['=' test] (',' fpdef ['=' test])*  */
1212	res = (is_odd(nch)
1213	       && validate_fpdef(CHILD(tree, 0)));
1214
1215	if (res && (nch > 1)) {
1216	    int pos = 1;
1217	    if (TYPE(CHILD(tree, 1)) == EQUAL) {
1218		res = validate_test(CHILD(tree, 2));
1219		pos += 2;
1220	    }
1221	    /*  ... (',' fpdef ['=' test])*  */
1222	    for ( ; res && (pos < nch); pos += 2) {
1223		/* ',' fpdef */
1224		res = (validate_comma(CHILD(tree, pos))
1225		       && validate_fpdef(CHILD(tree, pos + 1)));
1226		if (res
1227		    && ((nch - pos) > 2)
1228		    && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1229		    /* ['=' test] */
1230		    res = validate_test(CHILD(tree, pos + 3));
1231		    pos += 2;
1232		}
1233	    }
1234	}
1235    }
1236    else
1237	err_string("Improperly formed argument list.");
1238
1239    return (res);
1240
1241}   /* validate_varargslist() */
1242
1243
1244/*  VALIDATE(fpdef)
1245 *
1246 *  fpdef:
1247 *	NAME
1248 *    | '(' fplist ')'
1249 */
1250static int
1251validate_fpdef(tree)
1252    node *tree;
1253{
1254    int nch = NCH(tree);
1255    int res = validate_ntype(tree, fpdef);
1256
1257    if (res) {
1258	if (nch == 1)
1259	    res = validate_ntype(CHILD(tree, 0), NAME);
1260	else if (nch == 3)
1261	    res = (validate_lparen(CHILD(tree, 0))
1262		   && validate_fplist(CHILD(tree, 1))
1263		   && validate_rparen(CHILD(tree, 2)));
1264	else
1265	    validate_numnodes(tree, 1, "fpdef");
1266    }
1267    return (res);
1268
1269} /* validate_fpdef() */
1270
1271
1272static int
1273validate_fplist(tree)
1274    node *tree;
1275{
1276    return (validate_repeating_list(tree, fplist,
1277				    validate_fpdef, "fplist"));
1278
1279}   /* validate_fplist() */
1280
1281
1282/*  simple_stmt | compound_stmt
1283 *
1284 */
1285static int
1286validate_stmt(tree)
1287    node *tree;
1288{
1289    int res = (validate_ntype(tree, stmt)
1290	       && validate_numnodes(tree, 1, "stmt"));
1291
1292    if (res) {
1293	tree = CHILD(tree, 0);
1294
1295	if (TYPE(tree) == simple_stmt)
1296	    res = validate_simple_stmt(tree);
1297	else
1298	    res = validate_compound_stmt(tree);
1299    }
1300    return (res);
1301
1302}   /* validate_stmt() */
1303
1304
1305/*  small_stmt (';' small_stmt)* [';'] NEWLINE
1306 *
1307 */
1308static int
1309validate_simple_stmt(tree)
1310    node *tree;
1311{
1312    int nch = NCH(tree);
1313    int res = (validate_ntype(tree, simple_stmt)
1314	       && (nch >= 2)
1315	       && validate_small_stmt(CHILD(tree, 0))
1316	       && validate_newline(CHILD(tree, nch - 1)));
1317
1318    if (nch < 2)
1319	res = validate_numnodes(tree, 2, "simple_stmt");
1320    --nch;				/* forget the NEWLINE	 */
1321    if (res && is_even(nch))
1322	res = validate_semi(CHILD(tree, --nch));
1323    if (res && (nch > 2)) {
1324	int i;
1325
1326	for (i = 1; res && (i < nch); i += 2)
1327	    res = (validate_semi(CHILD(tree, i))
1328		   && validate_small_stmt(CHILD(tree, i + 1)));
1329    }
1330    return (res);
1331
1332}   /* validate_simple_stmt() */
1333
1334
1335static int
1336validate_small_stmt(tree)
1337    node *tree;
1338{
1339    int nch = NCH(tree);
1340    int	res = (validate_numnodes(tree, 1, "small_stmt")
1341	       && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1342		   || (TYPE(CHILD(tree, 0)) == print_stmt)
1343		   || (TYPE(CHILD(tree, 0)) == del_stmt)
1344		   || (TYPE(CHILD(tree, 0)) == pass_stmt)
1345		   || (TYPE(CHILD(tree, 0)) == flow_stmt)
1346		   || (TYPE(CHILD(tree, 0)) == import_stmt)
1347		   || (TYPE(CHILD(tree, 0)) == global_stmt)
1348		   || (TYPE(CHILD(tree, 0)) == assert_stmt)
1349		   || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1350
1351    if (res)
1352	res = validate_node(CHILD(tree, 0));
1353    else if (nch == 1) {
1354	char buffer[60];
1355	sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1356		TYPE(CHILD(tree, 0)));
1357	err_string(buffer);
1358    }
1359    return (res);
1360
1361}   /* validate_small_stmt */
1362
1363
1364/*  compound_stmt:
1365 *	if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1366 */
1367static int
1368validate_compound_stmt(tree)
1369    node *tree;
1370{
1371    int res = (validate_ntype(tree, compound_stmt)
1372	       && validate_numnodes(tree, 1, "compound_stmt"));
1373
1374    if (!res)
1375	return (0);
1376
1377    tree = CHILD(tree, 0);
1378    res = ((TYPE(tree) == if_stmt)
1379	   || (TYPE(tree) == while_stmt)
1380	   || (TYPE(tree) == for_stmt)
1381	   || (TYPE(tree) == try_stmt)
1382	   || (TYPE(tree) == funcdef)
1383	   || (TYPE(tree) == classdef));
1384    if (res)
1385	res = validate_node(tree);
1386    else {
1387	char buffer[60];
1388	sprintf(buffer, "Illegal compound statement type: %d.", TYPE(tree));
1389	err_string(buffer);
1390    }
1391    return (res);
1392
1393}   /* validate_compound_stmt() */
1394
1395
1396static int
1397validate_expr_stmt(tree)
1398    node *tree;
1399{
1400    int j;
1401    int nch = NCH(tree);
1402    int res = (validate_ntype(tree, expr_stmt)
1403	       && is_odd(nch)
1404	       && validate_testlist(CHILD(tree, 0)));
1405
1406    for (j = 1; res && (j < nch); j += 2)
1407	res = (validate_equal(CHILD(tree, j))
1408	       && validate_testlist(CHILD(tree, j + 1)));
1409
1410    return (res);
1411
1412}   /* validate_expr_stmt() */
1413
1414
1415/*  print_stmt:
1416 *
1417 *	'print' (test ',')* [test]
1418 *
1419 */
1420static int
1421validate_print_stmt(tree)
1422    node *tree;
1423{
1424    int j;
1425    int nch = NCH(tree);
1426    int res = (validate_ntype(tree, print_stmt)
1427	       && (nch != 0)
1428	       && validate_name(CHILD(tree, 0), "print"));
1429
1430    if (res && is_even(nch)) {
1431	res = validate_test(CHILD(tree, nch - 1));
1432	--nch;
1433    }
1434    else if (!res && !PyErr_Occurred())
1435	validate_numnodes(tree, 1, "print_stmt");
1436    for (j = 1; res && (j < nch); j += 2)
1437	res = (validate_test(CHILD(tree, j))
1438	       && validate_ntype(CHILD(tree, j + 1), COMMA));
1439
1440    return (res);
1441
1442}   /* validate_print_stmt() */
1443
1444
1445static int
1446validate_del_stmt(tree)
1447    node *tree;
1448{
1449    return (validate_numnodes(tree, 2, "del_stmt")
1450	    && validate_name(CHILD(tree, 0), "del")
1451	    && validate_exprlist(CHILD(tree, 1)));
1452
1453}   /* validate_del_stmt() */
1454
1455
1456static int
1457validate_return_stmt(tree)
1458    node *tree;
1459{
1460    int nch = NCH(tree);
1461    int res = (validate_ntype(tree, return_stmt)
1462	       && ((nch == 1) || (nch == 2))
1463	       && validate_name(CHILD(tree, 0), "return"));
1464
1465    if (res && (nch == 2))
1466	res = validate_testlist(CHILD(tree, 1));
1467
1468    return (res);
1469
1470}   /* validate_return_stmt() */
1471
1472
1473static int
1474validate_raise_stmt(tree)
1475    node *tree;
1476{
1477    int nch = NCH(tree);
1478    int res = (validate_ntype(tree, raise_stmt)
1479	       && ((nch == 2) || (nch == 4) || (nch == 6)));
1480
1481    if (res) {
1482	res = (validate_name(CHILD(tree, 0), "raise")
1483	       && validate_test(CHILD(tree, 1)));
1484	if (res && nch > 2) {
1485	    res = (validate_comma(CHILD(tree, 2))
1486		   && validate_test(CHILD(tree, 3)));
1487	    if (res && (nch > 4))
1488		res = (validate_comma(CHILD(tree, 4))
1489		       && validate_test(CHILD(tree, 5)));
1490	}
1491    }
1492    else
1493	validate_numnodes(tree, 2, "raise");
1494    if (res && (nch == 4))
1495	res = (validate_comma(CHILD(tree, 2))
1496	       && validate_test(CHILD(tree, 3)));
1497
1498    return (res);
1499
1500}   /* validate_raise_stmt() */
1501
1502
1503/*  import_stmt:
1504 *
1505 *    'import' dotted_name (',' dotted_name)*
1506 *  | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1507 */
1508static int
1509validate_import_stmt(tree)
1510    node *tree;
1511{
1512    int nch = NCH(tree);
1513    int res = (validate_ntype(tree, import_stmt)
1514	       && (nch >= 2) && is_even(nch)
1515	       && validate_ntype(CHILD(tree, 0), NAME)
1516	       && validate_ntype(CHILD(tree, 1), dotted_name));
1517
1518    if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
1519	int j;
1520
1521	for (j = 2; res && (j < nch); j += 2)
1522	    res = (validate_comma(CHILD(tree, j))
1523		   && validate_ntype(CHILD(tree, j + 1), dotted_name));
1524    }
1525    else if (res && validate_name(CHILD(tree, 0), "from")) {
1526	res = ((nch >= 4) && is_even(nch)
1527	       && validate_name(CHILD(tree, 2), "import"));
1528	if (nch == 4) {
1529	    res = ((TYPE(CHILD(tree, 3)) == NAME)
1530		   || (TYPE(CHILD(tree, 3)) == STAR));
1531	    if (!res)
1532		err_string("Illegal import statement.");
1533	}
1534	else {
1535	    /*  'from' NAME 'import' NAME (',' NAME)+  */
1536	    int j;
1537	    res = validate_ntype(CHILD(tree, 3), NAME);
1538	    for (j = 4; res && (j < nch); j += 2)
1539		res = (validate_comma(CHILD(tree, j))
1540		       && validate_ntype(CHILD(tree, j + 1), NAME));
1541	}
1542    }
1543    else
1544	res = 0;
1545
1546    return (res);
1547
1548}   /* validate_import_stmt() */
1549
1550
1551static int
1552validate_global_stmt(tree)
1553    node *tree;
1554{
1555    int j;
1556    int nch = NCH(tree);
1557    int res = (validate_ntype(tree, global_stmt)
1558	       && is_even(nch) && (nch >= 2));
1559
1560    if (res)
1561	res = (validate_name(CHILD(tree, 0), "global")
1562	       && validate_ntype(CHILD(tree, 1), NAME));
1563    for (j = 2; res && (j < nch); j += 2)
1564	res = (validate_comma(CHILD(tree, j))
1565	       && validate_ntype(CHILD(tree, j + 1), NAME));
1566
1567    return (res);
1568
1569}   /* validate_global_stmt() */
1570
1571
1572/*  exec_stmt:
1573 *
1574 *  'exec' expr ['in' test [',' test]]
1575 */
1576static int
1577validate_exec_stmt(tree)
1578    node *tree;
1579{
1580    int nch = NCH(tree);
1581    int res = (validate_ntype(tree, exec_stmt)
1582	       && ((nch == 2) || (nch == 4) || (nch == 6))
1583	       && validate_name(CHILD(tree, 0), "exec")
1584	       && validate_expr(CHILD(tree, 1)));
1585
1586    if (!res && !PyErr_Occurred())
1587	err_string("Illegal exec statement.");
1588    if (res && (nch > 2))
1589	res = (validate_name(CHILD(tree, 2), "in")
1590	       && validate_test(CHILD(tree, 3)));
1591    if (res && (nch == 6))
1592	res = (validate_comma(CHILD(tree, 4))
1593	       && validate_test(CHILD(tree, 5)));
1594
1595    return (res);
1596
1597}   /* validate_exec_stmt() */
1598
1599
1600/*  assert_stmt:
1601 *
1602 *  'assert' test [',' test]
1603 */
1604static int
1605validate_assert_stmt(tree)
1606    node *tree;
1607{
1608    int nch = NCH(tree);
1609    int res = (validate_ntype(tree, assert_stmt)
1610	       && ((nch == 2) || (nch == 4))
1611	       && (validate_name(CHILD(tree, 0), "__assert__") ||
1612		   validate_name(CHILD(tree, 0), "assert"))
1613	       && validate_test(CHILD(tree, 1)));
1614
1615    if (!res && !PyErr_Occurred())
1616	err_string("Illegal assert statement.");
1617    if (res && (nch > 2))
1618	res = (validate_comma(CHILD(tree, 2))
1619	       && validate_test(CHILD(tree, 3)));
1620
1621    return (res);
1622
1623}   /* validate_assert_stmt() */
1624
1625
1626static int
1627validate_while(tree)
1628    node *tree;
1629{
1630    int nch = NCH(tree);
1631    int res = (validate_ntype(tree, while_stmt)
1632	       && ((nch == 4) || (nch == 7))
1633	       && validate_name(CHILD(tree, 0), "while")
1634	       && validate_test(CHILD(tree, 1))
1635	       && validate_colon(CHILD(tree, 2))
1636	       && validate_suite(CHILD(tree, 3)));
1637
1638    if (res && (nch == 7))
1639	res = (validate_name(CHILD(tree, 4), "else")
1640	       && validate_colon(CHILD(tree, 5))
1641	       && validate_suite(CHILD(tree, 6)));
1642
1643    return (res);
1644
1645}   /* validate_while() */
1646
1647
1648static int
1649validate_for(tree)
1650    node *tree;
1651{
1652    int nch = NCH(tree);
1653    int res = (validate_ntype(tree, for_stmt)
1654	       && ((nch == 6) || (nch == 9))
1655	       && validate_name(CHILD(tree, 0), "for")
1656	       && validate_exprlist(CHILD(tree, 1))
1657	       && validate_name(CHILD(tree, 2), "in")
1658	       && validate_testlist(CHILD(tree, 3))
1659	       && validate_colon(CHILD(tree, 4))
1660	       && validate_suite(CHILD(tree, 5)));
1661
1662    if (res && (nch == 9))
1663	res = (validate_name(CHILD(tree, 6), "else")
1664	       && validate_colon(CHILD(tree, 7))
1665	       && validate_suite(CHILD(tree, 8)));
1666
1667    return (res);
1668
1669}   /* validate_for() */
1670
1671
1672/*  try_stmt:
1673 *	'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1674 *    | 'try' ':' suite 'finally' ':' suite
1675 *
1676 */
1677static int
1678validate_try(tree)
1679    node *tree;
1680{
1681    int nch = NCH(tree);
1682    int pos = 3;
1683    int res = (validate_ntype(tree, try_stmt)
1684	       && (nch >= 6) && ((nch % 3) == 0));
1685
1686    if (res)
1687	res = (validate_name(CHILD(tree, 0), "try")
1688	       && validate_colon(CHILD(tree, 1))
1689	       && validate_suite(CHILD(tree, 2))
1690	       && validate_colon(CHILD(tree, nch - 2))
1691	       && validate_suite(CHILD(tree, nch - 1)));
1692    else {
1693	const char* name = "execpt";
1694	char buffer[60];
1695	if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1696	    name = STR(CHILD(tree, nch - 3));
1697	sprintf(buffer, "Illegal number of children for try/%s node.", name);
1698	err_string(buffer);
1699    }
1700    /*	Skip past except_clause sections:  */
1701    while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1702	res = (validate_except_clause(CHILD(tree, pos))
1703	       && validate_colon(CHILD(tree, pos + 1))
1704	       && validate_suite(CHILD(tree, pos + 2)));
1705	pos += 3;
1706    }
1707    if (res && (pos < nch)) {
1708	res = validate_ntype(CHILD(tree, pos), NAME);
1709	if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1710	    res = (validate_numnodes(tree, 6, "try/finally")
1711		   && validate_colon(CHILD(tree, 4))
1712		   && validate_suite(CHILD(tree, 5)));
1713	else if (res)
1714	    if (nch == (pos + 3)) {
1715		res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1716		       || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1717		if (!res)
1718		    err_string("Illegal trailing triple in try statement.");
1719	    }
1720	    else if (nch == (pos + 6))
1721		res = (validate_name(CHILD(tree, pos), "except")
1722		       && validate_colon(CHILD(tree, pos + 1))
1723		       && validate_suite(CHILD(tree, pos + 2))
1724		       && validate_name(CHILD(tree, pos + 3), "else"));
1725	    else
1726		res = validate_numnodes(tree, pos + 3, "try/except");
1727    }
1728    return (res);
1729
1730}   /* validate_try() */
1731
1732
1733static int
1734validate_except_clause(tree)
1735    node *tree;
1736{
1737    int nch = NCH(tree);
1738    int res = (validate_ntype(tree, except_clause)
1739	       && ((nch == 1) || (nch == 2) || (nch == 4))
1740	       && validate_name(CHILD(tree, 0), "except"));
1741
1742    if (res && (nch > 1))
1743	res = validate_test(CHILD(tree, 1));
1744    if (res && (nch == 4))
1745	res = (validate_comma(CHILD(tree, 2))
1746	       && validate_test(CHILD(tree, 3)));
1747
1748    return (res);
1749
1750}   /* validate_except_clause() */
1751
1752
1753static int
1754validate_test(tree)
1755    node *tree;
1756{
1757    int nch = NCH(tree);
1758    int res = validate_ntype(tree, test) && is_odd(nch);
1759
1760    if (res && (TYPE(CHILD(tree, 0)) == lambdef))
1761	res = ((nch == 1)
1762	       && validate_lambdef(CHILD(tree, 0)));
1763    else if (res) {
1764	int pos;
1765	res = validate_and_test(CHILD(tree, 0));
1766	for (pos = 1; res && (pos < nch); pos += 2)
1767	    res = (validate_name(CHILD(tree, pos), "or")
1768		   && validate_and_test(CHILD(tree, pos + 1)));
1769    }
1770    return (res);
1771
1772}   /* validate_test() */
1773
1774
1775static int
1776validate_and_test(tree)
1777    node *tree;
1778{
1779    int pos;
1780    int nch = NCH(tree);
1781    int res = (validate_ntype(tree, and_test)
1782	       && is_odd(nch)
1783	       && validate_not_test(CHILD(tree, 0)));
1784
1785    for (pos = 1; res && (pos < nch); pos += 2)
1786	res = (validate_name(CHILD(tree, pos), "and")
1787	       && validate_not_test(CHILD(tree, 0)));
1788
1789    return (res);
1790
1791}   /* validate_and_test() */
1792
1793
1794static int
1795validate_not_test(tree)
1796    node *tree;
1797{
1798    int nch = NCH(tree);
1799    int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
1800
1801    if (res) {
1802	if (nch == 2)
1803	    res = (validate_name(CHILD(tree, 0), "not")
1804		   && validate_not_test(CHILD(tree, 1)));
1805	else if (nch == 1)
1806	    res = validate_comparison(CHILD(tree, 0));
1807    }
1808    return (res);
1809
1810}   /* validate_not_test() */
1811
1812
1813static int
1814validate_comparison(tree)
1815    node *tree;
1816{
1817    int pos;
1818    int nch = NCH(tree);
1819    int res = (validate_ntype(tree, comparison)
1820	       && is_odd(nch)
1821	       && validate_expr(CHILD(tree, 0)));
1822
1823    for (pos = 1; res && (pos < nch); pos += 2)
1824	res = (validate_comp_op(CHILD(tree, pos))
1825	       && validate_expr(CHILD(tree, pos + 1)));
1826
1827    return (res);
1828
1829}   /* validate_comparison() */
1830
1831
1832static int
1833validate_comp_op(tree)
1834    node *tree;
1835{
1836    int res = 0;
1837    int nch = NCH(tree);
1838
1839    if (!validate_ntype(tree, comp_op))
1840	return (0);
1841    if (nch == 1) {
1842	/*
1843	 *  Only child will be a terminal with a well-defined symbolic name
1844	 *  or a NAME with a string of either 'is' or 'in'
1845	 */
1846	tree = CHILD(tree, 0);
1847	switch (TYPE(tree)) {
1848	    case LESS:
1849	    case GREATER:
1850	    case EQEQUAL:
1851	    case EQUAL:
1852	    case LESSEQUAL:
1853	    case GREATEREQUAL:
1854	    case NOTEQUAL:
1855	      res = 1;
1856	      break;
1857	    case NAME:
1858	      res = ((strcmp(STR(tree), "in") == 0)
1859		     || (strcmp(STR(tree), "is") == 0));
1860	      if (!res) {
1861		  char buff[128];
1862		  sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1863		  err_string(buff);
1864	      }
1865	      break;
1866	  default:
1867	      err_string("Illegal comparison operator type.");
1868	      break;
1869	}
1870    }
1871    else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
1872	res = (validate_ntype(CHILD(tree, 0), NAME)
1873	       && validate_ntype(CHILD(tree, 1), NAME)
1874	       && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1875		    && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1876		   || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1877		       && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
1878	if (!res && !PyErr_Occurred())
1879	    err_string("Unknown comparison operator.");
1880    }
1881    return (res);
1882
1883}   /* validate_comp_op() */
1884
1885
1886static int
1887validate_expr(tree)
1888    node *tree;
1889{
1890    int j;
1891    int nch = NCH(tree);
1892    int res = (validate_ntype(tree, expr)
1893	       && is_odd(nch)
1894	       && validate_xor_expr(CHILD(tree, 0)));
1895
1896    for (j = 2; res && (j < nch); j += 2)
1897	res = (validate_xor_expr(CHILD(tree, j))
1898	       && validate_vbar(CHILD(tree, j - 1)));
1899
1900    return (res);
1901
1902}   /* validate_expr() */
1903
1904
1905static int
1906validate_xor_expr(tree)
1907    node *tree;
1908{
1909    int j;
1910    int nch = NCH(tree);
1911    int res = (validate_ntype(tree, xor_expr)
1912	       && is_odd(nch)
1913	       && validate_and_expr(CHILD(tree, 0)));
1914
1915    for (j = 2; res && (j < nch); j += 2)
1916	res = (validate_circumflex(CHILD(tree, j - 1))
1917	       && validate_and_expr(CHILD(tree, j)));
1918
1919    return (res);
1920
1921}   /* validate_xor_expr() */
1922
1923
1924static int
1925validate_and_expr(tree)
1926    node *tree;
1927{
1928    int pos;
1929    int nch = NCH(tree);
1930    int res = (validate_ntype(tree, and_expr)
1931	       && is_odd(nch)
1932	       && validate_shift_expr(CHILD(tree, 0)));
1933
1934    for (pos = 1; res && (pos < nch); pos += 2)
1935	res = (validate_ampersand(CHILD(tree, pos))
1936	       && validate_shift_expr(CHILD(tree, pos + 1)));
1937
1938    return (res);
1939
1940}   /* validate_and_expr() */
1941
1942
1943static int
1944validate_chain_two_ops(tree, termvalid, op1, op2)
1945     node *tree;
1946     int (*termvalid)();
1947     int op1;
1948     int op2;
1949 {
1950    int pos = 1;
1951    int nch = NCH(tree);
1952    int res = (is_odd(nch)
1953	       && (*termvalid)(CHILD(tree, 0)));
1954
1955    for ( ; res && (pos < nch); pos += 2) {
1956	if (TYPE(CHILD(tree, pos)) != op1)
1957	    res = validate_ntype(CHILD(tree, pos), op2);
1958	if (res)
1959	    res = (*termvalid)(CHILD(tree, pos + 1));
1960    }
1961    return (res);
1962
1963}   /* validate_chain_two_ops() */
1964
1965
1966static int
1967validate_shift_expr(tree)
1968    node *tree;
1969{
1970    return (validate_ntype(tree, shift_expr)
1971	    && validate_chain_two_ops(tree, validate_arith_expr,
1972				      LEFTSHIFT, RIGHTSHIFT));
1973
1974}   /* validate_shift_expr() */
1975
1976
1977static int
1978validate_arith_expr(tree)
1979    node *tree;
1980{
1981    return (validate_ntype(tree, arith_expr)
1982	    && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
1983
1984}   /* validate_arith_expr() */
1985
1986
1987static int
1988validate_term(tree)
1989    node *tree;
1990{
1991    int pos = 1;
1992    int nch = NCH(tree);
1993    int res = (validate_ntype(tree, term)
1994	       && is_odd(nch)
1995	       && validate_factor(CHILD(tree, 0)));
1996
1997    for ( ; res && (pos < nch); pos += 2)
1998	res = (((TYPE(CHILD(tree, pos)) == STAR)
1999	       || (TYPE(CHILD(tree, pos)) == SLASH)
2000	       || (TYPE(CHILD(tree, pos)) == PERCENT))
2001	       && validate_factor(CHILD(tree, pos + 1)));
2002
2003    return (res);
2004
2005}   /* validate_term() */
2006
2007
2008/*  factor:
2009 *
2010 *  factor: ('+'|'-'|'~') factor | power
2011 */
2012static int
2013validate_factor(tree)
2014    node *tree;
2015{
2016    int nch = NCH(tree);
2017    int res = (validate_ntype(tree, factor)
2018	       && (((nch == 2)
2019		    && ((TYPE(CHILD(tree, 0)) == PLUS)
2020		        || (TYPE(CHILD(tree, 0)) == MINUS)
2021		        || (TYPE(CHILD(tree, 0)) == TILDE))
2022		    && validate_factor(CHILD(tree, 1)))
2023		   || ((nch == 1)
2024		       && validate_power(CHILD(tree, 0)))));
2025    return (res);
2026
2027}   /* validate_factor() */
2028
2029
2030/*  power:
2031 *
2032 *  power: atom trailer* ('**' factor)*
2033 */
2034static int
2035validate_power(tree)
2036    node *tree;
2037{
2038    int pos = 1;
2039    int nch = NCH(tree);
2040    int res = (validate_ntype(tree, power) && (nch >= 1)
2041	       && validate_atom(CHILD(tree, 0)));
2042
2043    while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2044	res = validate_trailer(CHILD(tree, pos++));
2045    if (res && (pos < nch)) {
2046	if (!is_even(nch - pos)) {
2047	    err_string("Illegal number of nodes for 'power'.");
2048	    return (0);
2049	}
2050	for ( ; res && (pos < (nch - 1)); pos += 2)
2051	    res = (validate_doublestar(CHILD(tree, pos))
2052		   && validate_factor(CHILD(tree, pos + 1)));
2053    }
2054    return (res);
2055
2056}   /* validate_power() */
2057
2058
2059static int
2060validate_atom(tree)
2061    node *tree;
2062{
2063    int pos;
2064    int nch = NCH(tree);
2065    int res = validate_ntype(tree, atom) && (nch >= 1);
2066
2067    if (res) {
2068	switch (TYPE(CHILD(tree, 0))) {
2069	  case LPAR:
2070	    res = ((nch <= 3)
2071		   && (validate_rparen(CHILD(tree, nch - 1))));
2072
2073	    if (res && (nch == 3))
2074		res = validate_testlist(CHILD(tree, 1));
2075	    break;
2076	  case LSQB:
2077	    res = ((nch <= 3)
2078		   && validate_ntype(CHILD(tree, nch - 1), RSQB));
2079
2080	    if (res && (nch == 3))
2081		res = validate_testlist(CHILD(tree, 1));
2082	    break;
2083	  case LBRACE:
2084	    res = ((nch <= 3)
2085		   && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2086
2087	    if (res && (nch == 3))
2088		res = validate_dictmaker(CHILD(tree, 1));
2089	    break;
2090	  case BACKQUOTE:
2091	    res = ((nch == 3)
2092		   && validate_testlist(CHILD(tree, 1))
2093		   && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2094	    break;
2095	  case NAME:
2096	  case NUMBER:
2097	    res = (nch == 1);
2098	    break;
2099	  case STRING:
2100	    for (pos = 1; res && (pos < nch); ++pos)
2101		res = validate_ntype(CHILD(tree, pos), STRING);
2102	    break;
2103	  default:
2104	    res = 0;
2105	    break;
2106	}
2107    }
2108    return (res);
2109
2110}   /* validate_atom() */
2111
2112
2113/*  funcdef:
2114 *	'def' NAME parameters ':' suite
2115 *
2116 */
2117static int
2118validate_funcdef(tree)
2119    node *tree;
2120{
2121    return (validate_ntype(tree, funcdef)
2122	    && validate_numnodes(tree, 5, "funcdef")
2123	    && validate_name(CHILD(tree, 0), "def")
2124	    && validate_ntype(CHILD(tree, 1), NAME)
2125	    && validate_colon(CHILD(tree, 3))
2126	    && validate_parameters(CHILD(tree, 2))
2127	    && validate_suite(CHILD(tree, 4)));
2128
2129}   /* validate_funcdef() */
2130
2131
2132static int
2133validate_lambdef(tree)
2134    node *tree;
2135{
2136    int nch = NCH(tree);
2137    int res = (validate_ntype(tree, lambdef)
2138	       && ((nch == 3) || (nch == 4))
2139	       && validate_name(CHILD(tree, 0), "lambda")
2140	       && validate_colon(CHILD(tree, nch - 2))
2141	       && validate_test(CHILD(tree, nch - 1)));
2142
2143    if (res && (nch == 4))
2144	res = validate_varargslist(CHILD(tree, 1));
2145    else if (!res && !PyErr_Occurred())
2146	validate_numnodes(tree, 3, "lambdef");
2147
2148    return (res);
2149
2150}   /* validate_lambdef() */
2151
2152
2153/*  arglist:
2154 *
2155 *  argument (',' argument)* [',']
2156 */
2157static int
2158validate_arglist(tree)
2159    node *tree;
2160{
2161    return (validate_repeating_list(tree, arglist,
2162				    validate_argument, "arglist"));
2163
2164}   /* validate_arglist() */
2165
2166
2167
2168/*  argument:
2169 *
2170 *  [test '='] test
2171 */
2172static int
2173validate_argument(tree)
2174    node *tree;
2175{
2176    int nch = NCH(tree);
2177    int res = (validate_ntype(tree, argument)
2178	       && ((nch == 1) || (nch == 3))
2179	       && validate_test(CHILD(tree, 0)));
2180
2181    if (res && (nch == 3))
2182	res = (validate_equal(CHILD(tree, 1))
2183	       && validate_test(CHILD(tree, 2)));
2184
2185    return (res);
2186
2187}   /* validate_argument() */
2188
2189
2190
2191/*  trailer:
2192 *
2193 *  '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
2194 */
2195static int
2196validate_trailer(tree)
2197    node *tree;
2198{
2199    int nch = NCH(tree);
2200    int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
2201
2202    if (res) {
2203	switch (TYPE(CHILD(tree, 0))) {
2204	  case LPAR:
2205	    res = validate_rparen(CHILD(tree, nch - 1));
2206	    if (res && (nch == 3))
2207		res = validate_arglist(CHILD(tree, 1));
2208	    break;
2209	  case LSQB:
2210	    res = (validate_numnodes(tree, 3, "trailer")
2211		   && validate_subscriptlist(CHILD(tree, 1))
2212		   && validate_ntype(CHILD(tree, 2), RSQB));
2213	    break;
2214	  case DOT:
2215	    res = (validate_numnodes(tree, 2, "trailer")
2216		   && validate_ntype(CHILD(tree, 1), NAME));
2217	    break;
2218	  default:
2219	    res = 0;
2220	    break;
2221	}
2222    }
2223    else
2224	validate_numnodes(tree, 2, "trailer");
2225
2226    return (res);
2227
2228}   /* validate_trailer() */
2229
2230
2231/*  subscriptlist:
2232 *
2233 *  subscript (',' subscript)* [',']
2234 */
2235static int
2236validate_subscriptlist(tree)
2237    node *tree;
2238{
2239    return (validate_repeating_list(tree, subscriptlist,
2240				    validate_subscript, "subscriptlist"));
2241
2242}   /* validate_subscriptlist() */
2243
2244
2245/*  subscript:
2246 *
2247 *  '.' '.' '.' | test | [test] ':' [test] [sliceop]
2248 */
2249static int
2250validate_subscript(tree)
2251    node *tree;
2252{
2253    int offset = 0;
2254    int nch = NCH(tree);
2255    int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
2256
2257    if (!res) {
2258	if (!PyErr_Occurred())
2259	    err_string("invalid number of arguments for subscript node");
2260	return (0);
2261    }
2262    if (TYPE(CHILD(tree, 0)) == DOT)
2263	/* take care of ('.' '.' '.') possibility */
2264	return (validate_numnodes(tree, 3, "subscript")
2265		&& validate_dot(CHILD(tree, 0))
2266		&& validate_dot(CHILD(tree, 1))
2267		&& validate_dot(CHILD(tree, 2)));
2268    if (nch == 1) {
2269	if (TYPE(CHILD(tree, 0)) == test)
2270	    res = validate_test(CHILD(tree, 0));
2271	else
2272	    res = validate_colon(CHILD(tree, 0));
2273	return (res);
2274    }
2275    /*	Must be [test] ':' [test] [sliceop],
2276     *	but at least one of the optional components will
2277     *	be present, but we don't know which yet.
2278     */
2279    if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2280	res = validate_test(CHILD(tree, 0));
2281	offset = 1;
2282    }
2283    if (res)
2284	res = validate_colon(CHILD(tree, offset));
2285    if (res) {
2286	int rem = nch - ++offset;
2287	if (rem) {
2288	    if (TYPE(CHILD(tree, offset)) == test) {
2289		res = validate_test(CHILD(tree, offset));
2290		++offset;
2291		--rem;
2292	    }
2293	    if (res && rem)
2294		res = validate_sliceop(CHILD(tree, offset));
2295	}
2296    }
2297    return (res);
2298
2299}   /* validate_subscript() */
2300
2301
2302static int
2303validate_sliceop(tree)
2304    node *tree;
2305{
2306    int nch = NCH(tree);
2307    int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2308	      && validate_ntype(tree, sliceop);
2309    if (!res && !PyErr_Occurred()) {
2310	validate_numnodes(tree, 1, "sliceop");
2311	res = 0;
2312    }
2313    if (res)
2314	res = validate_colon(CHILD(tree, 0));
2315    if (res && (nch == 2))
2316	res = validate_test(CHILD(tree, 1));
2317
2318    return (res);
2319
2320}   /* validate_sliceop() */
2321
2322
2323static int
2324validate_exprlist(tree)
2325    node *tree;
2326{
2327    return (validate_repeating_list(tree, exprlist,
2328				    validate_expr, "exprlist"));
2329
2330}   /* validate_exprlist() */
2331
2332
2333static int
2334validate_dictmaker(tree)
2335    node *tree;
2336{
2337    int nch = NCH(tree);
2338    int res = (validate_ntype(tree, dictmaker)
2339	       && (nch >= 3)
2340	       && validate_test(CHILD(tree, 0))
2341	       && validate_colon(CHILD(tree, 1))
2342	       && validate_test(CHILD(tree, 2)));
2343
2344    if (res && ((nch % 4) == 0))
2345	res = validate_comma(CHILD(tree, --nch));
2346    else if (res)
2347	res = ((nch % 4) == 3);
2348
2349    if (res && (nch > 3)) {
2350	int pos = 3;
2351	/*  ( ',' test ':' test )*  */
2352	while (res && (pos < nch)) {
2353	    res = (validate_comma(CHILD(tree, pos))
2354		   && validate_test(CHILD(tree, pos + 1))
2355		   && validate_colon(CHILD(tree, pos + 2))
2356		   && validate_test(CHILD(tree, pos + 3)));
2357	    pos += 4;
2358	}
2359    }
2360    return (res);
2361
2362}   /* validate_dictmaker() */
2363
2364
2365static int
2366validate_eval_input(tree)
2367    node *tree;
2368{
2369    int pos;
2370    int nch = NCH(tree);
2371    int res = (validate_ntype(tree, eval_input)
2372	       && (nch >= 2)
2373	       && validate_testlist(CHILD(tree, 0))
2374	       && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2375
2376    for (pos = 1; res && (pos < (nch - 1)); ++pos)
2377	res = validate_ntype(CHILD(tree, pos), NEWLINE);
2378
2379    return (res);
2380
2381}   /* validate_eval_input() */
2382
2383
2384static int
2385validate_node(tree)
2386    node *tree;
2387{
2388    int   nch  = 0;			/* num. children on current node  */
2389    int   res  = 1;			/* result value			  */
2390    node* next = 0;			/* node to process after this one */
2391
2392    while (res & (tree != 0)) {
2393	nch  = NCH(tree);
2394	next = 0;
2395	switch (TYPE(tree)) {
2396	    /*
2397	     *  Definition nodes.
2398	     */
2399	  case funcdef:
2400	    res = validate_funcdef(tree);
2401	    break;
2402	  case classdef:
2403	    res = validate_class(tree);
2404	    break;
2405	    /*
2406	     *  "Trivial" parse tree nodes.
2407	     *  (Why did I call these trivial?)
2408	     */
2409	  case stmt:
2410	    res = validate_stmt(tree);
2411	    break;
2412	  case small_stmt:
2413	    /*
2414	     *  expr_stmt | print_stmt  | del_stmt | pass_stmt | flow_stmt
2415	     *  | import_stmt | global_stmt | exec_stmt | assert_stmt
2416	     */
2417	    res = validate_small_stmt(tree);
2418	    break;
2419	  case flow_stmt:
2420	    res  = (validate_numnodes(tree, 1, "flow_stmt")
2421		    && ((TYPE(CHILD(tree, 0)) == break_stmt)
2422			|| (TYPE(CHILD(tree, 0)) == continue_stmt)
2423			|| (TYPE(CHILD(tree, 0)) == return_stmt)
2424			|| (TYPE(CHILD(tree, 0)) == raise_stmt)));
2425	    if (res)
2426		next = CHILD(tree, 0);
2427	    else if (nch == 1)
2428		err_string("Illegal flow_stmt type.");
2429	    break;
2430	    /*
2431	     *  Compound statements.
2432	     */
2433	  case simple_stmt:
2434	    res = validate_simple_stmt(tree);
2435	    break;
2436	  case compound_stmt:
2437	    res = validate_compound_stmt(tree);
2438	    break;
2439	    /*
2440	     *  Fundemental statements.
2441	     */
2442	  case expr_stmt:
2443	    res = validate_expr_stmt(tree);
2444	    break;
2445	  case print_stmt:
2446	    res = validate_print_stmt(tree);
2447	    break;
2448	  case del_stmt:
2449	    res = validate_del_stmt(tree);
2450	    break;
2451	  case pass_stmt:
2452	    res = (validate_numnodes(tree, 1, "pass")
2453		   && validate_name(CHILD(tree, 0), "pass"));
2454	    break;
2455	  case break_stmt:
2456	    res = (validate_numnodes(tree, 1, "break")
2457		   && validate_name(CHILD(tree, 0), "break"));
2458	    break;
2459	  case continue_stmt:
2460	    res = (validate_numnodes(tree, 1, "continue")
2461		   && validate_name(CHILD(tree, 0), "continue"));
2462	    break;
2463	  case return_stmt:
2464	    res = validate_return_stmt(tree);
2465	    break;
2466	  case raise_stmt:
2467	    res = validate_raise_stmt(tree);
2468	    break;
2469	  case import_stmt:
2470	    res = validate_import_stmt(tree);
2471	    break;
2472	  case global_stmt:
2473	    res = validate_global_stmt(tree);
2474	    break;
2475	  case exec_stmt:
2476	    res = validate_exec_stmt(tree);
2477	    break;
2478	  case assert_stmt:
2479	    res = validate_assert_stmt(tree);
2480	    break;
2481	  case if_stmt:
2482	    res = validate_if(tree);
2483	    break;
2484	  case while_stmt:
2485	    res = validate_while(tree);
2486	    break;
2487	  case for_stmt:
2488	    res = validate_for(tree);
2489	    break;
2490	  case try_stmt:
2491	    res = validate_try(tree);
2492	    break;
2493	  case suite:
2494	    res = validate_suite(tree);
2495	    break;
2496	    /*
2497	     *  Expression nodes.
2498	     */
2499	  case testlist:
2500	    res = validate_testlist(tree);
2501	    break;
2502	  case test:
2503	    res = validate_test(tree);
2504	    break;
2505	  case and_test:
2506	    res = validate_and_test(tree);
2507	    break;
2508	  case not_test:
2509	    res = validate_not_test(tree);
2510	    break;
2511	  case comparison:
2512	    res = validate_comparison(tree);
2513	    break;
2514	  case exprlist:
2515	    res = validate_exprlist(tree);
2516	    break;
2517	  case comp_op:
2518	    res = validate_comp_op(tree);
2519	    break;
2520	  case expr:
2521	    res = validate_expr(tree);
2522	    break;
2523	  case xor_expr:
2524	    res = validate_xor_expr(tree);
2525	    break;
2526	  case and_expr:
2527	    res = validate_and_expr(tree);
2528	    break;
2529	  case shift_expr:
2530	    res = validate_shift_expr(tree);
2531	    break;
2532	  case arith_expr:
2533	    res = validate_arith_expr(tree);
2534	    break;
2535	  case term:
2536	    res = validate_term(tree);
2537	    break;
2538	  case factor:
2539	    res = validate_factor(tree);
2540	    break;
2541	  case power:
2542	    res = validate_power(tree);
2543	    break;
2544	  case atom:
2545	    res = validate_atom(tree);
2546	    break;
2547
2548	  default:
2549	    /* Hopefully never reached! */
2550	    err_string("Unrecogniged node type.");
2551	    res = 0;
2552	    break;
2553	}
2554	tree = next;
2555    }
2556    return (res);
2557
2558}   /* validate_node() */
2559
2560
2561static int
2562validate_expr_tree(tree)
2563    node *tree;
2564{
2565    int res = validate_eval_input(tree);
2566
2567    if (!res && !PyErr_Occurred())
2568	err_string("Could not validate expression tuple.");
2569
2570    return (res);
2571
2572}   /* validate_expr_tree() */
2573
2574
2575/*  file_input:
2576 *	(NEWLINE | stmt)* ENDMARKER
2577 */
2578static int
2579validate_file_input(tree)
2580    node *tree;
2581{
2582    int j   = 0;
2583    int nch = NCH(tree) - 1;
2584    int res = ((nch >= 0)
2585	       && validate_ntype(CHILD(tree, nch), ENDMARKER));
2586
2587    for ( ; res && (j < nch); ++j) {
2588	if (TYPE(CHILD(tree, j)) == stmt)
2589	    res = validate_stmt(CHILD(tree, j));
2590	else
2591	    res = validate_newline(CHILD(tree, j));
2592    }
2593    /*	This stays in to prevent any internal failues from getting to the
2594     *	user.  Hopefully, this won't be needed.  If a user reports getting
2595     *	this, we have some debugging to do.
2596     */
2597    if (!res && !PyErr_Occurred())
2598	err_string("VALIDATION FAILURE: report this to the maintainer!.");
2599
2600    return (res);
2601
2602}   /* validate_file_input() */
2603
2604
2605/*  Functions exported by this module.  Most of this should probably
2606 *  be converted into an AST object with methods, but that is better
2607 *  done directly in Python, allowing subclasses to be created directly.
2608 *  We'd really have to write a wrapper around it all anyway to allow
2609 *  inheritance.
2610 */
2611static PyMethodDef parser_functions[] =  {
2612    {"ast2tuple",	parser_ast2tuple,	1,
2613	"Creates a tuple-tree representation of an AST."},
2614    {"ast2list",	parser_ast2list,	1,
2615	"Creates a list-tree representation of an AST."},
2616    {"compileast",	parser_compileast,	1,
2617	"Compiles an AST object into a code object."},
2618    {"expr",		parser_expr,		1,
2619	"Creates an AST object from an expression."},
2620    {"isexpr",		parser_isexpr,		1,
2621	"Determines if an AST object was created from an expression."},
2622    {"issuite",		parser_issuite,		1,
2623	"Determines if an AST object was created from a suite."},
2624    {"suite",		parser_suite,		1,
2625	"Creates an AST object from a suite."},
2626    {"sequence2ast",	parser_tuple2ast,	1,
2627	"Creates an AST object from a tree representation."},
2628    {"tuple2ast",	parser_tuple2ast,	1,
2629	"Creates an AST object from a tree representation."},
2630
2631    {0, 0, 0}
2632    };
2633
2634
2635void
2636initparser()
2637 {
2638    PyObject* module;
2639    PyObject* dict;
2640
2641    PyAST_Type.ob_type = &PyType_Type;
2642    module = Py_InitModule("parser", parser_functions);
2643    dict = PyModule_GetDict(module);
2644
2645    parser_error = PyString_FromString("parser.ParserError");
2646
2647    if ((parser_error == 0)
2648	|| (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2649	/*
2650	 *  This is serious.
2651	 */
2652	Py_FatalError("can't define parser.ParserError");
2653    }
2654    /*
2655     *  Nice to have, but don't cry if we fail.
2656     */
2657    Py_INCREF(&PyAST_Type);
2658    PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2659
2660    PyDict_SetItemString(dict, "__copyright__",
2661			 PyString_FromString(parser_copyright_string));
2662    PyDict_SetItemString(dict, "__doc__",
2663			 PyString_FromString(parser_doc_string));
2664    PyDict_SetItemString(dict, "__version__",
2665			 PyString_FromString(parser_version_string));
2666
2667}   /* initparser() */
2668
2669
2670/*
2671 *  end of parsermodule.c
2672 */
2673