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