History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Modules/parsermodule.c (1 of 3706 files). Show all

Unified · Split

sys/src/cmd/python/Modules/parsermodule.c+3279−0
@@ -0,0 +1,3279 @@
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+ * I've added some annotations that help with the lint code-checking
22+ * program, but they're not complete by a long shot. The real errors
23+ * that lint detects are gone, but there are still warnings with
24+ * Py_[X]DECREF() and Py_[X]INCREF() macros. The lint annotations
25+ * look like "NOTE(...)".
26+ */
27+
28+#include "Python.h" /* general Python API */
29+#include "graminit.h" /* symbols defined in the grammar */
30+#include "node.h" /* internal parser structure */
31+#include "errcode.h" /* error codes for PyNode_*() */
32+#include "token.h" /* token definitions */
33+ /* ISTERMINAL() / ISNONTERMINAL() */
34+#include "compile.h" /* PyNode_Compile() */
35+
36+#ifdef lint
37+#include <note.h>
38+#else
39+#define NOTE(x)
40+#endif
41+
42+/* String constants used to initialize module attributes.
43+ *
44+ */
45+static char parser_copyright_string[] =
46+"Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
47+University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
48+Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\
49+Centrum, Amsterdam, The Netherlands.";
50+
51+
52+PyDoc_STRVAR(parser_doc_string,
53+"This is an interface to Python's internal parser.");
54+
55+static char parser_version_string[] = "0.5";
56+
57+
58+typedef PyObject* (*SeqMaker) (Py_ssize_t length);
59+typedef int (*SeqInserter) (PyObject* sequence,
60+ Py_ssize_t index,
61+ PyObject* element);
62+
63+/* The function below is copyrighted by Stichting Mathematisch Centrum. The
64+ * original copyright statement is included below, and continues to apply
65+ * in full to the function immediately following. All other material is
66+ * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
67+ * Institute and State University. Changes were made to comply with the
68+ * new naming conventions. Added arguments to provide support for creating
69+ * lists as well as tuples, and optionally including the line numbers.
70+ */
71+
72+
73+static PyObject*
74+node2tuple(node *n, /* node to convert */
75+ SeqMaker mkseq, /* create sequence */
76+ SeqInserter addelem, /* func. to add elem. in seq. */
77+ int lineno) /* include line numbers? */
78+{
79+ if (n == NULL) {
80+ Py_INCREF(Py_None);
81+ return (Py_None);
82+ }
83+ if (ISNONTERMINAL(TYPE(n))) {
84+ int i;
85+ PyObject *v;
86+ PyObject *w;
87+
88+ v = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl));
89+ if (v == NULL)
90+ return (v);
91+ w = PyInt_FromLong(TYPE(n));
92+ if (w == NULL) {
93+ Py_DECREF(v);
94+ return ((PyObject*) NULL);
95+ }
96+ (void) addelem(v, 0, w);
97+ for (i = 0; i < NCH(n); i++) {
98+ w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
99+ if (w == NULL) {
100+ Py_DECREF(v);
101+ return ((PyObject*) NULL);
102+ }
103+ (void) addelem(v, i+1, w);
104+ }
105+
106+ if (TYPE(n) == encoding_decl)
107+ (void) addelem(v, i+1, PyString_FromString(STR(n)));
108+ return (v);
109+ }
110+ else if (ISTERMINAL(TYPE(n))) {
111+ PyObject *result = mkseq(2 + lineno);
112+ if (result != NULL) {
113+ (void) addelem(result, 0, PyInt_FromLong(TYPE(n)));
114+ (void) addelem(result, 1, PyString_FromString(STR(n)));
115+ if (lineno == 1)
116+ (void) addelem(result, 2, PyInt_FromLong(n->n_lineno));
117+ }
118+ return (result);
119+ }
120+ else {
121+ PyErr_SetString(PyExc_SystemError,
122+ "unrecognized parse tree node type");
123+ return ((PyObject*) NULL);
124+ }
125+}
126+/*
127+ * End of material copyrighted by Stichting Mathematisch Centrum.
128+ */
129+
130+
131+
132+/* There are two types of intermediate objects we're interested in:
133+ * 'eval' and 'exec' types. These constants can be used in the st_type
134+ * field of the object type to identify which any given object represents.
135+ * These should probably go in an external header to allow other extensions
136+ * to use them, but then, we really should be using C++ too. ;-)
137+ */
138+
139+#define PyST_EXPR 1
140+#define PyST_SUITE 2
141+
142+
143+/* These are the internal objects and definitions required to implement the
144+ * ST type. Most of the internal names are more reminiscent of the 'old'
145+ * naming style, but the code uses the new naming convention.
146+ */
147+
148+static PyObject*
149+parser_error = 0;
150+
151+
152+typedef struct {
153+ PyObject_HEAD /* standard object header */
154+ node* st_node; /* the node* returned by the parser */
155+ int st_type; /* EXPR or SUITE ? */
156+} PyST_Object;
157+
158+
159+static void parser_free(PyST_Object *st);
160+static int parser_compare(PyST_Object *left, PyST_Object *right);
161+static PyObject *parser_getattr(PyObject *self, char *name);
162+
163+
164+static
165+PyTypeObject PyST_Type = {
166+ PyObject_HEAD_INIT(NULL)
167+ 0,
168+ "parser.st", /* tp_name */
169+ (int) sizeof(PyST_Object), /* tp_basicsize */
170+ 0, /* tp_itemsize */
171+ (destructor)parser_free, /* tp_dealloc */
172+ 0, /* tp_print */
173+ parser_getattr, /* tp_getattr */
174+ 0, /* tp_setattr */
175+ (cmpfunc)parser_compare, /* tp_compare */
176+ 0, /* tp_repr */
177+ 0, /* tp_as_number */
178+ 0, /* tp_as_sequence */
179+ 0, /* tp_as_mapping */
180+ 0, /* tp_hash */
181+ 0, /* tp_call */
182+ 0, /* tp_str */
183+ 0, /* tp_getattro */
184+ 0, /* tp_setattro */
185+
186+ /* Functions to access object as input/output buffer */
187+ 0, /* tp_as_buffer */
188+
189+ Py_TPFLAGS_DEFAULT, /* tp_flags */
190+
191+ /* __doc__ */
192+ "Intermediate representation of a Python parse tree."
193+}; /* PyST_Type */
194+
195+
196+static int
197+parser_compare_nodes(node *left, node *right)
198+{
199+ int j;
200+
201+ if (TYPE(left) < TYPE(right))
202+ return (-1);
203+
204+ if (TYPE(right) < TYPE(left))
205+ return (1);
206+
207+ if (ISTERMINAL(TYPE(left)))
208+ return (strcmp(STR(left), STR(right)));
209+
210+ if (NCH(left) < NCH(right))
211+ return (-1);
212+
213+ if (NCH(right) < NCH(left))
214+ return (1);
215+
216+ for (j = 0; j < NCH(left); ++j) {
217+ int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
218+
219+ if (v != 0)
220+ return (v);
221+ }
222+ return (0);
223+}
224+
225+
226+/* int parser_compare(PyST_Object* left, PyST_Object* right)
227+ *
228+ * Comparison function used by the Python operators ==, !=, <, >, <=, >=
229+ * This really just wraps a call to parser_compare_nodes() with some easy
230+ * checks and protection code.
231+ *
232+ */
233+static int
234+parser_compare(PyST_Object *left, PyST_Object *right)
235+{
236+ if (left == right)
237+ return (0);
238+
239+ if ((left == 0) || (right == 0))
240+ return (-1);
241+
242+ return (parser_compare_nodes(left->st_node, right->st_node));
243+}
244+
245+
246+/* parser_newstobject(node* st)
247+ *
248+ * Allocates a new Python object representing an ST. This is simply the
249+ * 'wrapper' object that holds a node* and allows it to be passed around in
250+ * Python code.
251+ *
252+ */
253+static PyObject*
254+parser_newstobject(node *st, int type)
255+{
256+ PyST_Object* o = PyObject_New(PyST_Object, &PyST_Type);
257+
258+ if (o != 0) {
259+ o->st_node = st;
260+ o->st_type = type;
261+ }
262+ else {
263+ PyNode_Free(st);
264+ }
265+ return ((PyObject*)o);
266+}
267+
268+
269+/* void parser_free(PyST_Object* st)
270+ *
271+ * This is called by a del statement that reduces the reference count to 0.
272+ *
273+ */
274+static void
275+parser_free(PyST_Object *st)
276+{
277+ PyNode_Free(st->st_node);
278+ PyObject_Del(st);
279+}
280+
281+
282+/* parser_st2tuple(PyObject* self, PyObject* args, PyObject* kw)
283+ *
284+ * This provides conversion from a node* to a tuple object that can be
285+ * returned to the Python-level caller. The ST object is not modified.
286+ *
287+ */
288+static PyObject*
289+parser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw)
290+{
291+ PyObject *line_option = 0;
292+ PyObject *res = 0;
293+ int ok;
294+
295+ static char *keywords[] = {"ast", "line_info", NULL};
296+
297+ if (self == NULL) {
298+ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2tuple", keywords,
299+ &PyST_Type, &self, &line_option);
300+ }
301+ else
302+ ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:totuple", &keywords[1],
303+ &line_option);
304+ if (ok != 0) {
305+ int lineno = 0;
306+ if (line_option != NULL) {
307+ lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0;
308+ }
309+ /*
310+ * Convert ST into a tuple representation. Use Guido's function,
311+ * since it's known to work already.
312+ */
313+ res = node2tuple(((PyST_Object*)self)->st_node,
314+ PyTuple_New, PyTuple_SetItem, lineno);
315+ }
316+ return (res);
317+}
318+
319+
320+/* parser_st2list(PyObject* self, PyObject* args, PyObject* kw)
321+ *
322+ * This provides conversion from a node* to a list object that can be
323+ * returned to the Python-level caller. The ST object is not modified.
324+ *
325+ */
326+static PyObject*
327+parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw)
328+{
329+ PyObject *line_option = 0;
330+ PyObject *res = 0;
331+ int ok;
332+
333+ static char *keywords[] = {"ast", "line_info", NULL};
334+
335+ if (self == NULL)
336+ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2list", keywords,
337+ &PyST_Type, &self, &line_option);
338+ else
339+ ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1],
340+ &line_option);
341+ if (ok) {
342+ int lineno = 0;
343+ if (line_option != 0) {
344+ lineno = PyObject_IsTrue(line_option) ? 1 : 0;
345+ }
346+ /*
347+ * Convert ST into a tuple representation. Use Guido's function,
348+ * since it's known to work already.
349+ */
350+ res = node2tuple(self->st_node,
351+ PyList_New, PyList_SetItem, lineno);
352+ }
353+ return (res);
354+}
355+
356+
357+/* parser_compilest(PyObject* self, PyObject* args)
358+ *
359+ * This function creates code objects from the parse tree represented by
360+ * the passed-in data object. An optional file name is passed in as well.
361+ *
362+ */
363+static PyObject*
364+parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw)
365+{
366+ PyObject* res = 0;
367+ char* str = "<syntax-tree>";
368+ int ok;
369+
370+ static char *keywords[] = {"ast", "filename", NULL};
371+
372+ if (self == NULL)
373+ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compilest", keywords,
374+ &PyST_Type, &self, &str);
375+ else
376+ ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1],
377+ &str);
378+
379+ if (ok)
380+ res = (PyObject *)PyNode_Compile(self->st_node, str);
381+
382+ return (res);
383+}
384+
385+
386+/* PyObject* parser_isexpr(PyObject* self, PyObject* args)
387+ * PyObject* parser_issuite(PyObject* self, PyObject* args)
388+ *
389+ * Checks the passed-in ST object to determine if it is an expression or
390+ * a statement suite, respectively. The return is a Python truth value.
391+ *
392+ */
393+static PyObject*
394+parser_isexpr(PyST_Object *self, PyObject *args, PyObject *kw)
395+{
396+ PyObject* res = 0;
397+ int ok;
398+
399+ static char *keywords[] = {"ast", NULL};
400+
401+ if (self == NULL)
402+ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
403+ &PyST_Type, &self);
404+ else
405+ ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]);
406+
407+ if (ok) {
408+ /* Check to see if the ST represents an expression or not. */
409+ res = (self->st_type == PyST_EXPR) ? Py_True : Py_False;
410+ Py_INCREF(res);
411+ }
412+ return (res);
413+}
414+
415+
416+static PyObject*
417+parser_issuite(PyST_Object *self, PyObject *args, PyObject *kw)
418+{
419+ PyObject* res = 0;
420+ int ok;
421+
422+ static char *keywords[] = {"ast", NULL};
423+
424+ if (self == NULL)
425+ ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
426+ &PyST_Type, &self);
427+ else
428+ ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]);
429+
430+ if (ok) {
431+ /* Check to see if the ST represents an expression or not. */
432+ res = (self->st_type == PyST_EXPR) ? Py_False : Py_True;
433+ Py_INCREF(res);
434+ }
435+ return (res);
436+}
437+
438+
439+#define PUBLIC_METHOD_TYPE (METH_VARARGS|METH_KEYWORDS)
440+
441+static PyMethodDef
442+parser_methods[] = {
443+ {"compile", (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE,
444+ PyDoc_STR("Compile this ST object into a code object.")},
445+ {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
446+ PyDoc_STR("Determines if this ST object was created from an expression.")},
447+ {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
448+ PyDoc_STR("Determines if this ST object was created from a suite.")},
449+ {"tolist", (PyCFunction)parser_st2list, PUBLIC_METHOD_TYPE,
450+ PyDoc_STR("Creates a list-tree representation of this ST.")},
451+ {"totuple", (PyCFunction)parser_st2tuple, PUBLIC_METHOD_TYPE,
452+ PyDoc_STR("Creates a tuple-tree representation of this ST.")},
453+
454+ {NULL, NULL, 0, NULL}
455+};
456+
457+
458+static PyObject*
459+parser_getattr(PyObject *self, char *name)
460+{
461+ return (Py_FindMethod(parser_methods, self, name));
462+}
463+
464+
465+/* err_string(char* message)
466+ *
467+ * Sets the error string for an exception of type ParserError.
468+ *
469+ */
470+static void
471+err_string(char *message)
472+{
473+ PyErr_SetString(parser_error, message);
474+}
475+
476+
477+/* PyObject* parser_do_parse(PyObject* args, int type)
478+ *
479+ * Internal function to actually execute the parse and return the result if
480+ * successful or set an exception if not.
481+ *
482+ */
483+static PyObject*
484+parser_do_parse(PyObject *args, PyObject *kw, char *argspec, int type)
485+{
486+ char* string = 0;
487+ PyObject* res = 0;
488+
489+ static char *keywords[] = {"source", NULL};
490+
491+ if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
492+ node* n = PyParser_SimpleParseString(string,
493+ (type == PyST_EXPR)
494+ ? eval_input : file_input);
495+
496+ if (n)
497+ res = parser_newstobject(n, type);
498+ }
499+ return (res);
500+}
501+
502+
503+/* PyObject* parser_expr(PyObject* self, PyObject* args)
504+ * PyObject* parser_suite(PyObject* self, PyObject* args)
505+ *
506+ * External interfaces to the parser itself. Which is called determines if
507+ * the parser attempts to recognize an expression ('eval' form) or statement
508+ * suite ('exec' form). The real work is done by parser_do_parse() above.
509+ *
510+ */
511+static PyObject*
512+parser_expr(PyST_Object *self, PyObject *args, PyObject *kw)
513+{
514+ NOTE(ARGUNUSED(self))
515+ return (parser_do_parse(args, kw, "s:expr", PyST_EXPR));
516+}
517+
518+
519+static PyObject*
520+parser_suite(PyST_Object *self, PyObject *args, PyObject *kw)
521+{
522+ NOTE(ARGUNUSED(self))
523+ return (parser_do_parse(args, kw, "s:suite", PyST_SUITE));
524+}
525+
526+
527+
528+/* This is the messy part of the code. Conversion from a tuple to an ST
529+ * object requires that the input tuple be valid without having to rely on
530+ * catching an exception from the compiler. This is done to allow the
531+ * compiler itself to remain fast, since most of its input will come from
532+ * the parser directly, and therefore be known to be syntactically correct.
533+ * This validation is done to ensure that we don't core dump the compile
534+ * phase, returning an exception instead.
535+ *
536+ * Two aspects can be broken out in this code: creating a node tree from
537+ * the tuple passed in, and verifying that it is indeed valid. It may be
538+ * advantageous to expand the number of ST types to include funcdefs and
539+ * lambdadefs to take advantage of the optimizer, recognizing those STs
540+ * here. They are not necessary, and not quite as useful in a raw form.
541+ * For now, let's get expressions and suites working reliably.
542+ */
543+
544+
545+static node* build_node_tree(PyObject *tuple);
546+static int validate_expr_tree(node *tree);
547+static int validate_file_input(node *tree);
548+static int validate_encoding_decl(node *tree);
549+
550+/* PyObject* parser_tuple2st(PyObject* self, PyObject* args)
551+ *
552+ * This is the public function, called from the Python code. It receives a
553+ * single tuple object from the caller, and creates an ST object if the
554+ * tuple can be validated. It does this by checking the first code of the
555+ * tuple, and, if acceptable, builds the internal representation. If this
556+ * step succeeds, the internal representation is validated as fully as
557+ * possible with the various validate_*() routines defined below.
558+ *
559+ * This function must be changed if support is to be added for PyST_FRAGMENT
560+ * ST objects.
561+ *
562+ */
563+static PyObject*
564+parser_tuple2st(PyST_Object *self, PyObject *args, PyObject *kw)
565+{
566+ NOTE(ARGUNUSED(self))
567+ PyObject *st = 0;
568+ PyObject *tuple;
569+ node *tree;
570+
571+ static char *keywords[] = {"sequence", NULL};
572+
573+ if (!PyArg_ParseTupleAndKeywords(args, kw, "O:sequence2st", keywords,
574+ &tuple))
575+ return (0);
576+ if (!PySequence_Check(tuple)) {
577+ PyErr_SetString(PyExc_ValueError,
578+ "sequence2st() requires a single sequence argument");
579+ return (0);
580+ }
581+ /*
582+ * Convert the tree to the internal form before checking it.
583+ */
584+ tree = build_node_tree(tuple);
585+ if (tree != 0) {
586+ int start_sym = TYPE(tree);
587+ if (start_sym == eval_input) {
588+ /* Might be an eval form. */
589+ if (validate_expr_tree(tree))
590+ st = parser_newstobject(tree, PyST_EXPR);
591+ else
592+ PyNode_Free(tree);
593+ }
594+ else if (start_sym == file_input) {
595+ /* This looks like an exec form so far. */
596+ if (validate_file_input(tree))
597+ st = parser_newstobject(tree, PyST_SUITE);
598+ else
599+ PyNode_Free(tree);
600+ }
601+ else if (start_sym == encoding_decl) {
602+ /* This looks like an encoding_decl so far. */
603+ if (validate_encoding_decl(tree))
604+ st = parser_newstobject(tree, PyST_SUITE);
605+ else
606+ PyNode_Free(tree);
607+ }
608+ else {
609+ /* This is a fragment, at best. */
610+ PyNode_Free(tree);
611+ err_string("parse tree does not use a valid start symbol");
612+ }
613+ }
614+ /* Make sure we throw an exception on all errors. We should never
615+ * get this, but we'd do well to be sure something is done.
616+ */
617+ if (st == NULL && !PyErr_Occurred())
618+ err_string("unspecified ST error occurred");
619+
620+ return st;
621+}
622+
623+
624+/* node* build_node_children()
625+ *
626+ * Iterate across the children of the current non-terminal node and build
627+ * their structures. If successful, return the root of this portion of
628+ * the tree, otherwise, 0. Any required exception will be specified already,
629+ * and no memory will have been deallocated.
630+ *
631+ */
632+static node*
633+build_node_children(PyObject *tuple, node *root, int *line_num)
634+{
635+ Py_ssize_t len = PyObject_Size(tuple);
636+ Py_ssize_t i;
637+ int err;
638+
639+ for (i = 1; i < len; ++i) {
640+ /* elem must always be a sequence, however simple */
641+ PyObject* elem = PySequence_GetItem(tuple, i);
642+ int ok = elem != NULL;
643+ long type = 0;
644+ char *strn = 0;
645+
646+ if (ok)
647+ ok = PySequence_Check(elem);
648+ if (ok) {
649+ PyObject *temp = PySequence_GetItem(elem, 0);
650+ if (temp == NULL)
651+ ok = 0;
652+ else {
653+ ok = PyInt_Check(temp);
654+ if (ok)
655+ type = PyInt_AS_LONG(temp);
656+ Py_DECREF(temp);
657+ }
658+ }
659+ if (!ok) {
660+ PyObject *err = Py_BuildValue("os", elem,
661+ "Illegal node construct.");
662+ PyErr_SetObject(parser_error, err);
663+ Py_XDECREF(err);
664+ Py_XDECREF(elem);
665+ return (0);
666+ }
667+ if (ISTERMINAL(type)) {
668+ Py_ssize_t len = PyObject_Size(elem);
669+ PyObject *temp;
670+
671+ if ((len != 2) && (len != 3)) {
672+ err_string("terminal nodes must have 2 or 3 entries");
673+ return 0;
674+ }
675+ temp = PySequence_GetItem(elem, 1);
676+ if (temp == NULL)
677+ return 0;
678+ if (!PyString_Check(temp)) {
679+ PyErr_Format(parser_error,
680+ "second item in terminal node must be a string,"
681+ " found %s",
682+ temp->ob_type->tp_name);
683+ Py_DECREF(temp);
684+ return 0;
685+ }
686+ if (len == 3) {
687+ PyObject *o = PySequence_GetItem(elem, 2);
688+ if (o != NULL) {
689+ if (PyInt_Check(o))
690+ *line_num = PyInt_AS_LONG(o);
691+ else {
692+ PyErr_Format(parser_error,
693+ "third item in terminal node must be an"
694+ " integer, found %s",
695+ temp->ob_type->tp_name);
696+ Py_DECREF(o);
697+ Py_DECREF(temp);
698+ return 0;
699+ }
700+ Py_DECREF(o);
701+ }
702+ }
703+ len = PyString_GET_SIZE(temp) + 1;
704+ strn = (char *)PyObject_MALLOC(len);
705+ if (strn != NULL)
706+ (void) memcpy(strn, PyString_AS_STRING(temp), len);
707+ Py_DECREF(temp);
708+ }
709+ else if (!ISNONTERMINAL(type)) {
710+ /*
711+ * It has to be one or the other; this is an error.
712+ * Throw an exception.
713+ */
714+ PyObject *err = Py_BuildValue("os", elem, "unknown node type.");
715+ PyErr_SetObject(parser_error, err);
716+ Py_XDECREF(err);
717+ Py_XDECREF(elem);
718+ return (0);
719+ }
720+ err = PyNode_AddChild(root, type, strn, *line_num, 0);
721+ if (err == E_NOMEM) {
722+ PyObject_FREE(strn);
723+ return (node *) PyErr_NoMemory();
724+ }
725+ if (err == E_OVERFLOW) {
726+ PyObject_FREE(strn);
727+ PyErr_SetString(PyExc_ValueError,
728+ "unsupported number of child nodes");
729+ return NULL;
730+ }
731+
732+ if (ISNONTERMINAL(type)) {
733+ node* new_child = CHILD(root, i - 1);
734+
735+ if (new_child != build_node_children(elem, new_child, line_num)) {
736+ Py_XDECREF(elem);
737+ return (0);
738+ }
739+ }
740+ else if (type == NEWLINE) { /* It's true: we increment the */
741+ ++(*line_num); /* line number *after* the newline! */
742+ }
743+ Py_XDECREF(elem);
744+ }
745+ return root;
746+}
747+
748+
749+static node*
750+build_node_tree(PyObject *tuple)
751+{
752+ node* res = 0;
753+ PyObject *temp = PySequence_GetItem(tuple, 0);
754+ long num = -1;
755+
756+ if (temp != NULL)
757+ num = PyInt_AsLong(temp);
758+ Py_XDECREF(temp);
759+ if (ISTERMINAL(num)) {
760+ /*
761+ * The tuple is simple, but it doesn't start with a start symbol.
762+ * Throw an exception now and be done with it.
763+ */
764+ tuple = Py_BuildValue("os", tuple,
765+ "Illegal syntax-tree; cannot start with terminal symbol.");
766+ PyErr_SetObject(parser_error, tuple);
767+ Py_XDECREF(tuple);
768+ }
769+ else if (ISNONTERMINAL(num)) {
770+ /*
771+ * Not efficient, but that can be handled later.
772+ */
773+ int line_num = 0;
774+ PyObject *encoding = NULL;
775+
776+ if (num == encoding_decl) {
777+ encoding = PySequence_GetItem(tuple, 2);
778+ /* tuple isn't borrowed anymore here, need to DECREF */
779+ tuple = PySequence_GetSlice(tuple, 0, 2);
780+ }
781+ res = PyNode_New(num);
782+ if (res != NULL) {
783+ if (res != build_node_children(tuple, res, &line_num)) {
784+ PyNode_Free(res);
785+ res = NULL;
786+ }
787+ if (res && encoding) {
788+ Py_ssize_t len;
789+ len = PyString_GET_SIZE(encoding) + 1;
790+ res->n_str = (char *)PyObject_MALLOC(len);
791+ if (res->n_str != NULL)
792+ (void) memcpy(res->n_str, PyString_AS_STRING(encoding), len);
793+ Py_DECREF(encoding);
794+ Py_DECREF(tuple);
795+ }
796+ }
797+ }
798+ else {
799+ /* The tuple is illegal -- if the number is neither TERMINAL nor
800+ * NONTERMINAL, we can't use it. Not sure the implementation
801+ * allows this condition, but the API doesn't preclude it.
802+ */
803+ PyObject *err = Py_BuildValue("os", tuple,
804+ "Illegal component tuple.");
805+ PyErr_SetObject(parser_error, err);
806+ Py_XDECREF(err);
807+ }
808+
809+ return (res);
810+}
811+
812+
813+/*
814+ * Validation routines used within the validation section:
815+ */
816+static int validate_terminal(node *terminal, int type, char *string);
817+
818+#define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
819+#define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
820+#define validate_colon(ch) validate_terminal(ch, COLON, ":")
821+#define validate_comma(ch) validate_terminal(ch, COMMA, ",")
822+#define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
823+#define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
824+#define validate_indent(ch) validate_terminal(ch, INDENT, (char*)NULL)
825+#define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
826+#define validate_newline(ch) validate_terminal(ch, NEWLINE, (char*)NULL)
827+#define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
828+#define validate_semi(ch) validate_terminal(ch, SEMI, ";")
829+#define validate_star(ch) validate_terminal(ch, STAR, "*")
830+#define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
831+#define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
832+#define validate_dot(ch) validate_terminal(ch, DOT, ".")
833+#define validate_at(ch) validate_terminal(ch, AT, "@")
834+#define validate_name(ch, str) validate_terminal(ch, NAME, str)
835+
836+#define VALIDATER(n) static int validate_##n(node *tree)
837+
838+VALIDATER(node); VALIDATER(small_stmt);
839+VALIDATER(class); VALIDATER(node);
840+VALIDATER(parameters); VALIDATER(suite);
841+VALIDATER(testlist); VALIDATER(varargslist);
842+VALIDATER(fpdef); VALIDATER(fplist);
843+VALIDATER(stmt); VALIDATER(simple_stmt);
844+VALIDATER(expr_stmt); VALIDATER(power);
845+VALIDATER(print_stmt); VALIDATER(del_stmt);
846+VALIDATER(return_stmt); VALIDATER(list_iter);
847+VALIDATER(raise_stmt); VALIDATER(import_stmt);
848+VALIDATER(import_name); VALIDATER(import_from);
849+VALIDATER(global_stmt); VALIDATER(list_if);
850+VALIDATER(assert_stmt); VALIDATER(list_for);
851+VALIDATER(exec_stmt); VALIDATER(compound_stmt);
852+VALIDATER(while); VALIDATER(for);
853+VALIDATER(try); VALIDATER(except_clause);
854+VALIDATER(test); VALIDATER(and_test);
855+VALIDATER(not_test); VALIDATER(comparison);
856+VALIDATER(comp_op); VALIDATER(expr);
857+VALIDATER(xor_expr); VALIDATER(and_expr);
858+VALIDATER(shift_expr); VALIDATER(arith_expr);
859+VALIDATER(term); VALIDATER(factor);
860+VALIDATER(atom); VALIDATER(lambdef);
861+VALIDATER(trailer); VALIDATER(subscript);
862+VALIDATER(subscriptlist); VALIDATER(sliceop);
863+VALIDATER(exprlist); VALIDATER(dictmaker);
864+VALIDATER(arglist); VALIDATER(argument);
865+VALIDATER(listmaker); VALIDATER(yield_stmt);
866+VALIDATER(testlist1); VALIDATER(gen_for);
867+VALIDATER(gen_iter); VALIDATER(gen_if);
868+VALIDATER(testlist_gexp); VALIDATER(yield_expr);
869+VALIDATER(yield_or_testlist); VALIDATER(or_test);
870+VALIDATER(old_test); VALIDATER(old_lambdef);
871+
872+#undef VALIDATER
873+
874+#define is_even(n) (((n) & 1) == 0)
875+#define is_odd(n) (((n) & 1) == 1)
876+
877+
878+static int
879+validate_ntype(node *n, int t)
880+{
881+ if (TYPE(n) != t) {
882+ PyErr_Format(parser_error, "Expected node type %d, got %d.",
883+ t, TYPE(n));
884+ return 0;
885+ }
886+ return 1;
887+}
888+
889+
890+/* Verifies that the number of child nodes is exactly 'num', raising
891+ * an exception if it isn't. The exception message does not indicate
892+ * the exact number of nodes, allowing this to be used to raise the
893+ * "right" exception when the wrong number of nodes is present in a
894+ * specific variant of a statement's syntax. This is commonly used
895+ * in that fashion.
896+ */
897+static int
898+validate_numnodes(node *n, int num, const char *const name)
899+{
900+ if (NCH(n) != num) {
901+ PyErr_Format(parser_error,
902+ "Illegal number of children for %s node.", name);
903+ return 0;
904+ }
905+ return 1;
906+}
907+
908+
909+static int
910+validate_terminal(node *terminal, int type, char *string)
911+{
912+ int res = (validate_ntype(terminal, type)
913+ && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
914+
915+ if (!res && !PyErr_Occurred()) {
916+ PyErr_Format(parser_error,
917+ "Illegal terminal: expected \"%s\"", string);
918+ }
919+ return (res);
920+}
921+
922+
923+/* X (',' X) [',']
924+ */
925+static int
926+validate_repeating_list(node *tree, int ntype, int (*vfunc)(node *),
927+ const char *const name)
928+{
929+ int nch = NCH(tree);
930+ int res = (nch && validate_ntype(tree, ntype)
931+ && vfunc(CHILD(tree, 0)));
932+
933+ if (!res && !PyErr_Occurred())
934+ (void) validate_numnodes(tree, 1, name);
935+ else {
936+ if (is_even(nch))
937+ res = validate_comma(CHILD(tree, --nch));
938+ if (res && nch > 1) {
939+ int pos = 1;
940+ for ( ; res && pos < nch; pos += 2)
941+ res = (validate_comma(CHILD(tree, pos))
942+ && vfunc(CHILD(tree, pos + 1)));
943+ }
944+ }
945+ return (res);
946+}
947+
948+
949+/* validate_class()
950+ *
951+ * classdef:
952+ * 'class' NAME ['(' testlist ')'] ':' suite
953+ */
954+static int
955+validate_class(node *tree)
956+{
957+ int nch = NCH(tree);
958+ int res = (validate_ntype(tree, classdef) &&
959+ ((nch == 4) || (nch == 6) || (nch == 7)));
960+
961+ if (res) {
962+ res = (validate_name(CHILD(tree, 0), "class")
963+ && validate_ntype(CHILD(tree, 1), NAME)
964+ && validate_colon(CHILD(tree, nch - 2))
965+ && validate_suite(CHILD(tree, nch - 1)));
966+ }
967+ else {
968+ (void) validate_numnodes(tree, 4, "class");
969+ }
970+
971+ if (res) {
972+ if (nch == 7) {
973+ res = ((validate_lparen(CHILD(tree, 2)) &&
974+ validate_testlist(CHILD(tree, 3)) &&
975+ validate_rparen(CHILD(tree, 4))));
976+ }
977+ else if (nch == 6) {
978+ res = (validate_lparen(CHILD(tree,2)) &&
979+ validate_rparen(CHILD(tree,3)));
980+ }
981+ }
982+ return (res);
983+}
984+
985+
986+/* if_stmt:
987+ * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
988+ */
989+static int
990+validate_if(node *tree)
991+{
992+ int nch = NCH(tree);
993+ int res = (validate_ntype(tree, if_stmt)
994+ && (nch >= 4)
995+ && validate_name(CHILD(tree, 0), "if")
996+ && validate_test(CHILD(tree, 1))
997+ && validate_colon(CHILD(tree, 2))
998+ && validate_suite(CHILD(tree, 3)));
999+
1000+ if (res && ((nch % 4) == 3)) {
1001+ /* ... 'else' ':' suite */
1002+ res = (validate_name(CHILD(tree, nch - 3), "else")
1003+ && validate_colon(CHILD(tree, nch - 2))
1004+ && validate_suite(CHILD(tree, nch - 1)));
1005+ nch -= 3;
1006+ }
1007+ else if (!res && !PyErr_Occurred())
1008+ (void) validate_numnodes(tree, 4, "if");
1009+ if ((nch % 4) != 0)
1010+ /* Will catch the case for nch < 4 */
1011+ res = validate_numnodes(tree, 0, "if");
1012+ else if (res && (nch > 4)) {
1013+ /* ... ('elif' test ':' suite)+ ... */
1014+ int j = 4;
1015+ while ((j < nch) && res) {
1016+ res = (validate_name(CHILD(tree, j), "elif")
1017+ && validate_colon(CHILD(tree, j + 2))
1018+ && validate_test(CHILD(tree, j + 1))
1019+ && validate_suite(CHILD(tree, j + 3)));
1020+ j += 4;
1021+ }
1022+ }
1023+ return (res);
1024+}
1025+
1026+
1027+/* parameters:
1028+ * '(' [varargslist] ')'
1029+ *
1030+ */
1031+static int
1032+validate_parameters(node *tree)
1033+{
1034+ int nch = NCH(tree);
1035+ int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
1036+
1037+ if (res) {
1038+ res = (validate_lparen(CHILD(tree, 0))
1039+ && validate_rparen(CHILD(tree, nch - 1)));
1040+ if (res && (nch == 3))
1041+ res = validate_varargslist(CHILD(tree, 1));
1042+ }
1043+ else {
1044+ (void) validate_numnodes(tree, 2, "parameters");
1045+ }
1046+ return (res);
1047+}
1048+
1049+
1050+/* validate_suite()
1051+ *
1052+ * suite:
1053+ * simple_stmt
1054+ * | NEWLINE INDENT stmt+ DEDENT
1055+ */
1056+static int
1057+validate_suite(node *tree)
1058+{
1059+ int nch = NCH(tree);
1060+ int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
1061+
1062+ if (res && (nch == 1))
1063+ res = validate_simple_stmt(CHILD(tree, 0));
1064+ else if (res) {
1065+ /* NEWLINE INDENT stmt+ DEDENT */
1066+ res = (validate_newline(CHILD(tree, 0))
1067+ && validate_indent(CHILD(tree, 1))
1068+ && validate_stmt(CHILD(tree, 2))
1069+ && validate_dedent(CHILD(tree, nch - 1)));
1070+
1071+ if (res && (nch > 4)) {
1072+ int i = 3;
1073+ --nch; /* forget the DEDENT */
1074+ for ( ; res && (i < nch); ++i)
1075+ res = validate_stmt(CHILD(tree, i));
1076+ }
1077+ else if (nch < 4)
1078+ res = validate_numnodes(tree, 4, "suite");
1079+ }
1080+ return (res);
1081+}
1082+
1083+
1084+static int
1085+validate_testlist(node *tree)
1086+{
1087+ return (validate_repeating_list(tree, testlist,
1088+ validate_test, "testlist"));
1089+}
1090+
1091+
1092+static int
1093+validate_testlist1(node *tree)
1094+{
1095+ return (validate_repeating_list(tree, testlist1,
1096+ validate_test, "testlist1"));
1097+}
1098+
1099+
1100+static int
1101+validate_testlist_safe(node *tree)
1102+{
1103+ return (validate_repeating_list(tree, testlist_safe,
1104+ validate_old_test, "testlist_safe"));
1105+}
1106+
1107+
1108+/* '*' NAME [',' '**' NAME] | '**' NAME
1109+ */
1110+static int
1111+validate_varargslist_trailer(node *tree, int start)
1112+{
1113+ int nch = NCH(tree);
1114+ int res = 0;
1115+ int sym;
1116+
1117+ if (nch <= start) {
1118+ err_string("expected variable argument trailer for varargslist");
1119+ return 0;
1120+ }
1121+ sym = TYPE(CHILD(tree, start));
1122+ if (sym == STAR) {
1123+ /*
1124+ * ('*' NAME [',' '**' NAME]
1125+ */
1126+ if (nch-start == 2)
1127+ res = validate_name(CHILD(tree, start+1), NULL);
1128+ else if (nch-start == 5)
1129+ res = (validate_name(CHILD(tree, start+1), NULL)
1130+ && validate_comma(CHILD(tree, start+2))
1131+ && validate_doublestar(CHILD(tree, start+3))
1132+ && validate_name(CHILD(tree, start+4), NULL));
1133+ }
1134+ else if (sym == DOUBLESTAR) {
1135+ /*
1136+ * '**' NAME
1137+ */
1138+ if (nch-start == 2)
1139+ res = validate_name(CHILD(tree, start+1), NULL);
1140+ }
1141+ if (!res)
1142+ err_string("illegal variable argument trailer for varargslist");
1143+ return res;
1144+}
1145+
1146+
1147+/* validate_varargslist()
1148+ *
1149+ * varargslist:
1150+ * (fpdef ['=' test] ',')*
1151+ * ('*' NAME [',' '**' NAME]
1152+ * | '**' NAME)
1153+ * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1154+ *
1155+ */
1156+static int
1157+validate_varargslist(node *tree)
1158+{
1159+ int nch = NCH(tree);
1160+ int res = validate_ntype(tree, varargslist) && (nch != 0);
1161+ int sym;
1162+
1163+ if (!res)
1164+ return 0;
1165+ if (nch < 1) {
1166+ err_string("varargslist missing child nodes");
1167+ return 0;
1168+ }
1169+ sym = TYPE(CHILD(tree, 0));
1170+ if (sym == STAR || sym == DOUBLESTAR)
1171+ /* whole thing matches:
1172+ * '*' NAME [',' '**' NAME] | '**' NAME
1173+ */
1174+ res = validate_varargslist_trailer(tree, 0);
1175+ else if (sym == fpdef) {
1176+ int i = 0;
1177+
1178+ sym = TYPE(CHILD(tree, nch-1));
1179+ if (sym == NAME) {
1180+ /*
1181+ * (fpdef ['=' test] ',')+
1182+ * ('*' NAME [',' '**' NAME]
1183+ * | '**' NAME)
1184+ */
1185+ /* skip over (fpdef ['=' test] ',')+ */
1186+ while (res && (i+2 <= nch)) {
1187+ res = validate_fpdef(CHILD(tree, i));
1188+ ++i;
1189+ if (res && TYPE(CHILD(tree, i)) == EQUAL && (i+2 <= nch)) {
1190+ res = (validate_equal(CHILD(tree, i))
1191+ && validate_test(CHILD(tree, i+1)));
1192+ if (res)
1193+ i += 2;
1194+ }
1195+ if (res && i < nch) {
1196+ res = validate_comma(CHILD(tree, i));
1197+ ++i;
1198+ if (res && i < nch
1199+ && (TYPE(CHILD(tree, i)) == DOUBLESTAR
1200+ || TYPE(CHILD(tree, i)) == STAR))
1201+ break;
1202+ }
1203+ }
1204+ /* ... '*' NAME [',' '**' NAME] | '**' NAME
1205+ * i --^^^
1206+ */
1207+ if (res)
1208+ res = validate_varargslist_trailer(tree, i);
1209+ }
1210+ else {
1211+ /*
1212+ * fpdef ['=' test] (',' fpdef ['=' test])* [',']
1213+ */
1214+ /* strip trailing comma node */
1215+ if (sym == COMMA) {
1216+ res = validate_comma(CHILD(tree, nch-1));
1217+ if (!res)
1218+ return 0;
1219+ --nch;
1220+ }
1221+ /*
1222+ * fpdef ['=' test] (',' fpdef ['=' test])*
1223+ */
1224+ res = validate_fpdef(CHILD(tree, 0));
1225+ ++i;
1226+ if (res && (i+2 <= nch) && TYPE(CHILD(tree, i)) == EQUAL) {
1227+ res = (validate_equal(CHILD(tree, i))
1228+ && validate_test(CHILD(tree, i+1)));
1229+ i += 2;
1230+ }
1231+ /*
1232+ * ... (',' fpdef ['=' test])*
1233+ * i ---^^^
1234+ */
1235+ while (res && (nch - i) >= 2) {
1236+ res = (validate_comma(CHILD(tree, i))
1237+ && validate_fpdef(CHILD(tree, i+1)));
1238+ i += 2;
1239+ if (res && (nch - i) >= 2 && TYPE(CHILD(tree, i)) == EQUAL) {
1240+ res = (validate_equal(CHILD(tree, i))
1241+ && validate_test(CHILD(tree, i+1)));
1242+ i += 2;
1243+ }
1244+ }
1245+ if (res && nch - i != 0) {
1246+ res = 0;
1247+ err_string("illegal formation for varargslist");
1248+ }
1249+ }
1250+ }
1251+ return res;
1252+}
1253+
1254+
1255+/* list_iter: list_for | list_if
1256+ */
1257+static int
1258+validate_list_iter(node *tree)
1259+{
1260+ int res = (validate_ntype(tree, list_iter)
1261+ && validate_numnodes(tree, 1, "list_iter"));
1262+ if (res && TYPE(CHILD(tree, 0)) == list_for)
1263+ res = validate_list_for(CHILD(tree, 0));
1264+ else
1265+ res = validate_list_if(CHILD(tree, 0));
1266+
1267+ return res;
1268+}
1269+
1270+/* gen_iter: gen_for | gen_if
1271+ */
1272+static int
1273+validate_gen_iter(node *tree)
1274+{
1275+ int res = (validate_ntype(tree, gen_iter)
1276+ && validate_numnodes(tree, 1, "gen_iter"));
1277+ if (res && TYPE(CHILD(tree, 0)) == gen_for)
1278+ res = validate_gen_for(CHILD(tree, 0));
1279+ else
1280+ res = validate_gen_if(CHILD(tree, 0));
1281+
1282+ return res;
1283+}
1284+
1285+/* list_for: 'for' exprlist 'in' testlist [list_iter]
1286+ */
1287+static int
1288+validate_list_for(node *tree)
1289+{
1290+ int nch = NCH(tree);
1291+ int res;
1292+
1293+ if (nch == 5)
1294+ res = validate_list_iter(CHILD(tree, 4));
1295+ else
1296+ res = validate_numnodes(tree, 4, "list_for");
1297+
1298+ if (res)
1299+ res = (validate_name(CHILD(tree, 0), "for")
1300+ && validate_exprlist(CHILD(tree, 1))
1301+ && validate_name(CHILD(tree, 2), "in")
1302+ && validate_testlist_safe(CHILD(tree, 3)));
1303+
1304+ return res;
1305+}
1306+
1307+/* gen_for: 'for' exprlist 'in' test [gen_iter]
1308+ */
1309+static int
1310+validate_gen_for(node *tree)
1311+{
1312+ int nch = NCH(tree);
1313+ int res;
1314+
1315+ if (nch == 5)
1316+ res = validate_gen_iter(CHILD(tree, 4));
1317+ else
1318+ res = validate_numnodes(tree, 4, "gen_for");
1319+
1320+ if (res)
1321+ res = (validate_name(CHILD(tree, 0), "for")
1322+ && validate_exprlist(CHILD(tree, 1))
1323+ && validate_name(CHILD(tree, 2), "in")
1324+ && validate_or_test(CHILD(tree, 3)));
1325+
1326+ return res;
1327+}
1328+
1329+/* list_if: 'if' old_test [list_iter]
1330+ */
1331+static int
1332+validate_list_if(node *tree)
1333+{
1334+ int nch = NCH(tree);
1335+ int res;
1336+
1337+ if (nch == 3)
1338+ res = validate_list_iter(CHILD(tree, 2));
1339+ else
1340+ res = validate_numnodes(tree, 2, "list_if");
1341+
1342+ if (res)
1343+ res = (validate_name(CHILD(tree, 0), "if")
1344+ && validate_old_test(CHILD(tree, 1)));
1345+
1346+ return res;
1347+}
1348+
1349+/* gen_if: 'if' old_test [gen_iter]
1350+ */
1351+static int
1352+validate_gen_if(node *tree)
1353+{
1354+ int nch = NCH(tree);
1355+ int res;
1356+
1357+ if (nch == 3)
1358+ res = validate_gen_iter(CHILD(tree, 2));
1359+ else
1360+ res = validate_numnodes(tree, 2, "gen_if");
1361+
1362+ if (res)
1363+ res = (validate_name(CHILD(tree, 0), "if")
1364+ && validate_old_test(CHILD(tree, 1)));
1365+
1366+ return res;
1367+}
1368+
1369+/* validate_fpdef()
1370+ *
1371+ * fpdef:
1372+ * NAME
1373+ * | '(' fplist ')'
1374+ */
1375+static int
1376+validate_fpdef(node *tree)
1377+{
1378+ int nch = NCH(tree);
1379+ int res = validate_ntype(tree, fpdef);
1380+
1381+ if (res) {
1382+ if (nch == 1)
1383+ res = validate_ntype(CHILD(tree, 0), NAME);
1384+ else if (nch == 3)
1385+ res = (validate_lparen(CHILD(tree, 0))
1386+ && validate_fplist(CHILD(tree, 1))
1387+ && validate_rparen(CHILD(tree, 2)));
1388+ else
1389+ res = validate_numnodes(tree, 1, "fpdef");
1390+ }
1391+ return (res);
1392+}
1393+
1394+
1395+static int
1396+validate_fplist(node *tree)
1397+{
1398+ return (validate_repeating_list(tree, fplist,
1399+ validate_fpdef, "fplist"));
1400+}
1401+
1402+
1403+/* simple_stmt | compound_stmt
1404+ *
1405+ */
1406+static int
1407+validate_stmt(node *tree)
1408+{
1409+ int res = (validate_ntype(tree, stmt)
1410+ && validate_numnodes(tree, 1, "stmt"));
1411+
1412+ if (res) {
1413+ tree = CHILD(tree, 0);
1414+
1415+ if (TYPE(tree) == simple_stmt)
1416+ res = validate_simple_stmt(tree);
1417+ else
1418+ res = validate_compound_stmt(tree);
1419+ }
1420+ return (res);
1421+}
1422+
1423+
1424+/* small_stmt (';' small_stmt)* [';'] NEWLINE
1425+ *
1426+ */
1427+static int
1428+validate_simple_stmt(node *tree)
1429+{
1430+ int nch = NCH(tree);
1431+ int res = (validate_ntype(tree, simple_stmt)
1432+ && (nch >= 2)
1433+ && validate_small_stmt(CHILD(tree, 0))
1434+ && validate_newline(CHILD(tree, nch - 1)));
1435+
1436+ if (nch < 2)
1437+ res = validate_numnodes(tree, 2, "simple_stmt");
1438+ --nch; /* forget the NEWLINE */
1439+ if (res && is_even(nch))
1440+ res = validate_semi(CHILD(tree, --nch));
1441+ if (res && (nch > 2)) {
1442+ int i;
1443+
1444+ for (i = 1; res && (i < nch); i += 2)
1445+ res = (validate_semi(CHILD(tree, i))
1446+ && validate_small_stmt(CHILD(tree, i + 1)));
1447+ }
1448+ return (res);
1449+}
1450+
1451+
1452+static int
1453+validate_small_stmt(node *tree)
1454+{
1455+ int nch = NCH(tree);
1456+ int res = validate_numnodes(tree, 1, "small_stmt");
1457+
1458+ if (res) {
1459+ int ntype = TYPE(CHILD(tree, 0));
1460+
1461+ if ( (ntype == expr_stmt)
1462+ || (ntype == print_stmt)
1463+ || (ntype == del_stmt)
1464+ || (ntype == pass_stmt)
1465+ || (ntype == flow_stmt)
1466+ || (ntype == import_stmt)
1467+ || (ntype == global_stmt)
1468+ || (ntype == assert_stmt)
1469+ || (ntype == exec_stmt))
1470+ res = validate_node(CHILD(tree, 0));
1471+ else {
1472+ res = 0;
1473+ err_string("illegal small_stmt child type");
1474+ }
1475+ }
1476+ else if (nch == 1) {
1477+ res = 0;
1478+ PyErr_Format(parser_error,
1479+ "Unrecognized child node of small_stmt: %d.",
1480+ TYPE(CHILD(tree, 0)));
1481+ }
1482+ return (res);
1483+}
1484+
1485+
1486+/* compound_stmt:
1487+ * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1488+ */
1489+static int
1490+validate_compound_stmt(node *tree)
1491+{
1492+ int res = (validate_ntype(tree, compound_stmt)
1493+ && validate_numnodes(tree, 1, "compound_stmt"));
1494+ int ntype;
1495+
1496+ if (!res)
1497+ return (0);
1498+
1499+ tree = CHILD(tree, 0);
1500+ ntype = TYPE(tree);
1501+ if ( (ntype == if_stmt)
1502+ || (ntype == while_stmt)
1503+ || (ntype == for_stmt)
1504+ || (ntype == try_stmt)
1505+ || (ntype == funcdef)
1506+ || (ntype == classdef))
1507+ res = validate_node(tree);
1508+ else {
1509+ res = 0;
1510+ PyErr_Format(parser_error,
1511+ "Illegal compound statement type: %d.", TYPE(tree));
1512+ }
1513+ return (res);
1514+}
1515+
1516+
1517+static int
1518+validate_yield_or_testlist(node *tree)
1519+{
1520+ if (TYPE(tree) == yield_expr)
1521+ return validate_yield_expr(tree);
1522+ else
1523+ return validate_testlist(tree);
1524+}
1525+
1526+static int
1527+validate_expr_stmt(node *tree)
1528+{
1529+ int j;
1530+ int nch = NCH(tree);
1531+ int res = (validate_ntype(tree, expr_stmt)
1532+ && is_odd(nch)
1533+ && validate_testlist(CHILD(tree, 0)));
1534+
1535+ if (res && nch == 3
1536+ && TYPE(CHILD(tree, 1)) == augassign) {
1537+ res = validate_numnodes(CHILD(tree, 1), 1, "augassign")
1538+ && validate_yield_or_testlist(CHILD(tree, 2));
1539+
1540+ if (res) {
1541+ char *s = STR(CHILD(CHILD(tree, 1), 0));
1542+
1543+ res = (strcmp(s, "+=") == 0
1544+ || strcmp(s, "-=") == 0
1545+ || strcmp(s, "*=") == 0
1546+ || strcmp(s, "/=") == 0
1547+ || strcmp(s, "//=") == 0
1548+ || strcmp(s, "%=") == 0
1549+ || strcmp(s, "&=") == 0
1550+ || strcmp(s, "|=") == 0
1551+ || strcmp(s, "^=") == 0
1552+ || strcmp(s, "<<=") == 0
1553+ || strcmp(s, ">>=") == 0
1554+ || strcmp(s, "**=") == 0);
1555+ if (!res)
1556+ err_string("illegal augmmented assignment operator");
1557+ }
1558+ }
1559+ else {
1560+ for (j = 1; res && (j < nch); j += 2)
1561+ res = validate_equal(CHILD(tree, j))
1562+ && validate_yield_or_testlist(CHILD(tree, j + 1));
1563+ }
1564+ return (res);
1565+}
1566+
1567+
1568+/* print_stmt:
1569+ *
1570+ * 'print' ( [ test (',' test)* [','] ]
1571+ * | '>>' test [ (',' test)+ [','] ] )
1572+ */
1573+static int
1574+validate_print_stmt(node *tree)
1575+{
1576+ int nch = NCH(tree);
1577+ int res = (validate_ntype(tree, print_stmt)
1578+ && (nch > 0)
1579+ && validate_name(CHILD(tree, 0), "print"));
1580+
1581+ if (res && nch > 1) {
1582+ int sym = TYPE(CHILD(tree, 1));
1583+ int i = 1;
1584+ int allow_trailing_comma = 1;
1585+
1586+ if (sym == test)
1587+ res = validate_test(CHILD(tree, i++));
1588+ else {
1589+ if (nch < 3)
1590+ res = validate_numnodes(tree, 3, "print_stmt");
1591+ else {
1592+ res = (validate_ntype(CHILD(tree, i), RIGHTSHIFT)
1593+ && validate_test(CHILD(tree, i+1)));
1594+ i += 2;
1595+ allow_trailing_comma = 0;
1596+ }
1597+ }
1598+ if (res) {
1599+ /* ... (',' test)* [','] */
1600+ while (res && i+2 <= nch) {
1601+ res = (validate_comma(CHILD(tree, i))
1602+ && validate_test(CHILD(tree, i+1)));
1603+ allow_trailing_comma = 1;
1604+ i += 2;
1605+ }
1606+ if (res && !allow_trailing_comma)
1607+ res = validate_numnodes(tree, i, "print_stmt");
1608+ else if (res && i < nch)
1609+ res = validate_comma(CHILD(tree, i));
1610+ }
1611+ }
1612+ return (res);
1613+}
1614+
1615+
1616+static int
1617+validate_del_stmt(node *tree)
1618+{
1619+ return (validate_numnodes(tree, 2, "del_stmt")
1620+ && validate_name(CHILD(tree, 0), "del")
1621+ && validate_exprlist(CHILD(tree, 1)));
1622+}
1623+
1624+
1625+static int
1626+validate_return_stmt(node *tree)
1627+{
1628+ int nch = NCH(tree);
1629+ int res = (validate_ntype(tree, return_stmt)
1630+ && ((nch == 1) || (nch == 2))
1631+ && validate_name(CHILD(tree, 0), "return"));
1632+
1633+ if (res && (nch == 2))
1634+ res = validate_testlist(CHILD(tree, 1));
1635+
1636+ return (res);
1637+}
1638+
1639+
1640+static int
1641+validate_raise_stmt(node *tree)
1642+{
1643+ int nch = NCH(tree);
1644+ int res = (validate_ntype(tree, raise_stmt)
1645+ && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
1646+
1647+ if (res) {
1648+ res = validate_name(CHILD(tree, 0), "raise");
1649+ if (res && (nch >= 2))
1650+ res = validate_test(CHILD(tree, 1));
1651+ if (res && nch > 2) {
1652+ res = (validate_comma(CHILD(tree, 2))
1653+ && validate_test(CHILD(tree, 3)));
1654+ if (res && (nch > 4))
1655+ res = (validate_comma(CHILD(tree, 4))
1656+ && validate_test(CHILD(tree, 5)));
1657+ }
1658+ }
1659+ else
1660+ (void) validate_numnodes(tree, 2, "raise");
1661+ if (res && (nch == 4))
1662+ res = (validate_comma(CHILD(tree, 2))
1663+ && validate_test(CHILD(tree, 3)));
1664+
1665+ return (res);
1666+}
1667+
1668+
1669+/* yield_expr: 'yield' [testlist]
1670+ */
1671+static int
1672+validate_yield_expr(node *tree)
1673+{
1674+ int nch = NCH(tree);
1675+ int res = (validate_ntype(tree, yield_expr)
1676+ && ((nch == 1) || (nch == 2))
1677+ && validate_name(CHILD(tree, 0), "yield"));
1678+
1679+ if (res && (nch == 2))
1680+ res = validate_testlist(CHILD(tree, 1));
1681+
1682+ return (res);
1683+}
1684+
1685+
1686+/* yield_stmt: yield_expr
1687+ */
1688+static int
1689+validate_yield_stmt(node *tree)
1690+{
1691+ return (validate_ntype(tree, yield_stmt)
1692+ && validate_numnodes(tree, 1, "yield_stmt")
1693+ && validate_yield_expr(CHILD(tree, 0)));
1694+}
1695+
1696+
1697+static int
1698+validate_import_as_name(node *tree)
1699+{
1700+ int nch = NCH(tree);
1701+ int ok = validate_ntype(tree, import_as_name);
1702+
1703+ if (ok) {
1704+ if (nch == 1)
1705+ ok = validate_name(CHILD(tree, 0), NULL);
1706+ else if (nch == 3)
1707+ ok = (validate_name(CHILD(tree, 0), NULL)
1708+ && validate_name(CHILD(tree, 1), "as")
1709+ && validate_name(CHILD(tree, 2), NULL));
1710+ else
1711+ ok = validate_numnodes(tree, 3, "import_as_name");
1712+ }
1713+ return ok;
1714+}
1715+
1716+
1717+/* dotted_name: NAME ("." NAME)*
1718+ */
1719+static int
1720+validate_dotted_name(node *tree)
1721+{
1722+ int nch = NCH(tree);
1723+ int res = (validate_ntype(tree, dotted_name)
1724+ && is_odd(nch)
1725+ && validate_name(CHILD(tree, 0), NULL));
1726+ int i;
1727+
1728+ for (i = 1; res && (i < nch); i += 2) {
1729+ res = (validate_dot(CHILD(tree, i))
1730+ && validate_name(CHILD(tree, i+1), NULL));
1731+ }
1732+ return res;
1733+}
1734+
1735+
1736+/* dotted_as_name: dotted_name [NAME NAME]
1737+ */
1738+static int
1739+validate_dotted_as_name(node *tree)
1740+{
1741+ int nch = NCH(tree);
1742+ int res = validate_ntype(tree, dotted_as_name);
1743+
1744+ if (res) {
1745+ if (nch == 1)
1746+ res = validate_dotted_name(CHILD(tree, 0));
1747+ else if (nch == 3)
1748+ res = (validate_dotted_name(CHILD(tree, 0))
1749+ && validate_name(CHILD(tree, 1), "as")
1750+ && validate_name(CHILD(tree, 2), NULL));
1751+ else {
1752+ res = 0;
1753+ err_string("illegal number of children for dotted_as_name");
1754+ }
1755+ }
1756+ return res;
1757+}
1758+
1759+
1760+/* dotted_as_name (',' dotted_as_name)* */
1761+static int
1762+validate_dotted_as_names(node *tree)
1763+{
1764+ int nch = NCH(tree);
1765+ int res = is_odd(nch) && validate_dotted_as_name(CHILD(tree, 0));
1766+ int i;
1767+
1768+ for (i = 1; res && (i < nch); i += 2)
1769+ res = (validate_comma(CHILD(tree, i))
1770+ && validate_dotted_as_name(CHILD(tree, i + 1)));
1771+ return (res);
1772+}
1773+
1774+
1775+/* import_as_name (',' import_as_name)* [','] */
1776+static int
1777+validate_import_as_names(node *tree)
1778+{
1779+ int nch = NCH(tree);
1780+ int res = validate_import_as_name(CHILD(tree, 0));
1781+ int i;
1782+
1783+ for (i = 1; res && (i + 1 < nch); i += 2)
1784+ res = (validate_comma(CHILD(tree, i))
1785+ && validate_import_as_name(CHILD(tree, i + 1)));
1786+ return (res);
1787+}
1788+
1789+
1790+/* 'import' dotted_as_names */
1791+static int
1792+validate_import_name(node *tree)
1793+{
1794+ return (validate_ntype(tree, import_name)
1795+ && validate_numnodes(tree, 2, "import_name")
1796+ && validate_name(CHILD(tree, 0), "import")
1797+ && validate_dotted_as_names(CHILD(tree, 1)));
1798+}
1799+
1800+/* Helper function to count the number of leading dots in
1801+ * 'from ...module import name'
1802+ */
1803+static int
1804+count_from_dots(node *tree)
1805+{
1806+ int i;
1807+ for (i = 0; i < NCH(tree); i++)
1808+ if (TYPE(CHILD(tree, i)) != DOT)
1809+ break;
1810+ return i;
1811+}
1812+
1813+/* 'from' ('.'* dotted_name | '.') 'import' ('*' | '(' import_as_names ')' |
1814+ * import_as_names
1815+ */
1816+static int
1817+validate_import_from(node *tree)
1818+{
1819+ int nch = NCH(tree);
1820+ int ndots = count_from_dots(tree);
1821+ int havename = (TYPE(CHILD(tree, ndots + 1)) == dotted_name);
1822+ int offset = ndots + havename;
1823+ int res = validate_ntype(tree, import_from)
1824+ && (nch >= 4 + ndots)
1825+ && validate_name(CHILD(tree, 0), "from")
1826+ && (!havename || validate_dotted_name(CHILD(tree, ndots + 1)))
1827+ && validate_name(CHILD(tree, offset + 1), "import");
1828+
1829+ if (res && TYPE(CHILD(tree, offset + 2)) == LPAR)
1830+ res = ((nch == offset + 5)
1831+ && validate_lparen(CHILD(tree, offset + 2))
1832+ && validate_import_as_names(CHILD(tree, offset + 3))
1833+ && validate_rparen(CHILD(tree, offset + 4)));
1834+ else if (res && TYPE(CHILD(tree, offset + 2)) != STAR)
1835+ res = validate_import_as_names(CHILD(tree, offset + 2));
1836+ return (res);
1837+}
1838+
1839+
1840+/* import_stmt: import_name | import_from */
1841+static int
1842+validate_import_stmt(node *tree)
1843+{
1844+ int nch = NCH(tree);
1845+ int res = validate_numnodes(tree, 1, "import_stmt");
1846+
1847+ if (res) {
1848+ int ntype = TYPE(CHILD(tree, 0));
1849+
1850+ if (ntype == import_name || ntype == import_from)
1851+ res = validate_node(CHILD(tree, 0));
1852+ else {
1853+ res = 0;
1854+ err_string("illegal import_stmt child type");
1855+ }
1856+ }
1857+ else if (nch == 1) {
1858+ res = 0;
1859+ PyErr_Format(parser_error,
1860+ "Unrecognized child node of import_stmt: %d.",
1861+ TYPE(CHILD(tree, 0)));
1862+ }
1863+ return (res);
1864+}
1865+
1866+
1867+
1868+
1869+static int
1870+validate_global_stmt(node *tree)
1871+{
1872+ int j;
1873+ int nch = NCH(tree);
1874+ int res = (validate_ntype(tree, global_stmt)
1875+ && is_even(nch) && (nch >= 2));
1876+
1877+ if (!res && !PyErr_Occurred())
1878+ err_string("illegal global statement");
1879+
1880+ if (res)
1881+ res = (validate_name(CHILD(tree, 0), "global")
1882+ && validate_ntype(CHILD(tree, 1), NAME));
1883+ for (j = 2; res && (j < nch); j += 2)
1884+ res = (validate_comma(CHILD(tree, j))
1885+ && validate_ntype(CHILD(tree, j + 1), NAME));
1886+
1887+ return (res);
1888+}
1889+
1890+
1891+/* exec_stmt:
1892+ *
1893+ * 'exec' expr ['in' test [',' test]]
1894+ */
1895+static int
1896+validate_exec_stmt(node *tree)
1897+{
1898+ int nch = NCH(tree);
1899+ int res = (validate_ntype(tree, exec_stmt)
1900+ && ((nch == 2) || (nch == 4) || (nch == 6))
1901+ && validate_name(CHILD(tree, 0), "exec")
1902+ && validate_expr(CHILD(tree, 1)));
1903+
1904+ if (!res && !PyErr_Occurred())
1905+ err_string("illegal exec statement");
1906+ if (res && (nch > 2))
1907+ res = (validate_name(CHILD(tree, 2), "in")
1908+ && validate_test(CHILD(tree, 3)));
1909+ if (res && (nch == 6))
1910+ res = (validate_comma(CHILD(tree, 4))
1911+ && validate_test(CHILD(tree, 5)));
1912+
1913+ return (res);
1914+}
1915+
1916+
1917+/* assert_stmt:
1918+ *
1919+ * 'assert' test [',' test]
1920+ */
1921+static int
1922+validate_assert_stmt(node *tree)
1923+{
1924+ int nch = NCH(tree);
1925+ int res = (validate_ntype(tree, assert_stmt)
1926+ && ((nch == 2) || (nch == 4))
1927+ && (validate_name(CHILD(tree, 0), "assert"))
1928+ && validate_test(CHILD(tree, 1)));
1929+
1930+ if (!res && !PyErr_Occurred())
1931+ err_string("illegal assert statement");
1932+ if (res && (nch > 2))
1933+ res = (validate_comma(CHILD(tree, 2))
1934+ && validate_test(CHILD(tree, 3)));
1935+
1936+ return (res);
1937+}
1938+
1939+
1940+static int
1941+validate_while(node *tree)
1942+{
1943+ int nch = NCH(tree);
1944+ int res = (validate_ntype(tree, while_stmt)
1945+ && ((nch == 4) || (nch == 7))
1946+ && validate_name(CHILD(tree, 0), "while")
1947+ && validate_test(CHILD(tree, 1))
1948+ && validate_colon(CHILD(tree, 2))
1949+ && validate_suite(CHILD(tree, 3)));
1950+
1951+ if (res && (nch == 7))
1952+ res = (validate_name(CHILD(tree, 4), "else")
1953+ && validate_colon(CHILD(tree, 5))
1954+ && validate_suite(CHILD(tree, 6)));
1955+
1956+ return (res);
1957+}
1958+
1959+
1960+static int
1961+validate_for(node *tree)
1962+{
1963+ int nch = NCH(tree);
1964+ int res = (validate_ntype(tree, for_stmt)
1965+ && ((nch == 6) || (nch == 9))
1966+ && validate_name(CHILD(tree, 0), "for")
1967+ && validate_exprlist(CHILD(tree, 1))
1968+ && validate_name(CHILD(tree, 2), "in")
1969+ && validate_testlist(CHILD(tree, 3))
1970+ && validate_colon(CHILD(tree, 4))
1971+ && validate_suite(CHILD(tree, 5)));
1972+
1973+ if (res && (nch == 9))
1974+ res = (validate_name(CHILD(tree, 6), "else")
1975+ && validate_colon(CHILD(tree, 7))
1976+ && validate_suite(CHILD(tree, 8)));
1977+
1978+ return (res);
1979+}
1980+
1981+
1982+/* try_stmt:
1983+ * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1984+ * | 'try' ':' suite 'finally' ':' suite
1985+ *
1986+ */
1987+static int
1988+validate_try(node *tree)
1989+{
1990+ int nch = NCH(tree);
1991+ int pos = 3;
1992+ int res = (validate_ntype(tree, try_stmt)
1993+ && (nch >= 6) && ((nch % 3) == 0));
1994+
1995+ if (res)
1996+ res = (validate_name(CHILD(tree, 0), "try")
1997+ && validate_colon(CHILD(tree, 1))
1998+ && validate_suite(CHILD(tree, 2))
1999+ && validate_colon(CHILD(tree, nch - 2))
2000+ && validate_suite(CHILD(tree, nch - 1)));
2001+ else if (!PyErr_Occurred()) {
2002+ const char* name = "except";
2003+ if (TYPE(CHILD(tree, nch - 3)) != except_clause)
2004+ name = STR(CHILD(tree, nch - 3));
2005+
2006+ PyErr_Format(parser_error,
2007+ "Illegal number of children for try/%s node.", name);
2008+ }
2009+ /* Skip past except_clause sections: */
2010+ while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
2011+ res = (validate_except_clause(CHILD(tree, pos))
2012+ && validate_colon(CHILD(tree, pos + 1))
2013+ && validate_suite(CHILD(tree, pos + 2)));
2014+ pos += 3;
2015+ }
2016+ if (res && (pos < nch)) {
2017+ res = validate_ntype(CHILD(tree, pos), NAME);
2018+ if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
2019+ res = (validate_numnodes(tree, 6, "try/finally")
2020+ && validate_colon(CHILD(tree, 4))
2021+ && validate_suite(CHILD(tree, 5)));
2022+ else if (res) {
2023+ if (nch == (pos + 3)) {
2024+ res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
2025+ || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
2026+ if (!res)
2027+ err_string("illegal trailing triple in try statement");
2028+ }
2029+ else if (nch == (pos + 6)) {
2030+ res = (validate_name(CHILD(tree, pos), "except")
2031+ && validate_colon(CHILD(tree, pos + 1))
2032+ && validate_suite(CHILD(tree, pos + 2))
2033+ && validate_name(CHILD(tree, pos + 3), "else"));
2034+ }
2035+ else
2036+ res = validate_numnodes(tree, pos + 3, "try/except");
2037+ }
2038+ }
2039+ return (res);
2040+}
2041+
2042+
2043+static int
2044+validate_except_clause(node *tree)
2045+{
2046+ int nch = NCH(tree);
2047+ int res = (validate_ntype(tree, except_clause)
2048+ && ((nch == 1) || (nch == 2) || (nch == 4))
2049+ && validate_name(CHILD(tree, 0), "except"));
2050+
2051+ if (res && (nch > 1))
2052+ res = validate_test(CHILD(tree, 1));
2053+ if (res && (nch == 4))
2054+ res = (validate_comma(CHILD(tree, 2))
2055+ && validate_test(CHILD(tree, 3)));
2056+
2057+ return (res);
2058+}
2059+
2060+
2061+static int
2062+validate_test(node *tree)
2063+{
2064+ int nch = NCH(tree);
2065+ int res = validate_ntype(tree, test) && is_odd(nch);
2066+
2067+ if (res && (TYPE(CHILD(tree, 0)) == lambdef))
2068+ res = ((nch == 1)
2069+ && validate_lambdef(CHILD(tree, 0)));
2070+ else if (res) {
2071+ res = validate_or_test(CHILD(tree, 0));
2072+ res = (res && (nch == 1 || (nch == 5 &&
2073+ validate_name(CHILD(tree, 1), "if") &&
2074+ validate_or_test(CHILD(tree, 2)) &&
2075+ validate_name(CHILD(tree, 3), "else") &&
2076+ validate_test(CHILD(tree, 4)))));
2077+ }
2078+ return (res);
2079+}
2080+
2081+static int
2082+validate_old_test(node *tree)
2083+{
2084+ int nch = NCH(tree);
2085+ int res = validate_ntype(tree, old_test) && (nch == 1);
2086+
2087+ if (res && (TYPE(CHILD(tree, 0)) == old_lambdef))
2088+ res = (validate_old_lambdef(CHILD(tree, 0)));
2089+ else if (res) {
2090+ res = (validate_or_test(CHILD(tree, 0)));
2091+ }
2092+ return (res);
2093+}
2094+
2095+static int
2096+validate_or_test(node *tree)
2097+{
2098+ int nch = NCH(tree);
2099+ int res = validate_ntype(tree, or_test) && is_odd(nch);
2100+
2101+ if (res) {
2102+ int pos;
2103+ res = validate_and_test(CHILD(tree, 0));
2104+ for (pos = 1; res && (pos < nch); pos += 2)
2105+ res = (validate_name(CHILD(tree, pos), "or")
2106+ && validate_and_test(CHILD(tree, pos + 1)));
2107+ }
2108+ return (res);
2109+}
2110+
2111+
2112+static int
2113+validate_and_test(node *tree)
2114+{
2115+ int pos;
2116+ int nch = NCH(tree);
2117+ int res = (validate_ntype(tree, and_test)
2118+ && is_odd(nch)
2119+ && validate_not_test(CHILD(tree, 0)));
2120+
2121+ for (pos = 1; res && (pos < nch); pos += 2)
2122+ res = (validate_name(CHILD(tree, pos), "and")
2123+ && validate_not_test(CHILD(tree, 0)));
2124+
2125+ return (res);
2126+}
2127+
2128+
2129+static int
2130+validate_not_test(node *tree)
2131+{
2132+ int nch = NCH(tree);
2133+ int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
2134+
2135+ if (res) {
2136+ if (nch == 2)
2137+ res = (validate_name(CHILD(tree, 0), "not")
2138+ && validate_not_test(CHILD(tree, 1)));
2139+ else if (nch == 1)
2140+ res = validate_comparison(CHILD(tree, 0));
2141+ }
2142+ return (res);
2143+}
2144+
2145+
2146+static int
2147+validate_comparison(node *tree)
2148+{
2149+ int pos;
2150+ int nch = NCH(tree);
2151+ int res = (validate_ntype(tree, comparison)
2152+ && is_odd(nch)
2153+ && validate_expr(CHILD(tree, 0)));
2154+
2155+ for (pos = 1; res && (pos < nch); pos += 2)
2156+ res = (validate_comp_op(CHILD(tree, pos))
2157+ && validate_expr(CHILD(tree, pos + 1)));
2158+
2159+ return (res);
2160+}
2161+
2162+
2163+static int
2164+validate_comp_op(node *tree)
2165+{
2166+ int res = 0;
2167+ int nch = NCH(tree);
2168+
2169+ if (!validate_ntype(tree, comp_op))
2170+ return (0);
2171+ if (nch == 1) {
2172+ /*
2173+ * Only child will be a terminal with a well-defined symbolic name
2174+ * or a NAME with a string of either 'is' or 'in'
2175+ */
2176+ tree = CHILD(tree, 0);
2177+ switch (TYPE(tree)) {
2178+ case LESS:
2179+ case GREATER:
2180+ case EQEQUAL:
2181+ case EQUAL:
2182+ case LESSEQUAL:
2183+ case GREATEREQUAL:
2184+ case NOTEQUAL:
2185+ res = 1;
2186+ break;
2187+ case NAME:
2188+ res = ((strcmp(STR(tree), "in") == 0)
2189+ || (strcmp(STR(tree), "is") == 0));
2190+ if (!res) {
2191+ PyErr_Format(parser_error,
2192+ "illegal operator '%s'", STR(tree));
2193+ }
2194+ break;
2195+ default:
2196+ err_string("illegal comparison operator type");
2197+ break;
2198+ }
2199+ }
2200+ else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
2201+ res = (validate_ntype(CHILD(tree, 0), NAME)
2202+ && validate_ntype(CHILD(tree, 1), NAME)
2203+ && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
2204+ && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
2205+ || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
2206+ && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
2207+ if (!res && !PyErr_Occurred())
2208+ err_string("unknown comparison operator");
2209+ }
2210+ return (res);
2211+}
2212+
2213+
2214+static int
2215+validate_expr(node *tree)
2216+{
2217+ int j;
2218+ int nch = NCH(tree);
2219+ int res = (validate_ntype(tree, expr)
2220+ && is_odd(nch)
2221+ && validate_xor_expr(CHILD(tree, 0)));
2222+
2223+ for (j = 2; res && (j < nch); j += 2)
2224+ res = (validate_xor_expr(CHILD(tree, j))
2225+ && validate_vbar(CHILD(tree, j - 1)));
2226+
2227+ return (res);
2228+}
2229+
2230+
2231+static int
2232+validate_xor_expr(node *tree)
2233+{
2234+ int j;
2235+ int nch = NCH(tree);
2236+ int res = (validate_ntype(tree, xor_expr)
2237+ && is_odd(nch)
2238+ && validate_and_expr(CHILD(tree, 0)));
2239+
2240+ for (j = 2; res && (j < nch); j += 2)
2241+ res = (validate_circumflex(CHILD(tree, j - 1))
2242+ && validate_and_expr(CHILD(tree, j)));
2243+
2244+ return (res);
2245+}
2246+
2247+
2248+static int
2249+validate_and_expr(node *tree)
2250+{
2251+ int pos;
2252+ int nch = NCH(tree);
2253+ int res = (validate_ntype(tree, and_expr)
2254+ && is_odd(nch)
2255+ && validate_shift_expr(CHILD(tree, 0)));
2256+
2257+ for (pos = 1; res && (pos < nch); pos += 2)
2258+ res = (validate_ampersand(CHILD(tree, pos))
2259+ && validate_shift_expr(CHILD(tree, pos + 1)));
2260+
2261+ return (res);
2262+}
2263+
2264+
2265+static int
2266+validate_chain_two_ops(node *tree, int (*termvalid)(node *), int op1, int op2)
2267+ {
2268+ int pos = 1;
2269+ int nch = NCH(tree);
2270+ int res = (is_odd(nch)
2271+ && (*termvalid)(CHILD(tree, 0)));
2272+
2273+ for ( ; res && (pos < nch); pos += 2) {
2274+ if (TYPE(CHILD(tree, pos)) != op1)
2275+ res = validate_ntype(CHILD(tree, pos), op2);
2276+ if (res)
2277+ res = (*termvalid)(CHILD(tree, pos + 1));
2278+ }
2279+ return (res);
2280+}
2281+
2282+
2283+static int
2284+validate_shift_expr(node *tree)
2285+{
2286+ return (validate_ntype(tree, shift_expr)
2287+ && validate_chain_two_ops(tree, validate_arith_expr,
2288+ LEFTSHIFT, RIGHTSHIFT));
2289+}
2290+
2291+
2292+static int
2293+validate_arith_expr(node *tree)
2294+{
2295+ return (validate_ntype(tree, arith_expr)
2296+ && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
2297+}
2298+
2299+
2300+static int
2301+validate_term(node *tree)
2302+{
2303+ int pos = 1;
2304+ int nch = NCH(tree);
2305+ int res = (validate_ntype(tree, term)
2306+ && is_odd(nch)
2307+ && validate_factor(CHILD(tree, 0)));
2308+
2309+ for ( ; res && (pos < nch); pos += 2)
2310+ res = (((TYPE(CHILD(tree, pos)) == STAR)
2311+ || (TYPE(CHILD(tree, pos)) == SLASH)
2312+ || (TYPE(CHILD(tree, pos)) == DOUBLESLASH)
2313+ || (TYPE(CHILD(tree, pos)) == PERCENT))
2314+ && validate_factor(CHILD(tree, pos + 1)));
2315+
2316+ return (res);
2317+}
2318+
2319+
2320+/* factor:
2321+ *
2322+ * factor: ('+'|'-'|'~') factor | power
2323+ */
2324+static int
2325+validate_factor(node *tree)
2326+{
2327+ int nch = NCH(tree);
2328+ int res = (validate_ntype(tree, factor)
2329+ && (((nch == 2)
2330+ && ((TYPE(CHILD(tree, 0)) == PLUS)
2331+ || (TYPE(CHILD(tree, 0)) == MINUS)
2332+ || (TYPE(CHILD(tree, 0)) == TILDE))
2333+ && validate_factor(CHILD(tree, 1)))
2334+ || ((nch == 1)
2335+ && validate_power(CHILD(tree, 0)))));
2336+ return (res);
2337+}
2338+
2339+
2340+/* power:
2341+ *
2342+ * power: atom trailer* ('**' factor)*
2343+ */
2344+static int
2345+validate_power(node *tree)
2346+{
2347+ int pos = 1;
2348+ int nch = NCH(tree);
2349+ int res = (validate_ntype(tree, power) && (nch >= 1)
2350+ && validate_atom(CHILD(tree, 0)));
2351+
2352+ while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2353+ res = validate_trailer(CHILD(tree, pos++));
2354+ if (res && (pos < nch)) {
2355+ if (!is_even(nch - pos)) {
2356+ err_string("illegal number of nodes for 'power'");
2357+ return (0);
2358+ }
2359+ for ( ; res && (pos < (nch - 1)); pos += 2)
2360+ res = (validate_doublestar(CHILD(tree, pos))
2361+ && validate_factor(CHILD(tree, pos + 1)));
2362+ }
2363+ return (res);
2364+}
2365+
2366+
2367+static int
2368+validate_atom(node *tree)
2369+{
2370+ int pos;
2371+ int nch = NCH(tree);
2372+ int res = validate_ntype(tree, atom);
2373+
2374+ if (res && nch < 1)
2375+ res = validate_numnodes(tree, nch+1, "atom");
2376+ if (res) {
2377+ switch (TYPE(CHILD(tree, 0))) {
2378+ case LPAR:
2379+ res = ((nch <= 3)
2380+ && (validate_rparen(CHILD(tree, nch - 1))));
2381+
2382+ if (res && (nch == 3)) {
2383+ if (TYPE(CHILD(tree, 1))==yield_expr)
2384+ res = validate_yield_expr(CHILD(tree, 1));
2385+ else
2386+ res = validate_testlist_gexp(CHILD(tree, 1));
2387+ }
2388+ break;
2389+ case LSQB:
2390+ if (nch == 2)
2391+ res = validate_ntype(CHILD(tree, 1), RSQB);
2392+ else if (nch == 3)
2393+ res = (validate_listmaker(CHILD(tree, 1))
2394+ && validate_ntype(CHILD(tree, 2), RSQB));
2395+ else {
2396+ res = 0;
2397+ err_string("illegal list display atom");
2398+ }
2399+ break;
2400+ case LBRACE:
2401+ res = ((nch <= 3)
2402+ && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2403+
2404+ if (res && (nch == 3))
2405+ res = validate_dictmaker(CHILD(tree, 1));
2406+ break;
2407+ case BACKQUOTE:
2408+ res = ((nch == 3)
2409+ && validate_testlist1(CHILD(tree, 1))
2410+ && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2411+ break;
2412+ case NAME:
2413+ case NUMBER:
2414+ res = (nch == 1);
2415+ break;
2416+ case STRING:
2417+ for (pos = 1; res && (pos < nch); ++pos)
2418+ res = validate_ntype(CHILD(tree, pos), STRING);
2419+ break;
2420+ default:
2421+ res = 0;
2422+ break;
2423+ }
2424+ }
2425+ return (res);
2426+}
2427+
2428+
2429+/* listmaker:
2430+ * test ( list_for | (',' test)* [','] )
2431+ */
2432+static int
2433+validate_listmaker(node *tree)
2434+{
2435+ int nch = NCH(tree);
2436+ int ok = nch;
2437+
2438+ if (nch == 0)
2439+ err_string("missing child nodes of listmaker");
2440+ else
2441+ ok = validate_test(CHILD(tree, 0));
2442+
2443+ /*
2444+ * list_for | (',' test)* [',']
2445+ */
2446+ if (nch == 2 && TYPE(CHILD(tree, 1)) == list_for)
2447+ ok = validate_list_for(CHILD(tree, 1));
2448+ else {
2449+ /* (',' test)* [','] */
2450+ int i = 1;
2451+ while (ok && nch - i >= 2) {
2452+ ok = (validate_comma(CHILD(tree, i))
2453+ && validate_test(CHILD(tree, i+1)));
2454+ i += 2;
2455+ }
2456+ if (ok && i == nch-1)
2457+ ok = validate_comma(CHILD(tree, i));
2458+ else if (i != nch) {
2459+ ok = 0;
2460+ err_string("illegal trailing nodes for listmaker");
2461+ }
2462+ }
2463+ return ok;
2464+}
2465+
2466+/* testlist_gexp:
2467+ * test ( gen_for | (',' test)* [','] )
2468+ */
2469+static int
2470+validate_testlist_gexp(node *tree)
2471+{
2472+ int nch = NCH(tree);
2473+ int ok = nch;
2474+
2475+ if (nch == 0)
2476+ err_string("missing child nodes of testlist_gexp");
2477+ else {
2478+ ok = validate_test(CHILD(tree, 0));
2479+ }
2480+
2481+ /*
2482+ * gen_for | (',' test)* [',']
2483+ */
2484+ if (nch == 2 && TYPE(CHILD(tree, 1)) == gen_for)
2485+ ok = validate_gen_for(CHILD(tree, 1));
2486+ else {
2487+ /* (',' test)* [','] */
2488+ int i = 1;
2489+ while (ok && nch - i >= 2) {
2490+ ok = (validate_comma(CHILD(tree, i))
2491+ && validate_test(CHILD(tree, i+1)));
2492+ i += 2;
2493+ }
2494+ if (ok && i == nch-1)
2495+ ok = validate_comma(CHILD(tree, i));
2496+ else if (i != nch) {
2497+ ok = 0;
2498+ err_string("illegal trailing nodes for testlist_gexp");
2499+ }
2500+ }
2501+ return ok;
2502+}
2503+
2504+/* decorator:
2505+ * '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
2506+ */
2507+static int
2508+validate_decorator(node *tree)
2509+{
2510+ int ok;
2511+ int nch = NCH(tree);
2512+ ok = (validate_ntype(tree, decorator) &&
2513+ (nch == 3 || nch == 5 || nch == 6) &&
2514+ validate_at(CHILD(tree, 0)) &&
2515+ validate_dotted_name(CHILD(tree, 1)) &&
2516+ validate_newline(RCHILD(tree, -1)));
2517+
2518+ if (ok && nch != 3) {
2519+ ok = (validate_lparen(CHILD(tree, 2)) &&
2520+ validate_rparen(RCHILD(tree, -2)));
2521+
2522+ if (ok && nch == 6)
2523+ ok = validate_arglist(CHILD(tree, 3));
2524+ }
2525+
2526+ return ok;
2527+}
2528+
2529+/* decorators:
2530+ * decorator+
2531+ */
2532+static int
2533+validate_decorators(node *tree)
2534+{
2535+ int i, nch, ok;
2536+ nch = NCH(tree);
2537+ ok = validate_ntype(tree, decorators) && nch >= 1;
2538+
2539+ for (i = 0; ok && i < nch; ++i)
2540+ ok = validate_decorator(CHILD(tree, i));
2541+
2542+ return ok;
2543+}
2544+
2545+/* funcdef:
2546+ *
2547+ * -6 -5 -4 -3 -2 -1
2548+ * [decorators] 'def' NAME parameters ':' suite
2549+ */
2550+static int
2551+validate_funcdef(node *tree)
2552+{
2553+ int nch = NCH(tree);
2554+ int ok = (validate_ntype(tree, funcdef)
2555+ && ((nch == 5) || (nch == 6))
2556+ && validate_name(RCHILD(tree, -5), "def")
2557+ && validate_ntype(RCHILD(tree, -4), NAME)
2558+ && validate_colon(RCHILD(tree, -2))
2559+ && validate_parameters(RCHILD(tree, -3))
2560+ && validate_suite(RCHILD(tree, -1)));
2561+
2562+ if (ok && (nch == 6))
2563+ ok = validate_decorators(CHILD(tree, 0));
2564+
2565+ return ok;
2566+}
2567+
2568+
2569+static int
2570+validate_lambdef(node *tree)
2571+{
2572+ int nch = NCH(tree);
2573+ int res = (validate_ntype(tree, lambdef)
2574+ && ((nch == 3) || (nch == 4))
2575+ && validate_name(CHILD(tree, 0), "lambda")
2576+ && validate_colon(CHILD(tree, nch - 2))
2577+ && validate_test(CHILD(tree, nch - 1)));
2578+
2579+ if (res && (nch == 4))
2580+ res = validate_varargslist(CHILD(tree, 1));
2581+ else if (!res && !PyErr_Occurred())
2582+ (void) validate_numnodes(tree, 3, "lambdef");
2583+
2584+ return (res);
2585+}
2586+
2587+
2588+static int
2589+validate_old_lambdef(node *tree)
2590+{
2591+ int nch = NCH(tree);
2592+ int res = (validate_ntype(tree, old_lambdef)
2593+ && ((nch == 3) || (nch == 4))
2594+ && validate_name(CHILD(tree, 0), "lambda")
2595+ && validate_colon(CHILD(tree, nch - 2))
2596+ && validate_test(CHILD(tree, nch - 1)));
2597+
2598+ if (res && (nch == 4))
2599+ res = validate_varargslist(CHILD(tree, 1));
2600+ else if (!res && !PyErr_Occurred())
2601+ (void) validate_numnodes(tree, 3, "old_lambdef");
2602+
2603+ return (res);
2604+}
2605+
2606+
2607+/* arglist:
2608+ *
2609+ * (argument ',')* (argument [','] | '*' test [',' '**' test] | '**' test)
2610+ */
2611+static int
2612+validate_arglist(node *tree)
2613+{
2614+ int nch = NCH(tree);
2615+ int i = 0;
2616+ int ok = 1;
2617+
2618+ if (nch <= 0)
2619+ /* raise the right error from having an invalid number of children */
2620+ return validate_numnodes(tree, nch + 1, "arglist");
2621+
2622+ if (nch > 1) {
2623+ for (i=0; i<nch; i++) {
2624+ if (TYPE(CHILD(tree, i)) == argument) {
2625+ node *ch = CHILD(tree, i);
2626+ if (NCH(ch) == 2 && TYPE(CHILD(ch, 1)) == gen_for) {
2627+ err_string("need '(', ')' for generator expression");
2628+ return 0;
2629+ }
2630+ }
2631+ }
2632+ }
2633+
2634+ while (ok && nch-i >= 2) {
2635+ /* skip leading (argument ',') */
2636+ ok = (validate_argument(CHILD(tree, i))
2637+ && validate_comma(CHILD(tree, i+1)));
2638+ if (ok)
2639+ i += 2;
2640+ else
2641+ PyErr_Clear();
2642+ }
2643+ ok = 1;
2644+ if (nch-i > 0) {
2645+ /*
2646+ * argument | '*' test [',' '**' test] | '**' test
2647+ */
2648+ int sym = TYPE(CHILD(tree, i));
2649+
2650+ if (sym == argument) {
2651+ ok = validate_argument(CHILD(tree, i));
2652+ if (ok && i+1 != nch) {
2653+ err_string("illegal arglist specification"
2654+ " (extra stuff on end)");
2655+ ok = 0;
2656+ }
2657+ }
2658+ else if (sym == STAR) {
2659+ ok = validate_star(CHILD(tree, i));
2660+ if (ok && (nch-i == 2))
2661+ ok = validate_test(CHILD(tree, i+1));
2662+ else if (ok && (nch-i == 5))
2663+ ok = (validate_test(CHILD(tree, i+1))
2664+ && validate_comma(CHILD(tree, i+2))
2665+ && validate_doublestar(CHILD(tree, i+3))
2666+ && validate_test(CHILD(tree, i+4)));
2667+ else {
2668+ err_string("illegal use of '*' in arglist");
2669+ ok = 0;
2670+ }
2671+ }
2672+ else if (sym == DOUBLESTAR) {
2673+ if (nch-i == 2)
2674+ ok = (validate_doublestar(CHILD(tree, i))
2675+ && validate_test(CHILD(tree, i+1)));
2676+ else {
2677+ err_string("illegal use of '**' in arglist");
2678+ ok = 0;
2679+ }
2680+ }
2681+ else {
2682+ err_string("illegal arglist specification");
2683+ ok = 0;
2684+ }
2685+ }
2686+ return (ok);
2687+}
2688+
2689+
2690+
2691+/* argument:
2692+ *
2693+ * [test '='] test [gen_for]
2694+ */
2695+static int
2696+validate_argument(node *tree)
2697+{
2698+ int nch = NCH(tree);
2699+ int res = (validate_ntype(tree, argument)
2700+ && ((nch == 1) || (nch == 2) || (nch == 3))
2701+ && validate_test(CHILD(tree, 0)));
2702+
2703+ if (res && (nch == 2))
2704+ res = validate_gen_for(CHILD(tree, 1));
2705+ else if (res && (nch == 3))
2706+ res = (validate_equal(CHILD(tree, 1))
2707+ && validate_test(CHILD(tree, 2)));
2708+
2709+ return (res);
2710+}
2711+
2712+
2713+
2714+/* trailer:
2715+ *
2716+ * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
2717+ */
2718+static int
2719+validate_trailer(node *tree)
2720+{
2721+ int nch = NCH(tree);
2722+ int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
2723+
2724+ if (res) {
2725+ switch (TYPE(CHILD(tree, 0))) {
2726+ case LPAR:
2727+ res = validate_rparen(CHILD(tree, nch - 1));
2728+ if (res && (nch == 3))
2729+ res = validate_arglist(CHILD(tree, 1));
2730+ break;
2731+ case LSQB:
2732+ res = (validate_numnodes(tree, 3, "trailer")
2733+ && validate_subscriptlist(CHILD(tree, 1))
2734+ && validate_ntype(CHILD(tree, 2), RSQB));
2735+ break;
2736+ case DOT:
2737+ res = (validate_numnodes(tree, 2, "trailer")
2738+ && validate_ntype(CHILD(tree, 1), NAME));
2739+ break;
2740+ default:
2741+ res = 0;
2742+ break;
2743+ }
2744+ }
2745+ else {
2746+ (void) validate_numnodes(tree, 2, "trailer");
2747+ }
2748+ return (res);
2749+}
2750+
2751+
2752+/* subscriptlist:
2753+ *
2754+ * subscript (',' subscript)* [',']
2755+ */
2756+static int
2757+validate_subscriptlist(node *tree)
2758+{
2759+ return (validate_repeating_list(tree, subscriptlist,
2760+ validate_subscript, "subscriptlist"));
2761+}
2762+
2763+
2764+/* subscript:
2765+ *
2766+ * '.' '.' '.' | test | [test] ':' [test] [sliceop]
2767+ */
2768+static int
2769+validate_subscript(node *tree)
2770+{
2771+ int offset = 0;
2772+ int nch = NCH(tree);
2773+ int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
2774+
2775+ if (!res) {
2776+ if (!PyErr_Occurred())
2777+ err_string("invalid number of arguments for subscript node");
2778+ return (0);
2779+ }
2780+ if (TYPE(CHILD(tree, 0)) == DOT)
2781+ /* take care of ('.' '.' '.') possibility */
2782+ return (validate_numnodes(tree, 3, "subscript")
2783+ && validate_dot(CHILD(tree, 0))
2784+ && validate_dot(CHILD(tree, 1))
2785+ && validate_dot(CHILD(tree, 2)));
2786+ if (nch == 1) {
2787+ if (TYPE(CHILD(tree, 0)) == test)
2788+ res = validate_test(CHILD(tree, 0));
2789+ else
2790+ res = validate_colon(CHILD(tree, 0));
2791+ return (res);
2792+ }
2793+ /* Must be [test] ':' [test] [sliceop],
2794+ * but at least one of the optional components will
2795+ * be present, but we don't know which yet.
2796+ */
2797+ if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2798+ res = validate_test(CHILD(tree, 0));
2799+ offset = 1;
2800+ }
2801+ if (res)
2802+ res = validate_colon(CHILD(tree, offset));
2803+ if (res) {
2804+ int rem = nch - ++offset;
2805+ if (rem) {
2806+ if (TYPE(CHILD(tree, offset)) == test) {
2807+ res = validate_test(CHILD(tree, offset));
2808+ ++offset;
2809+ --rem;
2810+ }
2811+ if (res && rem)
2812+ res = validate_sliceop(CHILD(tree, offset));
2813+ }
2814+ }
2815+ return (res);
2816+}
2817+
2818+
2819+static int
2820+validate_sliceop(node *tree)
2821+{
2822+ int nch = NCH(tree);
2823+ int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2824+ && validate_ntype(tree, sliceop);
2825+ if (!res && !PyErr_Occurred()) {
2826+ res = validate_numnodes(tree, 1, "sliceop");
2827+ }
2828+ if (res)
2829+ res = validate_colon(CHILD(tree, 0));
2830+ if (res && (nch == 2))
2831+ res = validate_test(CHILD(tree, 1));
2832+
2833+ return (res);
2834+}
2835+
2836+
2837+static int
2838+validate_exprlist(node *tree)
2839+{
2840+ return (validate_repeating_list(tree, exprlist,
2841+ validate_expr, "exprlist"));
2842+}
2843+
2844+
2845+static int
2846+validate_dictmaker(node *tree)
2847+{
2848+ int nch = NCH(tree);
2849+ int res = (validate_ntype(tree, dictmaker)
2850+ && (nch >= 3)
2851+ && validate_test(CHILD(tree, 0))
2852+ && validate_colon(CHILD(tree, 1))
2853+ && validate_test(CHILD(tree, 2)));
2854+
2855+ if (res && ((nch % 4) == 0))
2856+ res = validate_comma(CHILD(tree, --nch));
2857+ else if (res)
2858+ res = ((nch % 4) == 3);
2859+
2860+ if (res && (nch > 3)) {
2861+ int pos = 3;
2862+ /* ( ',' test ':' test )* */
2863+ while (res && (pos < nch)) {
2864+ res = (validate_comma(CHILD(tree, pos))
2865+ && validate_test(CHILD(tree, pos + 1))
2866+ && validate_colon(CHILD(tree, pos + 2))
2867+ && validate_test(CHILD(tree, pos + 3)));
2868+ pos += 4;
2869+ }
2870+ }
2871+ return (res);
2872+}
2873+
2874+
2875+static int
2876+validate_eval_input(node *tree)
2877+{
2878+ int pos;
2879+ int nch = NCH(tree);
2880+ int res = (validate_ntype(tree, eval_input)
2881+ && (nch >= 2)
2882+ && validate_testlist(CHILD(tree, 0))
2883+ && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2884+
2885+ for (pos = 1; res && (pos < (nch - 1)); ++pos)
2886+ res = validate_ntype(CHILD(tree, pos), NEWLINE);
2887+
2888+ return (res);
2889+}
2890+
2891+
2892+static int
2893+validate_node(node *tree)
2894+{
2895+ int nch = 0; /* num. children on current node */
2896+ int res = 1; /* result value */
2897+ node* next = 0; /* node to process after this one */
2898+
2899+ while (res && (tree != 0)) {
2900+ nch = NCH(tree);
2901+ next = 0;
2902+ switch (TYPE(tree)) {
2903+ /*
2904+ * Definition nodes.
2905+ */
2906+ case funcdef:
2907+ res = validate_funcdef(tree);
2908+ break;
2909+ case classdef:
2910+ res = validate_class(tree);
2911+ break;
2912+ /*
2913+ * "Trivial" parse tree nodes.
2914+ * (Why did I call these trivial?)
2915+ */
2916+ case stmt:
2917+ res = validate_stmt(tree);
2918+ break;
2919+ case small_stmt:
2920+ /*
2921+ * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
2922+ * | import_stmt | global_stmt | exec_stmt | assert_stmt
2923+ */
2924+ res = validate_small_stmt(tree);
2925+ break;
2926+ case flow_stmt:
2927+ res = (validate_numnodes(tree, 1, "flow_stmt")
2928+ && ((TYPE(CHILD(tree, 0)) == break_stmt)
2929+ || (TYPE(CHILD(tree, 0)) == continue_stmt)
2930+ || (TYPE(CHILD(tree, 0)) == yield_stmt)
2931+ || (TYPE(CHILD(tree, 0)) == return_stmt)
2932+ || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2933+ if (res)
2934+ next = CHILD(tree, 0);
2935+ else if (nch == 1)
2936+ err_string("illegal flow_stmt type");
2937+ break;
2938+ case yield_stmt:
2939+ res = validate_yield_stmt(tree);
2940+ break;
2941+ /*
2942+ * Compound statements.
2943+ */
2944+ case simple_stmt:
2945+ res = validate_simple_stmt(tree);
2946+ break;
2947+ case compound_stmt:
2948+ res = validate_compound_stmt(tree);
2949+ break;
2950+ /*
2951+ * Fundamental statements.
2952+ */
2953+ case expr_stmt:
2954+ res = validate_expr_stmt(tree);
2955+ break;
2956+ case print_stmt:
2957+ res = validate_print_stmt(tree);
2958+ break;
2959+ case del_stmt:
2960+ res = validate_del_stmt(tree);
2961+ break;
2962+ case pass_stmt:
2963+ res = (validate_numnodes(tree, 1, "pass")
2964+ && validate_name(CHILD(tree, 0), "pass"));
2965+ break;
2966+ case break_stmt:
2967+ res = (validate_numnodes(tree, 1, "break")
2968+ && validate_name(CHILD(tree, 0), "break"));
2969+ break;
2970+ case continue_stmt:
2971+ res = (validate_numnodes(tree, 1, "continue")
2972+ && validate_name(CHILD(tree, 0), "continue"));
2973+ break;
2974+ case return_stmt:
2975+ res = validate_return_stmt(tree);
2976+ break;
2977+ case raise_stmt:
2978+ res = validate_raise_stmt(tree);
2979+ break;
2980+ case import_stmt:
2981+ res = validate_import_stmt(tree);
2982+ break;
2983+ case import_name:
2984+ res = validate_import_name(tree);
2985+ break;
2986+ case import_from:
2987+ res = validate_import_from(tree);
2988+ break;
2989+ case global_stmt:
2990+ res = validate_global_stmt(tree);
2991+ break;
2992+ case exec_stmt:
2993+ res = validate_exec_stmt(tree);
2994+ break;
2995+ case assert_stmt:
2996+ res = validate_assert_stmt(tree);
2997+ break;
2998+ case if_stmt:
2999+ res = validate_if(tree);
3000+ break;
3001+ case while_stmt:
3002+ res = validate_while(tree);
3003+ break;
3004+ case for_stmt:
3005+ res = validate_for(tree);
3006+ break;
3007+ case try_stmt:
3008+ res = validate_try(tree);
3009+ break;
3010+ case suite:
3011+ res = validate_suite(tree);
3012+ break;
3013+ /*
3014+ * Expression nodes.
3015+ */
3016+ case testlist:
3017+ res = validate_testlist(tree);
3018+ break;
3019+ case yield_expr:
3020+ res = validate_yield_expr(tree);
3021+ break;
3022+ case testlist1:
3023+ res = validate_testlist1(tree);
3024+ break;
3025+ case test:
3026+ res = validate_test(tree);
3027+ break;
3028+ case and_test:
3029+ res = validate_and_test(tree);
3030+ break;
3031+ case not_test:
3032+ res = validate_not_test(tree);
3033+ break;
3034+ case comparison:
3035+ res = validate_comparison(tree);
3036+ break;
3037+ case exprlist:
3038+ res = validate_exprlist(tree);
3039+ break;
3040+ case comp_op:
3041+ res = validate_comp_op(tree);
3042+ break;
3043+ case expr:
3044+ res = validate_expr(tree);
3045+ break;
3046+ case xor_expr:
3047+ res = validate_xor_expr(tree);
3048+ break;
3049+ case and_expr:
3050+ res = validate_and_expr(tree);
3051+ break;
3052+ case shift_expr:
3053+ res = validate_shift_expr(tree);
3054+ break;
3055+ case arith_expr:
3056+ res = validate_arith_expr(tree);
3057+ break;
3058+ case term:
3059+ res = validate_term(tree);
3060+ break;
3061+ case factor:
3062+ res = validate_factor(tree);
3063+ break;
3064+ case power:
3065+ res = validate_power(tree);
3066+ break;
3067+ case atom:
3068+ res = validate_atom(tree);
3069+ break;
3070+
3071+ default:
3072+ /* Hopefully never reached! */
3073+ err_string("unrecognized node type");
3074+ res = 0;
3075+ break;
3076+ }
3077+ tree = next;
3078+ }
3079+ return (res);
3080+}
3081+
3082+
3083+static int
3084+validate_expr_tree(node *tree)
3085+{
3086+ int res = validate_eval_input(tree);
3087+
3088+ if (!res && !PyErr_Occurred())
3089+ err_string("could not validate expression tuple");
3090+
3091+ return (res);
3092+}
3093+
3094+
3095+/* file_input:
3096+ * (NEWLINE | stmt)* ENDMARKER
3097+ */
3098+static int
3099+validate_file_input(node *tree)
3100+{
3101+ int j;
3102+ int nch = NCH(tree) - 1;
3103+ int res = ((nch >= 0)
3104+ && validate_ntype(CHILD(tree, nch), ENDMARKER));
3105+
3106+ for (j = 0; res && (j < nch); ++j) {
3107+ if (TYPE(CHILD(tree, j)) == stmt)
3108+ res = validate_stmt(CHILD(tree, j));
3109+ else
3110+ res = validate_newline(CHILD(tree, j));
3111+ }
3112+ /* This stays in to prevent any internal failures from getting to the
3113+ * user. Hopefully, this won't be needed. If a user reports getting
3114+ * this, we have some debugging to do.
3115+ */
3116+ if (!res && !PyErr_Occurred())
3117+ err_string("VALIDATION FAILURE: report this to the maintainer!");
3118+
3119+ return (res);
3120+}
3121+
3122+static int
3123+validate_encoding_decl(node *tree)
3124+{
3125+ int nch = NCH(tree);
3126+ int res = ((nch == 1)
3127+ && validate_file_input(CHILD(tree, 0)));
3128+
3129+ if (!res && !PyErr_Occurred())
3130+ err_string("Error Parsing encoding_decl");
3131+
3132+ return res;
3133+}
3134+
3135+static PyObject*
3136+pickle_constructor = NULL;
3137+
3138+
3139+static PyObject*
3140+parser__pickler(PyObject *self, PyObject *args)
3141+{
3142+ NOTE(ARGUNUSED(self))
3143+ PyObject *result = NULL;
3144+ PyObject *st = NULL;
3145+ PyObject *empty_dict = NULL;
3146+
3147+ if (PyArg_ParseTuple(args, "O!:_pickler", &PyST_Type, &st)) {
3148+ PyObject *newargs;
3149+ PyObject *tuple;
3150+
3151+ if ((empty_dict = PyDict_New()) == NULL)
3152+ goto finally;
3153+ if ((newargs = Py_BuildValue("Oi", st, 1)) == NULL)
3154+ goto finally;
3155+ tuple = parser_st2tuple((PyST_Object*)NULL, newargs, empty_dict);
3156+ if (tuple != NULL) {
3157+ result = Py_BuildValue("O(O)", pickle_constructor, tuple);
3158+ Py_DECREF(tuple);
3159+ }
3160+ Py_DECREF(empty_dict);
3161+ Py_DECREF(newargs);
3162+ }
3163+ finally:
3164+ Py_XDECREF(empty_dict);
3165+
3166+ return (result);
3167+}
3168+
3169+
3170+/* Functions exported by this module. Most of this should probably
3171+ * be converted into an ST object with methods, but that is better
3172+ * done directly in Python, allowing subclasses to be created directly.
3173+ * We'd really have to write a wrapper around it all anyway to allow
3174+ * inheritance.
3175+ */
3176+static PyMethodDef parser_functions[] = {
3177+ {"ast2tuple", (PyCFunction)parser_st2tuple, PUBLIC_METHOD_TYPE,
3178+ PyDoc_STR("Creates a tuple-tree representation of an ST.")},
3179+ {"ast2list", (PyCFunction)parser_st2list, PUBLIC_METHOD_TYPE,
3180+ PyDoc_STR("Creates a list-tree representation of an ST.")},
3181+ {"compileast", (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE,
3182+ PyDoc_STR("Compiles an ST object into a code object.")},
3183+ {"compilest", (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE,
3184+ PyDoc_STR("Compiles an ST object into a code object.")},
3185+ {"expr", (PyCFunction)parser_expr, PUBLIC_METHOD_TYPE,
3186+ PyDoc_STR("Creates an ST object from an expression.")},
3187+ {"isexpr", (PyCFunction)parser_isexpr, PUBLIC_METHOD_TYPE,
3188+ PyDoc_STR("Determines if an ST object was created from an expression.")},
3189+ {"issuite", (PyCFunction)parser_issuite, PUBLIC_METHOD_TYPE,
3190+ PyDoc_STR("Determines if an ST object was created from a suite.")},
3191+ {"suite", (PyCFunction)parser_suite, PUBLIC_METHOD_TYPE,
3192+ PyDoc_STR("Creates an ST object from a suite.")},
3193+ {"sequence2ast", (PyCFunction)parser_tuple2st, PUBLIC_METHOD_TYPE,
3194+ PyDoc_STR("Creates an ST object from a tree representation.")},
3195+ {"sequence2st", (PyCFunction)parser_tuple2st, PUBLIC_METHOD_TYPE,
3196+ PyDoc_STR("Creates an ST object from a tree representation.")},
3197+ {"st2tuple", (PyCFunction)parser_st2tuple, PUBLIC_METHOD_TYPE,
3198+ PyDoc_STR("Creates a tuple-tree representation of an ST.")},
3199+ {"st2list", (PyCFunction)parser_st2list, PUBLIC_METHOD_TYPE,
3200+ PyDoc_STR("Creates a list-tree representation of an ST.")},
3201+ {"tuple2ast", (PyCFunction)parser_tuple2st, PUBLIC_METHOD_TYPE,
3202+ PyDoc_STR("Creates an ST object from a tree representation.")},
3203+ {"tuple2st", (PyCFunction)parser_tuple2st, PUBLIC_METHOD_TYPE,
3204+ PyDoc_STR("Creates an ST object from a tree representation.")},
3205+
3206+ /* private stuff: support pickle module */
3207+ {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS,
3208+ PyDoc_STR("Returns the pickle magic to allow ST objects to be pickled.")},
3209+
3210+ {NULL, NULL, 0, NULL}
3211+ };
3212+
3213+
3214+PyMODINIT_FUNC initparser(void); /* supply a prototype */
3215+
3216+PyMODINIT_FUNC
3217+initparser(void)
3218+{
3219+ PyObject *module, *copyreg;
3220+
3221+ PyST_Type.ob_type = &PyType_Type;
3222+ module = Py_InitModule("parser", parser_functions);
3223+ if (module == NULL)
3224+ return;
3225+
3226+ if (parser_error == 0)
3227+ parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
3228+
3229+ if (parser_error == 0)
3230+ /* caller will check PyErr_Occurred() */
3231+ return;
3232+ /* CAUTION: The code next used to skip bumping the refcount on
3233+ * parser_error. That's a disaster if initparser() gets called more
3234+ * than once. By incref'ing, we ensure that each module dict that
3235+ * gets created owns its reference to the shared parser_error object,
3236+ * and the file static parser_error vrbl owns a reference too.
3237+ */
3238+ Py_INCREF(parser_error);
3239+ if (PyModule_AddObject(module, "ParserError", parser_error) != 0)
3240+ return;
3241+
3242+ Py_INCREF(&PyST_Type);
3243+ PyModule_AddObject(module, "ASTType", (PyObject*)&PyST_Type);
3244+ Py_INCREF(&PyST_Type);
3245+ PyModule_AddObject(module, "STType", (PyObject*)&PyST_Type);
3246+
3247+ PyModule_AddStringConstant(module, "__copyright__",
3248+ parser_copyright_string);
3249+ PyModule_AddStringConstant(module, "__doc__",
3250+ parser_doc_string);
3251+ PyModule_AddStringConstant(module, "__version__",
3252+ parser_version_string);
3253+
3254+ /* Register to support pickling.
3255+ * If this fails, the import of this module will fail because an
3256+ * exception will be raised here; should we clear the exception?
3257+ */
3258+ copyreg = PyImport_ImportModule("copy_reg");
3259+ if (copyreg != NULL) {
3260+ PyObject *func, *pickler;
3261+
3262+ func = PyObject_GetAttrString(copyreg, "pickle");
3263+ pickle_constructor = PyObject_GetAttrString(module, "sequence2st");
3264+ pickler = PyObject_GetAttrString(module, "_pickler");
3265+ Py_XINCREF(pickle_constructor);
3266+ if ((func != NULL) && (pickle_constructor != NULL)
3267+ && (pickler != NULL)) {
3268+ PyObject *res;
3269+
3270+ res = PyObject_CallFunctionObjArgs(func, &PyST_Type, pickler,
3271+ pickle_constructor, NULL);
3272+ Py_XDECREF(res);
3273+ }
3274+ Py_XDECREF(func);
3275+ Py_XDECREF(pickle_constructor);
3276+ Py_XDECREF(pickler);
3277+ Py_DECREF(copyreg);
3278+ }
3279+}