Improved some error messages for command line processing.
[python/dscho.git] / Modules / parsermodule.c
blobcd8381ca50d5ad512ebe5c4271a7158fa984d681
1 /* parsermodule.c
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.
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.
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.
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(...)".
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 "token.h" /* token definitions */
32 /* ISTERMINAL() / ISNONTERMINAL() */
33 #include "compile.h" /* PyNode_Compile() */
35 #ifdef lint
36 #include <note.h>
37 #else
38 #define NOTE(x)
39 #endif
41 #ifdef macintosh
42 char *strdup Py_PROTO((char *));
43 #endif
45 /* String constants used to initialize module attributes.
48 static char*
49 parser_copyright_string
50 = "Copyright 1995-1996 by Virginia Polytechnic Institute & State\n\
51 University, Blacksburg, Virginia, USA, and Fred L. Drake, Jr., Reston,\n\
52 Virginia, USA. Portions copyright 1991-1995 by Stichting Mathematisch\n\
53 Centrum, Amsterdam, The Netherlands.";
56 static char*
57 parser_doc_string
58 = "This is an interface to Python's internal parser.";
60 static char*
61 parser_version_string = "0.4";
64 typedef PyObject* (*SeqMaker) Py_PROTO((int length));
65 typedef int (*SeqInserter) Py_PROTO((PyObject* sequence,
66 int index,
67 PyObject* element));
69 /* The function below is copyrigthed by Stichting Mathematisch Centrum. The
70 * original copyright statement is included below, and continues to apply
71 * in full to the function immediately following. All other material is
72 * original, copyrighted by Fred L. Drake, Jr. and Virginia Polytechnic
73 * Institute and State University. Changes were made to comply with the
74 * new naming conventions. Added arguments to provide support for creating
75 * lists as well as tuples, and optionally including the line numbers.
78 /***********************************************************
79 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
80 The Netherlands.
82 All Rights Reserved
84 Permission to use, copy, modify, and distribute this software and its
85 documentation for any purpose and without fee is hereby granted,
86 provided that the above copyright notice appear in all copies and that
87 both that copyright notice and this permission notice appear in
88 supporting documentation, and that the names of Stichting Mathematisch
89 Centrum or CWI or Corporation for National Research Initiatives or
90 CNRI not be used in advertising or publicity pertaining to
91 distribution of the software without specific, written prior
92 permission.
94 While CWI is the initial source for this software, a modified version
95 is made available by the Corporation for National Research Initiatives
96 (CNRI) at the Internet address ftp://ftp.python.org.
98 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
99 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
100 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
101 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
102 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
103 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
104 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
105 PERFORMANCE OF THIS SOFTWARE.
107 ******************************************************************/
109 static PyObject*
110 node2tuple(n, mkseq, addelem, lineno)
111 node *n; /* node to convert */
112 SeqMaker mkseq; /* create sequence */
113 SeqInserter addelem; /* func. to add elem. in seq. */
114 int lineno; /* include line numbers? */
116 if (n == NULL) {
117 Py_INCREF(Py_None);
118 return (Py_None);
120 if (ISNONTERMINAL(TYPE(n))) {
121 int i;
122 PyObject *v;
123 PyObject *w;
125 v = mkseq(1 + NCH(n));
126 if (v == NULL)
127 return (v);
128 w = PyInt_FromLong(TYPE(n));
129 if (w == NULL) {
130 Py_DECREF(v);
131 return ((PyObject*) NULL);
133 (void) addelem(v, 0, w);
134 for (i = 0; i < NCH(n); i++) {
135 w = node2tuple(CHILD(n, i), mkseq, addelem, lineno);
136 if (w == NULL) {
137 Py_DECREF(v);
138 return ((PyObject*) NULL);
140 (void) addelem(v, i+1, w);
142 return (v);
144 else if (ISTERMINAL(TYPE(n))) {
145 PyObject *result = mkseq(2 + lineno);
146 if (result != NULL) {
147 (void) addelem(result, 0, PyInt_FromLong(TYPE(n)));
148 (void) addelem(result, 1, PyString_FromString(STR(n)));
149 if (lineno == 1)
150 (void) addelem(result, 2, PyInt_FromLong(n->n_lineno));
152 return (result);
154 else {
155 PyErr_SetString(PyExc_SystemError,
156 "unrecognized parse tree node type");
157 return ((PyObject*) NULL);
159 } /* node2tuple() */
161 * End of material copyrighted by Stichting Mathematisch Centrum.
166 /* There are two types of intermediate objects we're interested in:
167 * 'eval' and 'exec' types. These constants can be used in the ast_type
168 * field of the object type to identify which any given object represents.
169 * These should probably go in an external header to allow other extensions
170 * to use them, but then, we really should be using C++ too. ;-)
172 * The PyAST_FRAGMENT type is not currently supported. Maybe not useful?
173 * Haven't decided yet.
176 #define PyAST_EXPR 1
177 #define PyAST_SUITE 2
178 #define PyAST_FRAGMENT 3
181 /* These are the internal objects and definitions required to implement the
182 * AST type. Most of the internal names are more reminiscent of the 'old'
183 * naming style, but the code uses the new naming convention.
186 static PyObject*
187 parser_error = 0;
190 typedef struct _PyAST_Object {
192 PyObject_HEAD /* standard object header */
193 node* ast_node; /* the node* returned by the parser */
194 int ast_type; /* EXPR or SUITE ? */
196 } PyAST_Object;
199 staticforward void
200 parser_free Py_PROTO((PyAST_Object *ast));
202 staticforward int
203 parser_compare Py_PROTO((PyAST_Object *left, PyAST_Object *right));
205 staticforward PyObject *
206 parser_getattr Py_PROTO((PyObject *self, char *name));
209 static
210 PyTypeObject PyAST_Type = {
212 PyObject_HEAD_INIT(NULL)
214 "ast", /* tp_name */
215 (int) sizeof(PyAST_Object), /* tp_basicsize */
216 0, /* tp_itemsize */
217 (destructor)parser_free, /* tp_dealloc */
218 0, /* tp_print */
219 parser_getattr, /* tp_getattr */
220 0, /* tp_setattr */
221 (cmpfunc)parser_compare, /* tp_compare */
222 0, /* tp_repr */
223 0, /* tp_as_number */
224 0, /* tp_as_sequence */
225 0, /* tp_as_mapping */
226 0, /* tp_hash */
227 0, /* tp_call */
228 0, /* tp_str */
229 0, /* tp_getattro */
230 0, /* tp_setattro */
232 /* Functions to access object as input/output buffer */
233 0, /* tp_as_buffer */
235 /* Space for future expansion */
236 0, /* tp_xxx4 */
238 /* __doc__ */
239 "Intermediate representation of a Python parse tree."
241 }; /* PyAST_Type */
244 static int
245 parser_compare_nodes(left, right)
246 node *left;
247 node *right;
249 int j;
251 if (TYPE(left) < TYPE(right))
252 return (-1);
254 if (TYPE(right) < TYPE(left))
255 return (1);
257 if (ISTERMINAL(TYPE(left)))
258 return (strcmp(STR(left), STR(right)));
260 if (NCH(left) < NCH(right))
261 return (-1);
263 if (NCH(right) < NCH(left))
264 return (1);
266 for (j = 0; j < NCH(left); ++j) {
267 int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j));
269 if (v != 0)
270 return (v);
272 return (0);
274 } /* parser_compare_nodes() */
277 /* int parser_compare(PyAST_Object* left, PyAST_Object* right)
279 * Comparison function used by the Python operators ==, !=, <, >, <=, >=
280 * This really just wraps a call to parser_compare_nodes() with some easy
281 * checks and protection code.
284 static int
285 parser_compare(left, right)
286 PyAST_Object *left;
287 PyAST_Object *right;
289 if (left == right)
290 return (0);
292 if ((left == 0) || (right == 0))
293 return (-1);
295 return (parser_compare_nodes(left->ast_node, right->ast_node));
297 } /* parser_compare() */
300 /* parser_newastobject(node* ast)
302 * Allocates a new Python object representing an AST. This is simply the
303 * 'wrapper' object that holds a node* and allows it to be passed around in
304 * Python code.
307 static PyObject*
308 parser_newastobject(ast, type)
309 node *ast;
310 int type;
312 PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type);
314 if (o != 0) {
315 o->ast_node = ast;
316 o->ast_type = type;
318 else {
319 PyNode_Free(ast);
321 return ((PyObject*)o);
323 } /* parser_newastobject() */
326 /* void parser_free(PyAST_Object* ast)
328 * This is called by a del statement that reduces the reference count to 0.
331 static void
332 parser_free(ast)
333 PyAST_Object *ast;
335 PyNode_Free(ast->ast_node);
336 PyMem_DEL(ast);
338 } /* parser_free() */
341 /* parser_ast2tuple(PyObject* self, PyObject* args)
343 * This provides conversion from a node* to a tuple object that can be
344 * returned to the Python-level caller. The AST object is not modified.
347 static PyObject*
348 parser_ast2tuple(self, args)
349 PyAST_Object *self;
350 PyObject *args;
352 PyObject *line_option = 0;
353 PyObject *res = 0;
354 int ok;
356 if (self == NULL) {
357 ok = PyArg_ParseTuple(
358 args, "O!|O:ast2tuple", &PyAST_Type, &self, &line_option);
360 else
361 ok = PyArg_ParseTuple(args, "|O:totuple", &line_option);
362 if (ok != 0) {
363 int lineno = 0;
364 if (line_option != NULL) {
365 lineno = (PyObject_IsTrue(line_option) != 0) ? 1 : 0;
368 * Convert AST into a tuple representation. Use Guido's function,
369 * since it's known to work already.
371 res = node2tuple(((PyAST_Object*)self)->ast_node,
372 PyTuple_New, PyTuple_SetItem, lineno);
374 return (res);
376 } /* parser_ast2tuple() */
379 /* parser_ast2tuple(PyObject* self, PyObject* args)
381 * This provides conversion from a node* to a tuple object that can be
382 * returned to the Python-level caller. The AST object is not modified.
385 static PyObject*
386 parser_ast2list(self, args)
387 PyAST_Object *self;
388 PyObject *args;
390 PyObject *line_option = 0;
391 PyObject *res = 0;
392 int ok;
394 if (self == NULL)
395 ok = PyArg_ParseTuple(
396 args, "O!|O:ast2list", &PyAST_Type, &self, &line_option);
397 else
398 ok = PyArg_ParseTuple(args, "|O:tolist", &line_option);
399 if (ok) {
400 int lineno = 0;
401 if (line_option != 0) {
402 lineno = PyObject_IsTrue(line_option) ? 1 : 0;
405 * Convert AST into a tuple representation. Use Guido's function,
406 * since it's known to work already.
408 res = node2tuple(self->ast_node,
409 PyList_New, PyList_SetItem, lineno);
411 return (res);
413 } /* parser_ast2list() */
416 /* parser_compileast(PyObject* self, PyObject* args)
418 * This function creates code objects from the parse tree represented by
419 * the passed-in data object. An optional file name is passed in as well.
422 static PyObject*
423 parser_compileast(self, args)
424 PyAST_Object *self;
425 PyObject *args;
427 PyObject* res = 0;
428 char* str = "<ast>";
429 int ok;
431 if (self == NULL)
432 ok = PyArg_ParseTuple(
433 args, "O!|s:compileast", &PyAST_Type, &self, &str);
434 else
435 ok = PyArg_ParseTuple(args, "|s:compile", &str);
437 if (ok)
438 res = (PyObject *)PyNode_Compile(self->ast_node, str);
440 return (res);
442 } /* parser_compileast() */
445 /* PyObject* parser_isexpr(PyObject* self, PyObject* args)
446 * PyObject* parser_issuite(PyObject* self, PyObject* args)
448 * Checks the passed-in AST object to determine if it is an expression or
449 * a statement suite, respectively. The return is a Python truth value.
452 static PyObject*
453 parser_isexpr(self, args)
454 PyAST_Object *self;
455 PyObject *args;
457 PyObject* res = 0;
458 int ok;
460 if (self == NULL)
461 ok = PyArg_ParseTuple(args, "O!:isexpr", &PyAST_Type, &self);
462 else
463 ok = PyArg_ParseTuple(args, ":isexpr");
465 if (ok) {
466 /* Check to see if the AST represents an expression or not. */
467 res = (self->ast_type == PyAST_EXPR) ? Py_True : Py_False;
468 Py_INCREF(res);
470 return (res);
472 } /* parser_isexpr() */
475 static PyObject*
476 parser_issuite(self, args)
477 PyAST_Object *self;
478 PyObject *args;
480 PyObject* res = 0;
481 int ok;
483 if (self == NULL)
484 ok = PyArg_ParseTuple(args, "O!:issuite", &PyAST_Type, &self);
485 else
486 ok = PyArg_ParseTuple(args, ":issuite");
488 if (ok) {
489 /* Check to see if the AST represents an expression or not. */
490 res = (self->ast_type == PyAST_EXPR) ? Py_False : Py_True;
491 Py_INCREF(res);
493 return (res);
495 } /* parser_issuite() */
498 static PyMethodDef
499 parser_methods[] = {
500 {"compile", (PyCFunction)parser_compileast, METH_VARARGS,
501 "Compile this AST object into a code object."},
502 {"isexpr", (PyCFunction)parser_isexpr, METH_VARARGS,
503 "Determines if this AST object was created from an expression."},
504 {"issuite", (PyCFunction)parser_issuite, METH_VARARGS,
505 "Determines if this AST object was created from a suite."},
506 {"tolist", (PyCFunction)parser_ast2list, METH_VARARGS,
507 "Creates a list-tree representation of this AST."},
508 {"totuple", (PyCFunction)parser_ast2tuple, METH_VARARGS,
509 "Creates a tuple-tree representation of this AST."},
511 {NULL, NULL, 0, NULL}
514 static PyObject*
515 parser_method_list = NULL;
518 static PyObject*
519 parser_getattr(self, name)
520 PyObject *self;
521 char *name;
523 if (strcmp(name, "__methods__") == 0) {
524 Py_INCREF(parser_method_list);
525 return (parser_method_list);
527 return (Py_FindMethod(parser_methods, self, name));
529 } /* parser_getattr() */
532 /* err_string(char* message)
534 * Sets the error string for an exception of type ParserError.
537 static void
538 err_string(message)
539 char *message;
541 PyErr_SetString(parser_error, message);
543 } /* err_string() */
546 /* PyObject* parser_do_parse(PyObject* args, int type)
548 * Internal function to actually execute the parse and return the result if
549 * successful, or set an exception if not.
552 static PyObject*
553 parser_do_parse(args, type)
554 PyObject *args;
555 int type;
557 char* string = 0;
558 PyObject* res = 0;
560 if (PyArg_ParseTuple(args, "s", &string)) {
561 node* n = PyParser_SimpleParseString(string,
562 (type == PyAST_EXPR)
563 ? eval_input : file_input);
565 if (n != 0)
566 res = parser_newastobject(n, type);
567 else
568 err_string("Could not parse string.");
570 return (res);
572 } /* parser_do_parse() */
575 /* PyObject* parser_expr(PyObject* self, PyObject* args)
576 * PyObject* parser_suite(PyObject* self, PyObject* args)
578 * External interfaces to the parser itself. Which is called determines if
579 * the parser attempts to recognize an expression ('eval' form) or statement
580 * suite ('exec' form). The real work is done by parser_do_parse() above.
583 static PyObject*
584 parser_expr(self, args)
585 PyObject *self;
586 PyObject *args;
588 NOTE(ARGUNUSED(self))
589 return (parser_do_parse(args, PyAST_EXPR));
591 } /* parser_expr() */
594 static PyObject*
595 parser_suite(self, args)
596 PyObject *self;
597 PyObject *args;
599 NOTE(ARGUNUSED(self))
600 return (parser_do_parse(args, PyAST_SUITE));
602 } /* parser_suite() */
606 /* This is the messy part of the code. Conversion from a tuple to an AST
607 * object requires that the input tuple be valid without having to rely on
608 * catching an exception from the compiler. This is done to allow the
609 * compiler itself to remain fast, since most of its input will come from
610 * the parser directly, and therefore be known to be syntactically correct.
611 * This validation is done to ensure that we don't core dump the compile
612 * phase, returning an exception instead.
614 * Two aspects can be broken out in this code: creating a node tree from
615 * the tuple passed in, and verifying that it is indeed valid. It may be
616 * advantageous to expand the number of AST types to include funcdefs and
617 * lambdadefs to take advantage of the optimizer, recognizing those ASTs
618 * here. They are not necessary, and not quite as useful in a raw form.
619 * For now, let's get expressions and suites working reliably.
623 staticforward node* build_node_tree Py_PROTO((PyObject *tuple));
624 staticforward int validate_expr_tree Py_PROTO((node *tree));
625 staticforward int validate_file_input Py_PROTO((node *tree));
628 /* PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
630 * This is the public function, called from the Python code. It receives a
631 * single tuple object from the caller, and creates an AST object if the
632 * tuple can be validated. It does this by checking the first code of the
633 * tuple, and, if acceptable, builds the internal representation. If this
634 * step succeeds, the internal representation is validated as fully as
635 * possible with the various validate_*() routines defined below.
637 * This function must be changed if support is to be added for PyAST_FRAGMENT
638 * AST objects.
641 static PyObject*
642 parser_tuple2ast(self, args)
643 PyObject *self;
644 PyObject *args;
646 NOTE(ARGUNUSED(self))
647 PyObject *ast = 0;
648 PyObject *tuple = 0;
649 PyObject *temp = 0;
650 int ok;
651 int start_sym = 0;
653 if (!PyArg_ParseTuple(args, "O:tuple2ast", &tuple))
654 return (0);
655 if (!PySequence_Check(tuple)) {
656 PyErr_SetString(PyExc_ValueError,
657 "tuple2ast() requires a single sequence argument");
658 return (0);
661 * This mess of tests is written this way so we can use the abstract
662 * object interface (AOI). Unfortunately, the AOI increments reference
663 * counts, which requires that we store a pointer to retrieved object
664 * so we can DECREF it after the check. But we really should accept
665 * lists as well as tuples at the very least.
667 ok = PyObject_Length(tuple) >= 2;
668 if (ok) {
669 temp = PySequence_GetItem(tuple, 0);
670 ok = (temp != NULL) && PyInt_Check(temp);
671 if (ok)
672 /* this is used after the initial checks: */
673 start_sym = PyInt_AsLong(temp);
674 Py_XDECREF(temp);
676 if (ok) {
677 temp = PySequence_GetItem(tuple, 1);
678 ok = (temp != NULL) && PySequence_Check(temp);
679 Py_XDECREF(temp);
681 if (ok) {
682 temp = PySequence_GetItem(tuple, 1);
683 ok = (temp != NULL) && PyObject_Length(temp) >= 2;
684 if (ok) {
685 PyObject *temp2 = PySequence_GetItem(temp, 0);
686 if (temp2 != NULL) {
687 ok = PyInt_Check(temp2);
688 Py_DECREF(temp2);
691 Py_XDECREF(temp);
693 /* If we've failed at some point, get out of here. */
694 if (!ok) {
695 err_string("malformed sequence for tuple2ast()");
696 return (0);
699 * This might be a valid parse tree, but let's do a quick check
700 * before we jump the gun.
702 if (start_sym == eval_input) {
703 /* Might be an eval form. */
704 node* expression = build_node_tree(tuple);
706 if ((expression != 0) && validate_expr_tree(expression))
707 ast = parser_newastobject(expression, PyAST_EXPR);
709 else if (start_sym == file_input) {
710 /* This looks like an exec form so far. */
711 node* suite_tree = build_node_tree(tuple);
713 if ((suite_tree != 0) && validate_file_input(suite_tree))
714 ast = parser_newastobject(suite_tree, PyAST_SUITE);
716 else
717 /* This is a fragment, and is not yet supported. Maybe they
718 * will be if I find a use for them.
720 err_string("Fragmentary parse trees not supported.");
722 /* Make sure we throw an exception on all errors. We should never
723 * get this, but we'd do well to be sure something is done.
725 if ((ast == 0) && !PyErr_Occurred())
726 err_string("Unspecified ast error occurred.");
728 return (ast);
730 } /* parser_tuple2ast() */
733 /* int check_terminal_tuple()
735 * Check a tuple to determine that it is indeed a valid terminal
736 * node. The node is known to be required as a terminal, so we throw
737 * an exception if there is a failure.
739 * The format of an acceptable terminal tuple is "(is[i])": the fact
740 * that elem is a tuple and the integer is a valid terminal symbol
741 * has been established before this function is called. We must
742 * check the length of the tuple and the type of the second element
743 * and optional third element. We do *NOT* check the actual text of
744 * the string element, which we could do in many cases. This is done
745 * by the validate_*() functions which operate on the internal
746 * representation.
748 static int
749 check_terminal_tuple(elem)
750 PyObject *elem;
752 int len = PyObject_Length(elem);
753 int res = 1;
754 char* str = "Illegal terminal symbol; bad node length.";
756 if ((len == 2) || (len == 3)) {
757 PyObject *temp = PySequence_GetItem(elem, 1);
758 res = PyString_Check(temp);
759 str = "Illegal terminal symbol; expected a string.";
760 if (res && (len == 3)) {
761 PyObject* third = PySequence_GetItem(elem, 2);
762 res = PyInt_Check(third);
763 str = "Invalid third element of terminal node.";
764 Py_XDECREF(third);
766 Py_XDECREF(temp);
768 else {
769 res = 0;
771 if (!res) {
772 elem = Py_BuildValue("(os)", elem, str);
773 PyErr_SetObject(parser_error, elem);
775 return (res);
777 } /* check_terminal_tuple() */
780 /* node* build_node_children()
782 * Iterate across the children of the current non-terminal node and build
783 * their structures. If successful, return the root of this portion of
784 * the tree, otherwise, 0. Any required exception will be specified already,
785 * and no memory will have been deallocated.
788 static node*
789 build_node_children(tuple, root, line_num)
790 PyObject *tuple;
791 node *root;
792 int *line_num;
794 int len = PyObject_Length(tuple);
795 int i;
797 for (i = 1; i < len; ++i) {
798 /* elem must always be a tuple, however simple */
799 PyObject* elem = PySequence_GetItem(tuple, i);
800 int ok = elem != NULL;
801 long type = 0;
802 char *strn = 0;
804 if (ok)
805 ok = PySequence_Check(elem);
806 if (ok) {
807 PyObject *temp = PySequence_GetItem(elem, 0);
808 if (temp == NULL)
809 ok = 0;
810 else {
811 ok = PyInt_Check(temp);
812 if (ok)
813 type = PyInt_AsLong(temp);
814 Py_DECREF(temp);
817 if (!ok) {
818 PyErr_SetObject(parser_error,
819 Py_BuildValue("(os)", elem,
820 "Illegal node construct."));
821 Py_XDECREF(elem);
822 return (0);
824 if (ISTERMINAL(type)) {
825 if (check_terminal_tuple(elem)) {
826 PyObject *temp = PySequence_GetItem(elem, 1);
828 /* check_terminal_tuple() already verified it's a string */
829 strn = (char *)malloc(PyString_GET_SIZE(temp) + 1);
830 if (strn != NULL)
831 (void) strcpy(strn, PyString_AS_STRING(temp));
832 Py_XDECREF(temp);
834 if (PyObject_Length(elem) == 3) {
835 PyObject* temp = PySequence_GetItem(elem, 2);
836 *line_num = PyInt_AsLong(temp);
837 Py_DECREF(temp);
840 else {
841 Py_XDECREF(elem);
842 return (0);
845 else if (!ISNONTERMINAL(type)) {
847 * It has to be one or the other; this is an error.
848 * Throw an exception.
850 PyErr_SetObject(parser_error,
851 Py_BuildValue("(os)", elem,
852 "Unknown node type."));
853 Py_XDECREF(elem);
854 return (0);
856 PyNode_AddChild(root, type, strn, *line_num);
858 if (ISNONTERMINAL(type)) {
859 node* new_child = CHILD(root, i - 1);
861 if (new_child != build_node_children(elem, new_child, line_num)) {
862 Py_XDECREF(elem);
863 return (0);
866 else if (type == NEWLINE) { /* It's true: we increment the */
867 ++(*line_num); /* line number *after* the newline! */
869 Py_XDECREF(elem);
871 return (root);
873 } /* build_node_children() */
876 static node*
877 build_node_tree(tuple)
878 PyObject *tuple;
880 node* res = 0;
881 PyObject *temp = PySequence_GetItem(tuple, 0);
882 long num = -1;
884 if (temp != NULL)
885 num = PyInt_AsLong(temp);
886 Py_XDECREF(temp);
887 if (ISTERMINAL(num)) {
889 * The tuple is simple, but it doesn't start with a start symbol.
890 * Throw an exception now and be done with it.
892 tuple = Py_BuildValue("(os)", tuple,
893 "Illegal ast tuple; cannot start with terminal symbol.");
894 PyErr_SetObject(parser_error, tuple);
896 else if (ISNONTERMINAL(num)) {
898 * Not efficient, but that can be handled later.
900 int line_num = 0;
902 res = PyNode_New(num);
903 if (res != build_node_children(tuple, res, &line_num)) {
904 PyNode_Free(res);
905 res = 0;
908 else
909 /* The tuple is illegal -- if the number is neither TERMINAL nor
910 * NONTERMINAL, we can't use it.
912 PyErr_SetObject(parser_error,
913 Py_BuildValue("(os)", tuple,
914 "Illegal component tuple."));
916 return (res);
918 } /* build_node_tree() */
921 #ifdef HAVE_OLD_CPP
922 #define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
923 #else
924 #define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
925 #endif
929 * Validation routines used within the validation section:
931 staticforward int validate_terminal Py_PROTO((node *terminal,
932 int type, char *string));
934 #define validate_ampersand(ch) validate_terminal(ch, AMPER, "&")
935 #define validate_circumflex(ch) validate_terminal(ch, CIRCUMFLEX, "^")
936 #define validate_colon(ch) validate_terminal(ch, COLON, ":")
937 #define validate_comma(ch) validate_terminal(ch, COMMA, ",")
938 #define validate_dedent(ch) validate_terminal(ch, DEDENT, "")
939 #define validate_equal(ch) validate_terminal(ch, EQUAL, "=")
940 #define validate_indent(ch) validate_terminal(ch, INDENT, (char*)NULL)
941 #define validate_lparen(ch) validate_terminal(ch, LPAR, "(")
942 #define validate_newline(ch) validate_terminal(ch, NEWLINE, (char*)NULL)
943 #define validate_rparen(ch) validate_terminal(ch, RPAR, ")")
944 #define validate_semi(ch) validate_terminal(ch, SEMI, ";")
945 #define validate_star(ch) validate_terminal(ch, STAR, "*")
946 #define validate_vbar(ch) validate_terminal(ch, VBAR, "|")
947 #define validate_doublestar(ch) validate_terminal(ch, DOUBLESTAR, "**")
948 #define validate_dot(ch) validate_terminal(ch, DOT, ".")
949 #define validate_name(ch, str) validate_terminal(ch, NAME, str)
951 VALIDATER(node); VALIDATER(small_stmt);
952 VALIDATER(class); VALIDATER(node);
953 VALIDATER(parameters); VALIDATER(suite);
954 VALIDATER(testlist); VALIDATER(varargslist);
955 VALIDATER(fpdef); VALIDATER(fplist);
956 VALIDATER(stmt); VALIDATER(simple_stmt);
957 VALIDATER(expr_stmt); VALIDATER(power);
958 VALIDATER(print_stmt); VALIDATER(del_stmt);
959 VALIDATER(return_stmt);
960 VALIDATER(raise_stmt); VALIDATER(import_stmt);
961 VALIDATER(global_stmt);
962 VALIDATER(assert_stmt);
963 VALIDATER(exec_stmt); VALIDATER(compound_stmt);
964 VALIDATER(while); VALIDATER(for);
965 VALIDATER(try); VALIDATER(except_clause);
966 VALIDATER(test); VALIDATER(and_test);
967 VALIDATER(not_test); VALIDATER(comparison);
968 VALIDATER(comp_op); VALIDATER(expr);
969 VALIDATER(xor_expr); VALIDATER(and_expr);
970 VALIDATER(shift_expr); VALIDATER(arith_expr);
971 VALIDATER(term); VALIDATER(factor);
972 VALIDATER(atom); VALIDATER(lambdef);
973 VALIDATER(trailer); VALIDATER(subscript);
974 VALIDATER(subscriptlist); VALIDATER(sliceop);
975 VALIDATER(exprlist); VALIDATER(dictmaker);
976 VALIDATER(arglist); VALIDATER(argument);
979 #define is_even(n) (((n) & 1) == 0)
980 #define is_odd(n) (((n) & 1) == 1)
983 static int
984 validate_ntype(n, t)
985 node *n;
986 int t;
988 int res = (TYPE(n) == t);
990 if (!res) {
991 char buffer[128];
992 (void) sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
993 err_string(buffer);
995 return (res);
997 } /* validate_ntype() */
1000 static int
1001 validate_numnodes(n, num, name)
1002 node *n;
1003 int num;
1004 const char *const name;
1006 if (NCH(n) != num) {
1007 char buff[60];
1008 (void) sprintf(buff, "Illegal number of children for %s node.", name);
1009 err_string(buff);
1011 return (NCH(n) == num);
1013 } /* validate_numnodes() */
1016 static int
1017 validate_terminal(terminal, type, string)
1018 node *terminal;
1019 int type;
1020 char *string;
1022 int res = (validate_ntype(terminal, type)
1023 && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));
1025 if (!res && !PyErr_Occurred()) {
1026 char buffer[60];
1027 (void) sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
1028 err_string(buffer);
1030 return (res);
1032 } /* validate_terminal() */
1035 /* X (',' X) [',']
1037 static int
1038 validate_repeating_list(tree, ntype, vfunc, name)
1039 node *tree;
1040 int ntype;
1041 int (*vfunc)();
1042 const char *const name;
1044 int nch = NCH(tree);
1045 int res = (nch && validate_ntype(tree, ntype)
1046 && vfunc(CHILD(tree, 0)));
1048 if (!res && !PyErr_Occurred())
1049 (void) validate_numnodes(tree, 1, name);
1050 else {
1051 if (is_even(nch))
1052 res = validate_comma(CHILD(tree, --nch));
1053 if (res && nch > 1) {
1054 int pos = 1;
1055 for ( ; res && pos < nch; pos += 2)
1056 res = (validate_comma(CHILD(tree, pos))
1057 && vfunc(CHILD(tree, pos + 1)));
1060 return (res);
1062 } /* validate_repeating_list() */
1065 /* VALIDATE(class)
1067 * classdef:
1068 * 'class' NAME ['(' testlist ')'] ':' suite
1070 static int
1071 validate_class(tree)
1072 node *tree;
1074 int nch = NCH(tree);
1075 int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
1077 if (res) {
1078 res = (validate_name(CHILD(tree, 0), "class")
1079 && validate_ntype(CHILD(tree, 1), NAME)
1080 && validate_colon(CHILD(tree, nch - 2))
1081 && validate_suite(CHILD(tree, nch - 1)));
1083 else
1084 (void) validate_numnodes(tree, 4, "class");
1085 if (res && (nch == 7)) {
1086 res = (validate_lparen(CHILD(tree, 2))
1087 && validate_testlist(CHILD(tree, 3))
1088 && validate_rparen(CHILD(tree, 4)));
1090 return (res);
1092 } /* validate_class() */
1095 /* if_stmt:
1096 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1098 static int
1099 validate_if(tree)
1100 node *tree;
1102 int nch = NCH(tree);
1103 int res = (validate_ntype(tree, if_stmt)
1104 && (nch >= 4)
1105 && validate_name(CHILD(tree, 0), "if")
1106 && validate_test(CHILD(tree, 1))
1107 && validate_colon(CHILD(tree, 2))
1108 && validate_suite(CHILD(tree, 3)));
1110 if (res && ((nch % 4) == 3)) {
1111 /* ... 'else' ':' suite */
1112 res = (validate_name(CHILD(tree, nch - 3), "else")
1113 && validate_colon(CHILD(tree, nch - 2))
1114 && validate_suite(CHILD(tree, nch - 1)));
1115 nch -= 3;
1117 else if (!res && !PyErr_Occurred())
1118 (void) validate_numnodes(tree, 4, "if");
1119 if ((nch % 4) != 0)
1120 /* Will catch the case for nch < 4 */
1121 res = validate_numnodes(tree, 0, "if");
1122 else if (res && (nch > 4)) {
1123 /* ... ('elif' test ':' suite)+ ... */
1124 int j = 4;
1125 while ((j < nch) && res) {
1126 res = (validate_name(CHILD(tree, j), "elif")
1127 && validate_colon(CHILD(tree, j + 2))
1128 && validate_test(CHILD(tree, j + 1))
1129 && validate_suite(CHILD(tree, j + 3)));
1130 j += 4;
1133 return (res);
1135 } /* validate_if() */
1138 /* parameters:
1139 * '(' [varargslist] ')'
1142 static int
1143 validate_parameters(tree)
1144 node *tree;
1146 int nch = NCH(tree);
1147 int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));
1149 if (res) {
1150 res = (validate_lparen(CHILD(tree, 0))
1151 && validate_rparen(CHILD(tree, nch - 1)));
1152 if (res && (nch == 3))
1153 res = validate_varargslist(CHILD(tree, 1));
1155 else
1156 (void) validate_numnodes(tree, 2, "parameters");
1158 return (res);
1160 } /* validate_parameters() */
1163 /* VALIDATE(suite)
1165 * suite:
1166 * simple_stmt
1167 * | NEWLINE INDENT stmt+ DEDENT
1169 static int
1170 validate_suite(tree)
1171 node *tree;
1173 int nch = NCH(tree);
1174 int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));
1176 if (res && (nch == 1))
1177 res = validate_simple_stmt(CHILD(tree, 0));
1178 else if (res) {
1179 /* NEWLINE INDENT stmt+ DEDENT */
1180 res = (validate_newline(CHILD(tree, 0))
1181 && validate_indent(CHILD(tree, 1))
1182 && validate_stmt(CHILD(tree, 2))
1183 && validate_dedent(CHILD(tree, nch - 1)));
1185 if (res && (nch > 4)) {
1186 int i = 3;
1187 --nch; /* forget the DEDENT */
1188 for ( ; res && (i < nch); ++i)
1189 res = validate_stmt(CHILD(tree, i));
1191 else if (nch < 4)
1192 res = validate_numnodes(tree, 4, "suite");
1194 return (res);
1196 } /* validate_suite() */
1199 static int
1200 validate_testlist(tree)
1201 node *tree;
1203 return (validate_repeating_list(tree, testlist,
1204 validate_test, "testlist"));
1206 } /* validate_testlist() */
1209 /* VALIDATE(varargslist)
1211 * varargslist:
1212 * (fpdef ['=' test] ',')* ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1213 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1215 * (fpdef ['=' test] ',')*
1216 * ('*' NAME [',' ('**'|'*' '*') NAME]
1217 * | ('**'|'*' '*') NAME)
1218 * | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1221 static int
1222 validate_varargslist(tree)
1223 node *tree;
1225 int nch = NCH(tree);
1226 int res = validate_ntype(tree, varargslist) && (nch != 0);
1228 if (res && (nch >= 2) && (TYPE(CHILD(tree, nch - 1)) == NAME)) {
1229 /* (fpdef ['=' test] ',')*
1230 * ('*' NAME [',' '*' '*' NAME] | '*' '*' NAME)
1232 int pos = 0;
1233 int remaining = nch;
1235 while (res && (TYPE(CHILD(tree, pos)) == fpdef)) {
1236 res = validate_fpdef(CHILD(tree, pos));
1237 if (res) {
1238 if (TYPE(CHILD(tree, pos + 1)) == EQUAL) {
1239 res = validate_test(CHILD(tree, pos + 2));
1240 pos += 2;
1242 res = res && validate_comma(CHILD(tree, pos + 1));
1243 pos += 2;
1246 if (res) {
1247 remaining = nch - pos;
1248 res = ((remaining == 2) || (remaining == 3)
1249 || (remaining == 5) || (remaining == 6));
1250 if (!res)
1251 (void) validate_numnodes(tree, 2, "varargslist");
1252 else if (TYPE(CHILD(tree, pos)) == DOUBLESTAR)
1253 return ((remaining == 2)
1254 && validate_ntype(CHILD(tree, pos+1), NAME));
1255 else {
1256 res = validate_star(CHILD(tree, pos++));
1257 --remaining;
1260 if (res) {
1261 if (remaining == 2) {
1262 res = (validate_star(CHILD(tree, pos))
1263 && validate_ntype(CHILD(tree, pos + 1), NAME));
1265 else {
1266 res = validate_ntype(CHILD(tree, pos++), NAME);
1267 if (res && (remaining >= 4)) {
1268 res = validate_comma(CHILD(tree, pos));
1269 if (--remaining == 3)
1270 res = (validate_star(CHILD(tree, pos + 1))
1271 && validate_star(CHILD(tree, pos + 2)));
1272 else
1273 res = validate_ntype(CHILD(tree, pos + 1), DOUBLESTAR);
1277 if (!res && !PyErr_Occurred())
1278 err_string("Incorrect validation of variable arguments list.");
1280 else if (res) {
1281 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1282 if (TYPE(CHILD(tree, nch - 1)) == COMMA)
1283 --nch;
1285 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1286 res = (is_odd(nch)
1287 && validate_fpdef(CHILD(tree, 0)));
1289 if (res && (nch > 1)) {
1290 int pos = 1;
1291 if (TYPE(CHILD(tree, 1)) == EQUAL) {
1292 res = validate_test(CHILD(tree, 2));
1293 pos += 2;
1295 /* ... (',' fpdef ['=' test])* */
1296 for ( ; res && (pos < nch); pos += 2) {
1297 /* ',' fpdef */
1298 res = (validate_comma(CHILD(tree, pos))
1299 && validate_fpdef(CHILD(tree, pos + 1)));
1300 if (res
1301 && ((nch - pos) > 2)
1302 && (TYPE(CHILD(tree, pos + 2)) == EQUAL)) {
1303 /* ['=' test] */
1304 res = validate_test(CHILD(tree, pos + 3));
1305 pos += 2;
1310 else
1311 err_string("Improperly formed argument list.");
1313 return (res);
1315 } /* validate_varargslist() */
1318 /* VALIDATE(fpdef)
1320 * fpdef:
1321 * NAME
1322 * | '(' fplist ')'
1324 static int
1325 validate_fpdef(tree)
1326 node *tree;
1328 int nch = NCH(tree);
1329 int res = validate_ntype(tree, fpdef);
1331 if (res) {
1332 if (nch == 1)
1333 res = validate_ntype(CHILD(tree, 0), NAME);
1334 else if (nch == 3)
1335 res = (validate_lparen(CHILD(tree, 0))
1336 && validate_fplist(CHILD(tree, 1))
1337 && validate_rparen(CHILD(tree, 2)));
1338 else
1339 res = validate_numnodes(tree, 1, "fpdef");
1341 return (res);
1343 } /* validate_fpdef() */
1346 static int
1347 validate_fplist(tree)
1348 node *tree;
1350 return (validate_repeating_list(tree, fplist,
1351 validate_fpdef, "fplist"));
1353 } /* validate_fplist() */
1356 /* simple_stmt | compound_stmt
1359 static int
1360 validate_stmt(tree)
1361 node *tree;
1363 int res = (validate_ntype(tree, stmt)
1364 && validate_numnodes(tree, 1, "stmt"));
1366 if (res) {
1367 tree = CHILD(tree, 0);
1369 if (TYPE(tree) == simple_stmt)
1370 res = validate_simple_stmt(tree);
1371 else
1372 res = validate_compound_stmt(tree);
1374 return (res);
1376 } /* validate_stmt() */
1379 /* small_stmt (';' small_stmt)* [';'] NEWLINE
1382 static int
1383 validate_simple_stmt(tree)
1384 node *tree;
1386 int nch = NCH(tree);
1387 int res = (validate_ntype(tree, simple_stmt)
1388 && (nch >= 2)
1389 && validate_small_stmt(CHILD(tree, 0))
1390 && validate_newline(CHILD(tree, nch - 1)));
1392 if (nch < 2)
1393 res = validate_numnodes(tree, 2, "simple_stmt");
1394 --nch; /* forget the NEWLINE */
1395 if (res && is_even(nch))
1396 res = validate_semi(CHILD(tree, --nch));
1397 if (res && (nch > 2)) {
1398 int i;
1400 for (i = 1; res && (i < nch); i += 2)
1401 res = (validate_semi(CHILD(tree, i))
1402 && validate_small_stmt(CHILD(tree, i + 1)));
1404 return (res);
1406 } /* validate_simple_stmt() */
1409 static int
1410 validate_small_stmt(tree)
1411 node *tree;
1413 int nch = NCH(tree);
1414 int res = (validate_numnodes(tree, 1, "small_stmt")
1415 && ((TYPE(CHILD(tree, 0)) == expr_stmt)
1416 || (TYPE(CHILD(tree, 0)) == print_stmt)
1417 || (TYPE(CHILD(tree, 0)) == del_stmt)
1418 || (TYPE(CHILD(tree, 0)) == pass_stmt)
1419 || (TYPE(CHILD(tree, 0)) == flow_stmt)
1420 || (TYPE(CHILD(tree, 0)) == import_stmt)
1421 || (TYPE(CHILD(tree, 0)) == global_stmt)
1422 || (TYPE(CHILD(tree, 0)) == assert_stmt)
1423 || (TYPE(CHILD(tree, 0)) == exec_stmt)));
1425 if (res)
1426 res = validate_node(CHILD(tree, 0));
1427 else if (nch == 1) {
1428 char buffer[60];
1429 (void) sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
1430 TYPE(CHILD(tree, 0)));
1431 err_string(buffer);
1433 return (res);
1435 } /* validate_small_stmt */
1438 /* compound_stmt:
1439 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1441 static int
1442 validate_compound_stmt(tree)
1443 node *tree;
1445 int res = (validate_ntype(tree, compound_stmt)
1446 && validate_numnodes(tree, 1, "compound_stmt"));
1448 if (!res)
1449 return (0);
1451 tree = CHILD(tree, 0);
1452 res = ((TYPE(tree) == if_stmt)
1453 || (TYPE(tree) == while_stmt)
1454 || (TYPE(tree) == for_stmt)
1455 || (TYPE(tree) == try_stmt)
1456 || (TYPE(tree) == funcdef)
1457 || (TYPE(tree) == classdef));
1458 if (res)
1459 res = validate_node(tree);
1460 else {
1461 char buffer[60];
1462 (void) sprintf(buffer, "Illegal compound statement type: %d.",
1463 TYPE(tree));
1464 err_string(buffer);
1466 return (res);
1468 } /* validate_compound_stmt() */
1471 static int
1472 validate_expr_stmt(tree)
1473 node *tree;
1475 int j;
1476 int nch = NCH(tree);
1477 int res = (validate_ntype(tree, expr_stmt)
1478 && is_odd(nch)
1479 && validate_testlist(CHILD(tree, 0)));
1481 for (j = 1; res && (j < nch); j += 2)
1482 res = (validate_equal(CHILD(tree, j))
1483 && validate_testlist(CHILD(tree, j + 1)));
1485 return (res);
1487 } /* validate_expr_stmt() */
1490 /* print_stmt:
1492 * 'print' (test ',')* [test]
1495 static int
1496 validate_print_stmt(tree)
1497 node *tree;
1499 int j;
1500 int nch = NCH(tree);
1501 int res = (validate_ntype(tree, print_stmt)
1502 && (nch != 0)
1503 && validate_name(CHILD(tree, 0), "print"));
1505 if (res && is_even(nch)) {
1506 res = validate_test(CHILD(tree, nch - 1));
1507 --nch;
1509 else if (!res && !PyErr_Occurred())
1510 (void) validate_numnodes(tree, 1, "print_stmt");
1511 for (j = 1; res && (j < nch); j += 2)
1512 res = (validate_test(CHILD(tree, j))
1513 && validate_ntype(CHILD(tree, j + 1), COMMA));
1515 return (res);
1517 } /* validate_print_stmt() */
1520 static int
1521 validate_del_stmt(tree)
1522 node *tree;
1524 return (validate_numnodes(tree, 2, "del_stmt")
1525 && validate_name(CHILD(tree, 0), "del")
1526 && validate_exprlist(CHILD(tree, 1)));
1528 } /* validate_del_stmt() */
1531 static int
1532 validate_return_stmt(tree)
1533 node *tree;
1535 int nch = NCH(tree);
1536 int res = (validate_ntype(tree, return_stmt)
1537 && ((nch == 1) || (nch == 2))
1538 && validate_name(CHILD(tree, 0), "return"));
1540 if (res && (nch == 2))
1541 res = validate_testlist(CHILD(tree, 1));
1543 return (res);
1545 } /* validate_return_stmt() */
1548 static int
1549 validate_raise_stmt(tree)
1550 node *tree;
1552 int nch = NCH(tree);
1553 int res = (validate_ntype(tree, raise_stmt)
1554 && ((nch == 1) || (nch == 2) || (nch == 4) || (nch == 6)));
1556 if (res) {
1557 res = validate_name(CHILD(tree, 0), "raise");
1558 if (res && (nch >= 2))
1559 res = validate_test(CHILD(tree, 1));
1560 if (res && nch > 2) {
1561 res = (validate_comma(CHILD(tree, 2))
1562 && validate_test(CHILD(tree, 3)));
1563 if (res && (nch > 4))
1564 res = (validate_comma(CHILD(tree, 4))
1565 && validate_test(CHILD(tree, 5)));
1568 else
1569 (void) validate_numnodes(tree, 2, "raise");
1570 if (res && (nch == 4))
1571 res = (validate_comma(CHILD(tree, 2))
1572 && validate_test(CHILD(tree, 3)));
1574 return (res);
1576 } /* validate_raise_stmt() */
1579 /* import_stmt:
1581 * 'import' dotted_name (',' dotted_name)*
1582 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1584 static int
1585 validate_import_stmt(tree)
1586 node *tree;
1588 int nch = NCH(tree);
1589 int res = (validate_ntype(tree, import_stmt)
1590 && (nch >= 2) && is_even(nch)
1591 && validate_ntype(CHILD(tree, 0), NAME)
1592 && validate_ntype(CHILD(tree, 1), dotted_name));
1594 if (res && (strcmp(STR(CHILD(tree, 0)), "import") == 0)) {
1595 int j;
1597 for (j = 2; res && (j < nch); j += 2)
1598 res = (validate_comma(CHILD(tree, j))
1599 && validate_ntype(CHILD(tree, j + 1), dotted_name));
1601 else if (res && validate_name(CHILD(tree, 0), "from")) {
1602 res = ((nch >= 4) && is_even(nch)
1603 && validate_name(CHILD(tree, 2), "import"));
1604 if (nch == 4) {
1605 res = ((TYPE(CHILD(tree, 3)) == NAME)
1606 || (TYPE(CHILD(tree, 3)) == STAR));
1607 if (!res)
1608 err_string("Illegal import statement.");
1610 else {
1611 /* 'from' NAME 'import' NAME (',' NAME)+ */
1612 int j;
1613 res = validate_ntype(CHILD(tree, 3), NAME);
1614 for (j = 4; res && (j < nch); j += 2)
1615 res = (validate_comma(CHILD(tree, j))
1616 && validate_ntype(CHILD(tree, j + 1), NAME));
1619 else
1620 res = 0;
1622 return (res);
1624 } /* validate_import_stmt() */
1627 static int
1628 validate_global_stmt(tree)
1629 node *tree;
1631 int j;
1632 int nch = NCH(tree);
1633 int res = (validate_ntype(tree, global_stmt)
1634 && is_even(nch) && (nch >= 2));
1636 if (res)
1637 res = (validate_name(CHILD(tree, 0), "global")
1638 && validate_ntype(CHILD(tree, 1), NAME));
1639 for (j = 2; res && (j < nch); j += 2)
1640 res = (validate_comma(CHILD(tree, j))
1641 && validate_ntype(CHILD(tree, j + 1), NAME));
1643 return (res);
1645 } /* validate_global_stmt() */
1648 /* exec_stmt:
1650 * 'exec' expr ['in' test [',' test]]
1652 static int
1653 validate_exec_stmt(tree)
1654 node *tree;
1656 int nch = NCH(tree);
1657 int res = (validate_ntype(tree, exec_stmt)
1658 && ((nch == 2) || (nch == 4) || (nch == 6))
1659 && validate_name(CHILD(tree, 0), "exec")
1660 && validate_expr(CHILD(tree, 1)));
1662 if (!res && !PyErr_Occurred())
1663 err_string("Illegal exec statement.");
1664 if (res && (nch > 2))
1665 res = (validate_name(CHILD(tree, 2), "in")
1666 && validate_test(CHILD(tree, 3)));
1667 if (res && (nch == 6))
1668 res = (validate_comma(CHILD(tree, 4))
1669 && validate_test(CHILD(tree, 5)));
1671 return (res);
1673 } /* validate_exec_stmt() */
1676 /* assert_stmt:
1678 * 'assert' test [',' test]
1680 static int
1681 validate_assert_stmt(tree)
1682 node *tree;
1684 int nch = NCH(tree);
1685 int res = (validate_ntype(tree, assert_stmt)
1686 && ((nch == 2) || (nch == 4))
1687 && (validate_name(CHILD(tree, 0), "__assert__") ||
1688 validate_name(CHILD(tree, 0), "assert"))
1689 && validate_test(CHILD(tree, 1)));
1691 if (!res && !PyErr_Occurred())
1692 err_string("Illegal assert statement.");
1693 if (res && (nch > 2))
1694 res = (validate_comma(CHILD(tree, 2))
1695 && validate_test(CHILD(tree, 3)));
1697 return (res);
1699 } /* validate_assert_stmt() */
1702 static int
1703 validate_while(tree)
1704 node *tree;
1706 int nch = NCH(tree);
1707 int res = (validate_ntype(tree, while_stmt)
1708 && ((nch == 4) || (nch == 7))
1709 && validate_name(CHILD(tree, 0), "while")
1710 && validate_test(CHILD(tree, 1))
1711 && validate_colon(CHILD(tree, 2))
1712 && validate_suite(CHILD(tree, 3)));
1714 if (res && (nch == 7))
1715 res = (validate_name(CHILD(tree, 4), "else")
1716 && validate_colon(CHILD(tree, 5))
1717 && validate_suite(CHILD(tree, 6)));
1719 return (res);
1721 } /* validate_while() */
1724 static int
1725 validate_for(tree)
1726 node *tree;
1728 int nch = NCH(tree);
1729 int res = (validate_ntype(tree, for_stmt)
1730 && ((nch == 6) || (nch == 9))
1731 && validate_name(CHILD(tree, 0), "for")
1732 && validate_exprlist(CHILD(tree, 1))
1733 && validate_name(CHILD(tree, 2), "in")
1734 && validate_testlist(CHILD(tree, 3))
1735 && validate_colon(CHILD(tree, 4))
1736 && validate_suite(CHILD(tree, 5)));
1738 if (res && (nch == 9))
1739 res = (validate_name(CHILD(tree, 6), "else")
1740 && validate_colon(CHILD(tree, 7))
1741 && validate_suite(CHILD(tree, 8)));
1743 return (res);
1745 } /* validate_for() */
1748 /* try_stmt:
1749 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1750 * | 'try' ':' suite 'finally' ':' suite
1753 static int
1754 validate_try(tree)
1755 node *tree;
1757 int nch = NCH(tree);
1758 int pos = 3;
1759 int res = (validate_ntype(tree, try_stmt)
1760 && (nch >= 6) && ((nch % 3) == 0));
1762 if (res)
1763 res = (validate_name(CHILD(tree, 0), "try")
1764 && validate_colon(CHILD(tree, 1))
1765 && validate_suite(CHILD(tree, 2))
1766 && validate_colon(CHILD(tree, nch - 2))
1767 && validate_suite(CHILD(tree, nch - 1)));
1768 else {
1769 const char* name = "execpt";
1770 char buffer[60];
1771 if (TYPE(CHILD(tree, nch - 3)) != except_clause)
1772 name = STR(CHILD(tree, nch - 3));
1773 (void) sprintf(buffer,
1774 "Illegal number of children for try/%s node.", name);
1775 err_string(buffer);
1777 /* Skip past except_clause sections: */
1778 while (res && (TYPE(CHILD(tree, pos)) == except_clause)) {
1779 res = (validate_except_clause(CHILD(tree, pos))
1780 && validate_colon(CHILD(tree, pos + 1))
1781 && validate_suite(CHILD(tree, pos + 2)));
1782 pos += 3;
1784 if (res && (pos < nch)) {
1785 res = validate_ntype(CHILD(tree, pos), NAME);
1786 if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0))
1787 res = (validate_numnodes(tree, 6, "try/finally")
1788 && validate_colon(CHILD(tree, 4))
1789 && validate_suite(CHILD(tree, 5)));
1790 else if (res) {
1791 if (nch == (pos + 3)) {
1792 res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0)
1793 || (strcmp(STR(CHILD(tree, pos)), "else") == 0));
1794 if (!res)
1795 err_string("Illegal trailing triple in try statement.");
1797 else if (nch == (pos + 6)) {
1798 res = (validate_name(CHILD(tree, pos), "except")
1799 && validate_colon(CHILD(tree, pos + 1))
1800 && validate_suite(CHILD(tree, pos + 2))
1801 && validate_name(CHILD(tree, pos + 3), "else"));
1803 else
1804 res = validate_numnodes(tree, pos + 3, "try/except");
1807 return (res);
1809 } /* validate_try() */
1812 static int
1813 validate_except_clause(tree)
1814 node *tree;
1816 int nch = NCH(tree);
1817 int res = (validate_ntype(tree, except_clause)
1818 && ((nch == 1) || (nch == 2) || (nch == 4))
1819 && validate_name(CHILD(tree, 0), "except"));
1821 if (res && (nch > 1))
1822 res = validate_test(CHILD(tree, 1));
1823 if (res && (nch == 4))
1824 res = (validate_comma(CHILD(tree, 2))
1825 && validate_test(CHILD(tree, 3)));
1827 return (res);
1829 } /* validate_except_clause() */
1832 static int
1833 validate_test(tree)
1834 node *tree;
1836 int nch = NCH(tree);
1837 int res = validate_ntype(tree, test) && is_odd(nch);
1839 if (res && (TYPE(CHILD(tree, 0)) == lambdef))
1840 res = ((nch == 1)
1841 && validate_lambdef(CHILD(tree, 0)));
1842 else if (res) {
1843 int pos;
1844 res = validate_and_test(CHILD(tree, 0));
1845 for (pos = 1; res && (pos < nch); pos += 2)
1846 res = (validate_name(CHILD(tree, pos), "or")
1847 && validate_and_test(CHILD(tree, pos + 1)));
1849 return (res);
1851 } /* validate_test() */
1854 static int
1855 validate_and_test(tree)
1856 node *tree;
1858 int pos;
1859 int nch = NCH(tree);
1860 int res = (validate_ntype(tree, and_test)
1861 && is_odd(nch)
1862 && validate_not_test(CHILD(tree, 0)));
1864 for (pos = 1; res && (pos < nch); pos += 2)
1865 res = (validate_name(CHILD(tree, pos), "and")
1866 && validate_not_test(CHILD(tree, 0)));
1868 return (res);
1870 } /* validate_and_test() */
1873 static int
1874 validate_not_test(tree)
1875 node *tree;
1877 int nch = NCH(tree);
1878 int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2));
1880 if (res) {
1881 if (nch == 2)
1882 res = (validate_name(CHILD(tree, 0), "not")
1883 && validate_not_test(CHILD(tree, 1)));
1884 else if (nch == 1)
1885 res = validate_comparison(CHILD(tree, 0));
1887 return (res);
1889 } /* validate_not_test() */
1892 static int
1893 validate_comparison(tree)
1894 node *tree;
1896 int pos;
1897 int nch = NCH(tree);
1898 int res = (validate_ntype(tree, comparison)
1899 && is_odd(nch)
1900 && validate_expr(CHILD(tree, 0)));
1902 for (pos = 1; res && (pos < nch); pos += 2)
1903 res = (validate_comp_op(CHILD(tree, pos))
1904 && validate_expr(CHILD(tree, pos + 1)));
1906 return (res);
1908 } /* validate_comparison() */
1911 static int
1912 validate_comp_op(tree)
1913 node *tree;
1915 int res = 0;
1916 int nch = NCH(tree);
1918 if (!validate_ntype(tree, comp_op))
1919 return (0);
1920 if (nch == 1) {
1922 * Only child will be a terminal with a well-defined symbolic name
1923 * or a NAME with a string of either 'is' or 'in'
1925 tree = CHILD(tree, 0);
1926 switch (TYPE(tree)) {
1927 case LESS:
1928 case GREATER:
1929 case EQEQUAL:
1930 case EQUAL:
1931 case LESSEQUAL:
1932 case GREATEREQUAL:
1933 case NOTEQUAL:
1934 res = 1;
1935 break;
1936 case NAME:
1937 res = ((strcmp(STR(tree), "in") == 0)
1938 || (strcmp(STR(tree), "is") == 0));
1939 if (!res) {
1940 char buff[128];
1941 (void) sprintf(buff, "Illegal operator: '%s'.", STR(tree));
1942 err_string(buff);
1944 break;
1945 default:
1946 err_string("Illegal comparison operator type.");
1947 break;
1950 else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) {
1951 res = (validate_ntype(CHILD(tree, 0), NAME)
1952 && validate_ntype(CHILD(tree, 1), NAME)
1953 && (((strcmp(STR(CHILD(tree, 0)), "is") == 0)
1954 && (strcmp(STR(CHILD(tree, 1)), "not") == 0))
1955 || ((strcmp(STR(CHILD(tree, 0)), "not") == 0)
1956 && (strcmp(STR(CHILD(tree, 1)), "in") == 0))));
1957 if (!res && !PyErr_Occurred())
1958 err_string("Unknown comparison operator.");
1960 return (res);
1962 } /* validate_comp_op() */
1965 static int
1966 validate_expr(tree)
1967 node *tree;
1969 int j;
1970 int nch = NCH(tree);
1971 int res = (validate_ntype(tree, expr)
1972 && is_odd(nch)
1973 && validate_xor_expr(CHILD(tree, 0)));
1975 for (j = 2; res && (j < nch); j += 2)
1976 res = (validate_xor_expr(CHILD(tree, j))
1977 && validate_vbar(CHILD(tree, j - 1)));
1979 return (res);
1981 } /* validate_expr() */
1984 static int
1985 validate_xor_expr(tree)
1986 node *tree;
1988 int j;
1989 int nch = NCH(tree);
1990 int res = (validate_ntype(tree, xor_expr)
1991 && is_odd(nch)
1992 && validate_and_expr(CHILD(tree, 0)));
1994 for (j = 2; res && (j < nch); j += 2)
1995 res = (validate_circumflex(CHILD(tree, j - 1))
1996 && validate_and_expr(CHILD(tree, j)));
1998 return (res);
2000 } /* validate_xor_expr() */
2003 static int
2004 validate_and_expr(tree)
2005 node *tree;
2007 int pos;
2008 int nch = NCH(tree);
2009 int res = (validate_ntype(tree, and_expr)
2010 && is_odd(nch)
2011 && validate_shift_expr(CHILD(tree, 0)));
2013 for (pos = 1; res && (pos < nch); pos += 2)
2014 res = (validate_ampersand(CHILD(tree, pos))
2015 && validate_shift_expr(CHILD(tree, pos + 1)));
2017 return (res);
2019 } /* validate_and_expr() */
2022 static int
2023 validate_chain_two_ops(tree, termvalid, op1, op2)
2024 node *tree;
2025 int (*termvalid)();
2026 int op1;
2027 int op2;
2029 int pos = 1;
2030 int nch = NCH(tree);
2031 int res = (is_odd(nch)
2032 && (*termvalid)(CHILD(tree, 0)));
2034 for ( ; res && (pos < nch); pos += 2) {
2035 if (TYPE(CHILD(tree, pos)) != op1)
2036 res = validate_ntype(CHILD(tree, pos), op2);
2037 if (res)
2038 res = (*termvalid)(CHILD(tree, pos + 1));
2040 return (res);
2042 } /* validate_chain_two_ops() */
2045 static int
2046 validate_shift_expr(tree)
2047 node *tree;
2049 return (validate_ntype(tree, shift_expr)
2050 && validate_chain_two_ops(tree, validate_arith_expr,
2051 LEFTSHIFT, RIGHTSHIFT));
2053 } /* validate_shift_expr() */
2056 static int
2057 validate_arith_expr(tree)
2058 node *tree;
2060 return (validate_ntype(tree, arith_expr)
2061 && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));
2063 } /* validate_arith_expr() */
2066 static int
2067 validate_term(tree)
2068 node *tree;
2070 int pos = 1;
2071 int nch = NCH(tree);
2072 int res = (validate_ntype(tree, term)
2073 && is_odd(nch)
2074 && validate_factor(CHILD(tree, 0)));
2076 for ( ; res && (pos < nch); pos += 2)
2077 res = (((TYPE(CHILD(tree, pos)) == STAR)
2078 || (TYPE(CHILD(tree, pos)) == SLASH)
2079 || (TYPE(CHILD(tree, pos)) == PERCENT))
2080 && validate_factor(CHILD(tree, pos + 1)));
2082 return (res);
2084 } /* validate_term() */
2087 /* factor:
2089 * factor: ('+'|'-'|'~') factor | power
2091 static int
2092 validate_factor(tree)
2093 node *tree;
2095 int nch = NCH(tree);
2096 int res = (validate_ntype(tree, factor)
2097 && (((nch == 2)
2098 && ((TYPE(CHILD(tree, 0)) == PLUS)
2099 || (TYPE(CHILD(tree, 0)) == MINUS)
2100 || (TYPE(CHILD(tree, 0)) == TILDE))
2101 && validate_factor(CHILD(tree, 1)))
2102 || ((nch == 1)
2103 && validate_power(CHILD(tree, 0)))));
2104 return (res);
2106 } /* validate_factor() */
2109 /* power:
2111 * power: atom trailer* ('**' factor)*
2113 static int
2114 validate_power(tree)
2115 node *tree;
2117 int pos = 1;
2118 int nch = NCH(tree);
2119 int res = (validate_ntype(tree, power) && (nch >= 1)
2120 && validate_atom(CHILD(tree, 0)));
2122 while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer))
2123 res = validate_trailer(CHILD(tree, pos++));
2124 if (res && (pos < nch)) {
2125 if (!is_even(nch - pos)) {
2126 err_string("Illegal number of nodes for 'power'.");
2127 return (0);
2129 for ( ; res && (pos < (nch - 1)); pos += 2)
2130 res = (validate_doublestar(CHILD(tree, pos))
2131 && validate_factor(CHILD(tree, pos + 1)));
2133 return (res);
2135 } /* validate_power() */
2138 static int
2139 validate_atom(tree)
2140 node *tree;
2142 int pos;
2143 int nch = NCH(tree);
2144 int res = validate_ntype(tree, atom) && (nch >= 1);
2146 if (res) {
2147 switch (TYPE(CHILD(tree, 0))) {
2148 case LPAR:
2149 res = ((nch <= 3)
2150 && (validate_rparen(CHILD(tree, nch - 1))));
2152 if (res && (nch == 3))
2153 res = validate_testlist(CHILD(tree, 1));
2154 break;
2155 case LSQB:
2156 res = ((nch <= 3)
2157 && validate_ntype(CHILD(tree, nch - 1), RSQB));
2159 if (res && (nch == 3))
2160 res = validate_testlist(CHILD(tree, 1));
2161 break;
2162 case LBRACE:
2163 res = ((nch <= 3)
2164 && validate_ntype(CHILD(tree, nch - 1), RBRACE));
2166 if (res && (nch == 3))
2167 res = validate_dictmaker(CHILD(tree, 1));
2168 break;
2169 case BACKQUOTE:
2170 res = ((nch == 3)
2171 && validate_testlist(CHILD(tree, 1))
2172 && validate_ntype(CHILD(tree, 2), BACKQUOTE));
2173 break;
2174 case NAME:
2175 case NUMBER:
2176 res = (nch == 1);
2177 break;
2178 case STRING:
2179 for (pos = 1; res && (pos < nch); ++pos)
2180 res = validate_ntype(CHILD(tree, pos), STRING);
2181 break;
2182 default:
2183 res = 0;
2184 break;
2187 return (res);
2189 } /* validate_atom() */
2192 /* funcdef:
2193 * 'def' NAME parameters ':' suite
2196 static int
2197 validate_funcdef(tree)
2198 node *tree;
2200 return (validate_ntype(tree, funcdef)
2201 && validate_numnodes(tree, 5, "funcdef")
2202 && validate_name(CHILD(tree, 0), "def")
2203 && validate_ntype(CHILD(tree, 1), NAME)
2204 && validate_colon(CHILD(tree, 3))
2205 && validate_parameters(CHILD(tree, 2))
2206 && validate_suite(CHILD(tree, 4)));
2208 } /* validate_funcdef() */
2211 static int
2212 validate_lambdef(tree)
2213 node *tree;
2215 int nch = NCH(tree);
2216 int res = (validate_ntype(tree, lambdef)
2217 && ((nch == 3) || (nch == 4))
2218 && validate_name(CHILD(tree, 0), "lambda")
2219 && validate_colon(CHILD(tree, nch - 2))
2220 && validate_test(CHILD(tree, nch - 1)));
2222 if (res && (nch == 4))
2223 res = validate_varargslist(CHILD(tree, 1));
2224 else if (!res && !PyErr_Occurred())
2225 (void) validate_numnodes(tree, 3, "lambdef");
2227 return (res);
2229 } /* validate_lambdef() */
2232 /* arglist:
2234 * argument (',' argument)* [',']
2236 static int
2237 validate_arglist(tree)
2238 node *tree;
2240 return (validate_repeating_list(tree, arglist,
2241 validate_argument, "arglist"));
2243 } /* validate_arglist() */
2247 /* argument:
2249 * [test '='] test
2251 static int
2252 validate_argument(tree)
2253 node *tree;
2255 int nch = NCH(tree);
2256 int res = (validate_ntype(tree, argument)
2257 && ((nch == 1) || (nch == 3))
2258 && validate_test(CHILD(tree, 0)));
2260 if (res && (nch == 3))
2261 res = (validate_equal(CHILD(tree, 1))
2262 && validate_test(CHILD(tree, 2)));
2264 return (res);
2266 } /* validate_argument() */
2270 /* trailer:
2272 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
2274 static int
2275 validate_trailer(tree)
2276 node *tree;
2278 int nch = NCH(tree);
2279 int res = validate_ntype(tree, trailer) && ((nch == 2) || (nch == 3));
2281 if (res) {
2282 switch (TYPE(CHILD(tree, 0))) {
2283 case LPAR:
2284 res = validate_rparen(CHILD(tree, nch - 1));
2285 if (res && (nch == 3))
2286 res = validate_arglist(CHILD(tree, 1));
2287 break;
2288 case LSQB:
2289 res = (validate_numnodes(tree, 3, "trailer")
2290 && validate_subscriptlist(CHILD(tree, 1))
2291 && validate_ntype(CHILD(tree, 2), RSQB));
2292 break;
2293 case DOT:
2294 res = (validate_numnodes(tree, 2, "trailer")
2295 && validate_ntype(CHILD(tree, 1), NAME));
2296 break;
2297 default:
2298 res = 0;
2299 break;
2302 else
2303 (void) validate_numnodes(tree, 2, "trailer");
2305 return (res);
2307 } /* validate_trailer() */
2310 /* subscriptlist:
2312 * subscript (',' subscript)* [',']
2314 static int
2315 validate_subscriptlist(tree)
2316 node *tree;
2318 return (validate_repeating_list(tree, subscriptlist,
2319 validate_subscript, "subscriptlist"));
2321 } /* validate_subscriptlist() */
2324 /* subscript:
2326 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
2328 static int
2329 validate_subscript(tree)
2330 node *tree;
2332 int offset = 0;
2333 int nch = NCH(tree);
2334 int res = validate_ntype(tree, subscript) && (nch >= 1) && (nch <= 4);
2336 if (!res) {
2337 if (!PyErr_Occurred())
2338 err_string("invalid number of arguments for subscript node");
2339 return (0);
2341 if (TYPE(CHILD(tree, 0)) == DOT)
2342 /* take care of ('.' '.' '.') possibility */
2343 return (validate_numnodes(tree, 3, "subscript")
2344 && validate_dot(CHILD(tree, 0))
2345 && validate_dot(CHILD(tree, 1))
2346 && validate_dot(CHILD(tree, 2)));
2347 if (nch == 1) {
2348 if (TYPE(CHILD(tree, 0)) == test)
2349 res = validate_test(CHILD(tree, 0));
2350 else
2351 res = validate_colon(CHILD(tree, 0));
2352 return (res);
2354 /* Must be [test] ':' [test] [sliceop],
2355 * but at least one of the optional components will
2356 * be present, but we don't know which yet.
2358 if ((TYPE(CHILD(tree, 0)) != COLON) || (nch == 4)) {
2359 res = validate_test(CHILD(tree, 0));
2360 offset = 1;
2362 if (res)
2363 res = validate_colon(CHILD(tree, offset));
2364 if (res) {
2365 int rem = nch - ++offset;
2366 if (rem) {
2367 if (TYPE(CHILD(tree, offset)) == test) {
2368 res = validate_test(CHILD(tree, offset));
2369 ++offset;
2370 --rem;
2372 if (res && rem)
2373 res = validate_sliceop(CHILD(tree, offset));
2376 return (res);
2378 } /* validate_subscript() */
2381 static int
2382 validate_sliceop(tree)
2383 node *tree;
2385 int nch = NCH(tree);
2386 int res = ((nch == 1) || validate_numnodes(tree, 2, "sliceop"))
2387 && validate_ntype(tree, sliceop);
2388 if (!res && !PyErr_Occurred()) {
2389 res = validate_numnodes(tree, 1, "sliceop");
2391 if (res)
2392 res = validate_colon(CHILD(tree, 0));
2393 if (res && (nch == 2))
2394 res = validate_test(CHILD(tree, 1));
2396 return (res);
2398 } /* validate_sliceop() */
2401 static int
2402 validate_exprlist(tree)
2403 node *tree;
2405 return (validate_repeating_list(tree, exprlist,
2406 validate_expr, "exprlist"));
2408 } /* validate_exprlist() */
2411 static int
2412 validate_dictmaker(tree)
2413 node *tree;
2415 int nch = NCH(tree);
2416 int res = (validate_ntype(tree, dictmaker)
2417 && (nch >= 3)
2418 && validate_test(CHILD(tree, 0))
2419 && validate_colon(CHILD(tree, 1))
2420 && validate_test(CHILD(tree, 2)));
2422 if (res && ((nch % 4) == 0))
2423 res = validate_comma(CHILD(tree, --nch));
2424 else if (res)
2425 res = ((nch % 4) == 3);
2427 if (res && (nch > 3)) {
2428 int pos = 3;
2429 /* ( ',' test ':' test )* */
2430 while (res && (pos < nch)) {
2431 res = (validate_comma(CHILD(tree, pos))
2432 && validate_test(CHILD(tree, pos + 1))
2433 && validate_colon(CHILD(tree, pos + 2))
2434 && validate_test(CHILD(tree, pos + 3)));
2435 pos += 4;
2438 return (res);
2440 } /* validate_dictmaker() */
2443 static int
2444 validate_eval_input(tree)
2445 node *tree;
2447 int pos;
2448 int nch = NCH(tree);
2449 int res = (validate_ntype(tree, eval_input)
2450 && (nch >= 2)
2451 && validate_testlist(CHILD(tree, 0))
2452 && validate_ntype(CHILD(tree, nch - 1), ENDMARKER));
2454 for (pos = 1; res && (pos < (nch - 1)); ++pos)
2455 res = validate_ntype(CHILD(tree, pos), NEWLINE);
2457 return (res);
2459 } /* validate_eval_input() */
2462 static int
2463 validate_node(tree)
2464 node *tree;
2466 int nch = 0; /* num. children on current node */
2467 int res = 1; /* result value */
2468 node* next = 0; /* node to process after this one */
2470 while (res & (tree != 0)) {
2471 nch = NCH(tree);
2472 next = 0;
2473 switch (TYPE(tree)) {
2475 * Definition nodes.
2477 case funcdef:
2478 res = validate_funcdef(tree);
2479 break;
2480 case classdef:
2481 res = validate_class(tree);
2482 break;
2484 * "Trivial" parse tree nodes.
2485 * (Why did I call these trivial?)
2487 case stmt:
2488 res = validate_stmt(tree);
2489 break;
2490 case small_stmt:
2492 * expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
2493 * | import_stmt | global_stmt | exec_stmt | assert_stmt
2495 res = validate_small_stmt(tree);
2496 break;
2497 case flow_stmt:
2498 res = (validate_numnodes(tree, 1, "flow_stmt")
2499 && ((TYPE(CHILD(tree, 0)) == break_stmt)
2500 || (TYPE(CHILD(tree, 0)) == continue_stmt)
2501 || (TYPE(CHILD(tree, 0)) == return_stmt)
2502 || (TYPE(CHILD(tree, 0)) == raise_stmt)));
2503 if (res)
2504 next = CHILD(tree, 0);
2505 else if (nch == 1)
2506 err_string("Illegal flow_stmt type.");
2507 break;
2509 * Compound statements.
2511 case simple_stmt:
2512 res = validate_simple_stmt(tree);
2513 break;
2514 case compound_stmt:
2515 res = validate_compound_stmt(tree);
2516 break;
2518 * Fundemental statements.
2520 case expr_stmt:
2521 res = validate_expr_stmt(tree);
2522 break;
2523 case print_stmt:
2524 res = validate_print_stmt(tree);
2525 break;
2526 case del_stmt:
2527 res = validate_del_stmt(tree);
2528 break;
2529 case pass_stmt:
2530 res = (validate_numnodes(tree, 1, "pass")
2531 && validate_name(CHILD(tree, 0), "pass"));
2532 break;
2533 case break_stmt:
2534 res = (validate_numnodes(tree, 1, "break")
2535 && validate_name(CHILD(tree, 0), "break"));
2536 break;
2537 case continue_stmt:
2538 res = (validate_numnodes(tree, 1, "continue")
2539 && validate_name(CHILD(tree, 0), "continue"));
2540 break;
2541 case return_stmt:
2542 res = validate_return_stmt(tree);
2543 break;
2544 case raise_stmt:
2545 res = validate_raise_stmt(tree);
2546 break;
2547 case import_stmt:
2548 res = validate_import_stmt(tree);
2549 break;
2550 case global_stmt:
2551 res = validate_global_stmt(tree);
2552 break;
2553 case exec_stmt:
2554 res = validate_exec_stmt(tree);
2555 break;
2556 case assert_stmt:
2557 res = validate_assert_stmt(tree);
2558 break;
2559 case if_stmt:
2560 res = validate_if(tree);
2561 break;
2562 case while_stmt:
2563 res = validate_while(tree);
2564 break;
2565 case for_stmt:
2566 res = validate_for(tree);
2567 break;
2568 case try_stmt:
2569 res = validate_try(tree);
2570 break;
2571 case suite:
2572 res = validate_suite(tree);
2573 break;
2575 * Expression nodes.
2577 case testlist:
2578 res = validate_testlist(tree);
2579 break;
2580 case test:
2581 res = validate_test(tree);
2582 break;
2583 case and_test:
2584 res = validate_and_test(tree);
2585 break;
2586 case not_test:
2587 res = validate_not_test(tree);
2588 break;
2589 case comparison:
2590 res = validate_comparison(tree);
2591 break;
2592 case exprlist:
2593 res = validate_exprlist(tree);
2594 break;
2595 case comp_op:
2596 res = validate_comp_op(tree);
2597 break;
2598 case expr:
2599 res = validate_expr(tree);
2600 break;
2601 case xor_expr:
2602 res = validate_xor_expr(tree);
2603 break;
2604 case and_expr:
2605 res = validate_and_expr(tree);
2606 break;
2607 case shift_expr:
2608 res = validate_shift_expr(tree);
2609 break;
2610 case arith_expr:
2611 res = validate_arith_expr(tree);
2612 break;
2613 case term:
2614 res = validate_term(tree);
2615 break;
2616 case factor:
2617 res = validate_factor(tree);
2618 break;
2619 case power:
2620 res = validate_power(tree);
2621 break;
2622 case atom:
2623 res = validate_atom(tree);
2624 break;
2626 default:
2627 /* Hopefully never reached! */
2628 err_string("Unrecogniged node type.");
2629 res = 0;
2630 break;
2632 tree = next;
2634 return (res);
2636 } /* validate_node() */
2639 static int
2640 validate_expr_tree(tree)
2641 node *tree;
2643 int res = validate_eval_input(tree);
2645 if (!res && !PyErr_Occurred())
2646 err_string("Could not validate expression tuple.");
2648 return (res);
2650 } /* validate_expr_tree() */
2653 /* file_input:
2654 * (NEWLINE | stmt)* ENDMARKER
2656 static int
2657 validate_file_input(tree)
2658 node *tree;
2660 int j = 0;
2661 int nch = NCH(tree) - 1;
2662 int res = ((nch >= 0)
2663 && validate_ntype(CHILD(tree, nch), ENDMARKER));
2665 for ( ; res && (j < nch); ++j) {
2666 if (TYPE(CHILD(tree, j)) == stmt)
2667 res = validate_stmt(CHILD(tree, j));
2668 else
2669 res = validate_newline(CHILD(tree, j));
2671 /* This stays in to prevent any internal failues from getting to the
2672 * user. Hopefully, this won't be needed. If a user reports getting
2673 * this, we have some debugging to do.
2675 if (!res && !PyErr_Occurred())
2676 err_string("VALIDATION FAILURE: report this to the maintainer!.");
2678 return (res);
2680 } /* validate_file_input() */
2683 static PyObject*
2684 pickle_constructor = NULL;
2687 static PyObject*
2688 parser__pickler(self, args)
2689 PyObject *self;
2690 PyObject *args;
2692 NOTE(ARGUNUSED(self))
2693 PyObject *result = NULL;
2694 PyObject *ast = NULL;
2696 if (PyArg_ParseTuple(args, "O!:_pickler", &PyAST_Type, &ast)) {
2697 PyObject *newargs;
2698 PyObject *tuple;
2700 if ((newargs = Py_BuildValue("Oi", ast, 1)) == NULL)
2701 goto finally;
2702 tuple = parser_ast2tuple((PyAST_Object*)NULL, newargs);
2703 if (tuple != NULL) {
2704 result = Py_BuildValue("O(O)", pickle_constructor, tuple);
2705 Py_DECREF(tuple);
2707 Py_DECREF(newargs);
2709 finally:
2710 return (result);
2712 } /* parser__pickler() */
2715 /* Functions exported by this module. Most of this should probably
2716 * be converted into an AST object with methods, but that is better
2717 * done directly in Python, allowing subclasses to be created directly.
2718 * We'd really have to write a wrapper around it all anyway to allow
2719 * inheritance.
2721 static PyMethodDef parser_functions[] = {
2722 {"ast2tuple", (PyCFunction)parser_ast2tuple, METH_VARARGS,
2723 "Creates a tuple-tree representation of an AST."},
2724 {"ast2list", (PyCFunction)parser_ast2list, METH_VARARGS,
2725 "Creates a list-tree representation of an AST."},
2726 {"compileast", (PyCFunction)parser_compileast, METH_VARARGS,
2727 "Compiles an AST object into a code object."},
2728 {"expr", (PyCFunction)parser_expr, METH_VARARGS,
2729 "Creates an AST object from an expression."},
2730 {"isexpr", (PyCFunction)parser_isexpr, METH_VARARGS,
2731 "Determines if an AST object was created from an expression."},
2732 {"issuite", (PyCFunction)parser_issuite, METH_VARARGS,
2733 "Determines if an AST object was created from a suite."},
2734 {"suite", (PyCFunction)parser_suite, METH_VARARGS,
2735 "Creates an AST object from a suite."},
2736 {"sequence2ast", (PyCFunction)parser_tuple2ast, METH_VARARGS,
2737 "Creates an AST object from a tree representation."},
2738 {"tuple2ast", (PyCFunction)parser_tuple2ast, METH_VARARGS,
2739 "Creates an AST object from a tree representation."},
2741 /* private stuff: support pickle module */
2742 {"_pickler", (PyCFunction)parser__pickler, METH_VARARGS,
2743 "Returns the pickle magic to allow ast objects to be pickled."},
2745 {NULL, NULL, 0, NULL}
2749 void
2750 initparser()
2752 PyObject* module;
2753 PyObject* dict;
2755 PyAST_Type.ob_type = &PyType_Type;
2756 module = Py_InitModule("parser", parser_functions);
2757 dict = PyModule_GetDict(module);
2759 parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
2761 if ((parser_error == 0)
2762 || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
2764 * This is serious.
2766 Py_FatalError("can't define parser.ParserError");
2769 * Nice to have, but don't cry if we fail.
2771 Py_INCREF(&PyAST_Type);
2772 PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
2774 PyDict_SetItemString(dict, "__copyright__",
2775 PyString_FromString(parser_copyright_string));
2776 PyDict_SetItemString(dict, "__doc__",
2777 PyString_FromString(parser_doc_string));
2778 PyDict_SetItemString(dict, "__version__",
2779 PyString_FromString(parser_version_string));
2781 parser_method_list = PyList_New(0);
2782 if (parser_method_list != NULL) {
2783 PyMethodDef *mdef = parser_methods;
2785 while (mdef->ml_name != NULL) {
2786 PyObject *temp = PyString_FromString(mdef->ml_name);
2787 if (temp != NULL) {
2788 PyList_Append(parser_method_list, temp);
2789 Py_DECREF(temp);
2791 ++mdef;
2795 /* register to support pickling */
2796 module = PyImport_ImportModule("copy_reg");
2797 if (module != NULL) {
2798 PyObject *func, *pickler;
2800 func = PyObject_GetAttrString(module, "pickle");
2801 pickle_constructor = PyDict_GetItemString(dict, "sequence2ast");
2802 pickler = PyDict_GetItemString(dict, "_pickler");
2803 Py_XINCREF(pickle_constructor);
2804 if ((func != NULL) && (pickle_constructor != NULL)
2805 && (pickler != NULL)) {
2806 PyObject *res;
2808 res = PyObject_CallFunction(
2809 func, "OOO", &PyAST_Type, pickler, pickle_constructor);
2810 Py_XDECREF(res);
2812 Py_XDECREF(func);
2813 Py_DECREF(module);
2815 } /* initparser() */