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
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() */
42 char *strdup
Py_PROTO((char *));
45 /* String constants used to initialize module attributes.
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.";
58 = "This is an interface to Python's internal parser.";
61 parser_version_string
= "0.4";
64 typedef PyObject
* (*SeqMaker
) Py_PROTO((int length
));
65 typedef int (*SeqInserter
) Py_PROTO((PyObject
* sequence
,
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,
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
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 ******************************************************************/
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? */
120 if (ISNONTERMINAL(TYPE(n
))) {
125 v
= mkseq(1 + NCH(n
));
128 w
= PyInt_FromLong(TYPE(n
));
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
);
138 return ((PyObject
*) NULL
);
140 (void) addelem(v
, i
+1, w
);
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
)));
150 (void) addelem(result
, 2, PyInt_FromLong(n
->n_lineno
));
155 PyErr_SetString(PyExc_SystemError
,
156 "unrecognized parse tree node type");
157 return ((PyObject
*) NULL
);
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.
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.
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 ? */
200 parser_free
Py_PROTO((PyAST_Object
*ast
));
203 parser_compare
Py_PROTO((PyAST_Object
*left
, PyAST_Object
*right
));
205 staticforward PyObject
*
206 parser_getattr
Py_PROTO((PyObject
*self
, char *name
));
210 PyTypeObject PyAST_Type
= {
212 PyObject_HEAD_INIT(NULL
)
215 (int) sizeof(PyAST_Object
), /* tp_basicsize */
217 (destructor
)parser_free
, /* tp_dealloc */
219 parser_getattr
, /* tp_getattr */
221 (cmpfunc
)parser_compare
, /* tp_compare */
223 0, /* tp_as_number */
224 0, /* tp_as_sequence */
225 0, /* tp_as_mapping */
232 /* Functions to access object as input/output buffer */
233 0, /* tp_as_buffer */
235 /* Space for future expansion */
239 "Intermediate representation of a Python parse tree."
245 parser_compare_nodes(left
, right
)
251 if (TYPE(left
) < TYPE(right
))
254 if (TYPE(right
) < TYPE(left
))
257 if (ISTERMINAL(TYPE(left
)))
258 return (strcmp(STR(left
), STR(right
)));
260 if (NCH(left
) < NCH(right
))
263 if (NCH(right
) < NCH(left
))
266 for (j
= 0; j
< NCH(left
); ++j
) {
267 int v
= parser_compare_nodes(CHILD(left
, j
), CHILD(right
, j
));
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.
285 parser_compare(left
, right
)
292 if ((left
== 0) || (right
== 0))
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
308 parser_newastobject(ast
, type
)
312 PyAST_Object
* o
= PyObject_NEW(PyAST_Object
, &PyAST_Type
);
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.
335 PyNode_Free(ast
->ast_node
);
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.
348 parser_ast2tuple(self
, args
)
352 PyObject
*line_option
= 0;
357 ok
= PyArg_ParseTuple(
358 args
, "O!|O:ast2tuple", &PyAST_Type
, &self
, &line_option
);
361 ok
= PyArg_ParseTuple(args
, "|O:totuple", &line_option
);
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
);
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.
386 parser_ast2list(self
, args
)
390 PyObject
*line_option
= 0;
395 ok
= PyArg_ParseTuple(
396 args
, "O!|O:ast2list", &PyAST_Type
, &self
, &line_option
);
398 ok
= PyArg_ParseTuple(args
, "|O:tolist", &line_option
);
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
);
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.
423 parser_compileast(self
, args
)
432 ok
= PyArg_ParseTuple(
433 args
, "O!|s:compileast", &PyAST_Type
, &self
, &str
);
435 ok
= PyArg_ParseTuple(args
, "|s:compile", &str
);
438 res
= (PyObject
*)PyNode_Compile(self
->ast_node
, str
);
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.
453 parser_isexpr(self
, args
)
461 ok
= PyArg_ParseTuple(args
, "O!:isexpr", &PyAST_Type
, &self
);
463 ok
= PyArg_ParseTuple(args
, ":isexpr");
466 /* Check to see if the AST represents an expression or not. */
467 res
= (self
->ast_type
== PyAST_EXPR
) ? Py_True
: Py_False
;
472 } /* parser_isexpr() */
476 parser_issuite(self
, args
)
484 ok
= PyArg_ParseTuple(args
, "O!:issuite", &PyAST_Type
, &self
);
486 ok
= PyArg_ParseTuple(args
, ":issuite");
489 /* Check to see if the AST represents an expression or not. */
490 res
= (self
->ast_type
== PyAST_EXPR
) ? Py_False
: Py_True
;
495 } /* parser_issuite() */
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
}
515 parser_method_list
= NULL
;
519 parser_getattr(self
, 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.
541 PyErr_SetString(parser_error
, message
);
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.
553 parser_do_parse(args
, type
)
560 if (PyArg_ParseTuple(args
, "s", &string
)) {
561 node
* n
= PyParser_SimpleParseString(string
,
563 ? eval_input
: file_input
);
566 res
= parser_newastobject(n
, type
);
568 err_string("Could not parse string.");
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.
584 parser_expr(self
, args
)
588 NOTE(ARGUNUSED(self
))
589 return (parser_do_parse(args
, PyAST_EXPR
));
591 } /* parser_expr() */
595 parser_suite(self
, 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
642 parser_tuple2ast(self
, args
)
646 NOTE(ARGUNUSED(self
))
653 if (!PyArg_ParseTuple(args
, "O:tuple2ast", &tuple
))
655 if (!PySequence_Check(tuple
)) {
656 PyErr_SetString(PyExc_ValueError
,
657 "tuple2ast() requires a single sequence argument");
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;
669 temp
= PySequence_GetItem(tuple
, 0);
670 ok
= (temp
!= NULL
) && PyInt_Check(temp
);
672 /* this is used after the initial checks: */
673 start_sym
= PyInt_AsLong(temp
);
677 temp
= PySequence_GetItem(tuple
, 1);
678 ok
= (temp
!= NULL
) && PySequence_Check(temp
);
682 temp
= PySequence_GetItem(tuple
, 1);
683 ok
= (temp
!= NULL
) && PyObject_Length(temp
) >= 2;
685 PyObject
*temp2
= PySequence_GetItem(temp
, 0);
687 ok
= PyInt_Check(temp2
);
693 /* If we've failed at some point, get out of here. */
695 err_string("malformed sequence for tuple2ast()");
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
);
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.");
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
749 check_terminal_tuple(elem
)
752 int len
= PyObject_Length(elem
);
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.";
772 elem
= Py_BuildValue("(os)", elem
, str
);
773 PyErr_SetObject(parser_error
, elem
);
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.
789 build_node_children(tuple
, root
, line_num
)
794 int len
= PyObject_Length(tuple
);
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
;
805 ok
= PySequence_Check(elem
);
807 PyObject
*temp
= PySequence_GetItem(elem
, 0);
811 ok
= PyInt_Check(temp
);
813 type
= PyInt_AsLong(temp
);
818 PyErr_SetObject(parser_error
,
819 Py_BuildValue("(os)", elem
,
820 "Illegal node construct."));
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);
831 (void) strcpy(strn
, PyString_AS_STRING(temp
));
834 if (PyObject_Length(elem
) == 3) {
835 PyObject
* temp
= PySequence_GetItem(elem
, 2);
836 *line_num
= PyInt_AsLong(temp
);
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."));
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
)) {
866 else if (type
== NEWLINE
) { /* It's true: we increment the */
867 ++(*line_num
); /* line number *after* the newline! */
873 } /* build_node_children() */
877 build_node_tree(tuple
)
881 PyObject
*temp
= PySequence_GetItem(tuple
, 0);
885 num
= PyInt_AsLong(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.
902 res
= PyNode_New(num
);
903 if (res
!= build_node_children(tuple
, res
, &line_num
)) {
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."));
918 } /* build_node_tree() */
922 #define VALIDATER(n) static int validate_/**/n Py_PROTO((node *tree))
924 #define VALIDATER(n) static int validate_##n Py_PROTO((node *tree))
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)
988 int res
= (TYPE(n
) == t
);
992 (void) sprintf(buffer
, "Expected node type %d, got %d.", t
, TYPE(n
));
997 } /* validate_ntype() */
1001 validate_numnodes(n
, num
, name
)
1004 const char *const name
;
1006 if (NCH(n
) != num
) {
1008 (void) sprintf(buff
, "Illegal number of children for %s node.", name
);
1011 return (NCH(n
) == num
);
1013 } /* validate_numnodes() */
1017 validate_terminal(terminal
, type
, string
)
1022 int res
= (validate_ntype(terminal
, type
)
1023 && ((string
== 0) || (strcmp(string
, STR(terminal
)) == 0)));
1025 if (!res
&& !PyErr_Occurred()) {
1027 (void) sprintf(buffer
, "Illegal terminal: expected \"%s\"", string
);
1032 } /* validate_terminal() */
1038 validate_repeating_list(tree
, ntype
, vfunc
, name
)
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
);
1052 res
= validate_comma(CHILD(tree
, --nch
));
1053 if (res
&& nch
> 1) {
1055 for ( ; res
&& pos
< nch
; pos
+= 2)
1056 res
= (validate_comma(CHILD(tree
, pos
))
1057 && vfunc(CHILD(tree
, pos
+ 1)));
1062 } /* validate_repeating_list() */
1068 * 'class' NAME ['(' testlist ')'] ':' suite
1071 validate_class(tree
)
1074 int nch
= NCH(tree
);
1075 int res
= validate_ntype(tree
, classdef
) && ((nch
== 4) || (nch
== 7));
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)));
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)));
1092 } /* validate_class() */
1096 * 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
1102 int nch
= NCH(tree
);
1103 int res
= (validate_ntype(tree
, if_stmt
)
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)));
1117 else if (!res
&& !PyErr_Occurred())
1118 (void) validate_numnodes(tree
, 4, "if");
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)+ ... */
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)));
1135 } /* validate_if() */
1139 * '(' [varargslist] ')'
1143 validate_parameters(tree
)
1146 int nch
= NCH(tree
);
1147 int res
= validate_ntype(tree
, parameters
) && ((nch
== 2) || (nch
== 3));
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));
1156 (void) validate_numnodes(tree
, 2, "parameters");
1160 } /* validate_parameters() */
1167 * | NEWLINE INDENT stmt+ DEDENT
1170 validate_suite(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));
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)) {
1187 --nch
; /* forget the DEDENT */
1188 for ( ; res
&& (i
< nch
); ++i
)
1189 res
= validate_stmt(CHILD(tree
, i
));
1192 res
= validate_numnodes(tree
, 4, "suite");
1196 } /* validate_suite() */
1200 validate_testlist(tree
)
1203 return (validate_repeating_list(tree
, testlist
,
1204 validate_test
, "testlist"));
1206 } /* validate_testlist() */
1209 /* VALIDATE(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])* [',']
1222 validate_varargslist(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)
1233 int remaining
= nch
;
1235 while (res
&& (TYPE(CHILD(tree
, pos
)) == fpdef
)) {
1236 res
= validate_fpdef(CHILD(tree
, pos
));
1238 if (TYPE(CHILD(tree
, pos
+ 1)) == EQUAL
) {
1239 res
= validate_test(CHILD(tree
, pos
+ 2));
1242 res
= res
&& validate_comma(CHILD(tree
, pos
+ 1));
1247 remaining
= nch
- pos
;
1248 res
= ((remaining
== 2) || (remaining
== 3)
1249 || (remaining
== 5) || (remaining
== 6));
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
));
1256 res
= validate_star(CHILD(tree
, pos
++));
1261 if (remaining
== 2) {
1262 res
= (validate_star(CHILD(tree
, pos
))
1263 && validate_ntype(CHILD(tree
, pos
+ 1), NAME
));
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)));
1273 res
= validate_ntype(CHILD(tree
, pos
+ 1), DOUBLESTAR
);
1277 if (!res
&& !PyErr_Occurred())
1278 err_string("Incorrect validation of variable arguments list.");
1281 /* fpdef ['=' test] (',' fpdef ['=' test])* [','] */
1282 if (TYPE(CHILD(tree
, nch
- 1)) == COMMA
)
1285 /* fpdef ['=' test] (',' fpdef ['=' test])* */
1287 && validate_fpdef(CHILD(tree
, 0)));
1289 if (res
&& (nch
> 1)) {
1291 if (TYPE(CHILD(tree
, 1)) == EQUAL
) {
1292 res
= validate_test(CHILD(tree
, 2));
1295 /* ... (',' fpdef ['=' test])* */
1296 for ( ; res
&& (pos
< nch
); pos
+= 2) {
1298 res
= (validate_comma(CHILD(tree
, pos
))
1299 && validate_fpdef(CHILD(tree
, pos
+ 1)));
1301 && ((nch
- pos
) > 2)
1302 && (TYPE(CHILD(tree
, pos
+ 2)) == EQUAL
)) {
1304 res
= validate_test(CHILD(tree
, pos
+ 3));
1311 err_string("Improperly formed argument list.");
1315 } /* validate_varargslist() */
1325 validate_fpdef(tree
)
1328 int nch
= NCH(tree
);
1329 int res
= validate_ntype(tree
, fpdef
);
1333 res
= validate_ntype(CHILD(tree
, 0), NAME
);
1335 res
= (validate_lparen(CHILD(tree
, 0))
1336 && validate_fplist(CHILD(tree
, 1))
1337 && validate_rparen(CHILD(tree
, 2)));
1339 res
= validate_numnodes(tree
, 1, "fpdef");
1343 } /* validate_fpdef() */
1347 validate_fplist(tree
)
1350 return (validate_repeating_list(tree
, fplist
,
1351 validate_fpdef
, "fplist"));
1353 } /* validate_fplist() */
1356 /* simple_stmt | compound_stmt
1363 int res
= (validate_ntype(tree
, stmt
)
1364 && validate_numnodes(tree
, 1, "stmt"));
1367 tree
= CHILD(tree
, 0);
1369 if (TYPE(tree
) == simple_stmt
)
1370 res
= validate_simple_stmt(tree
);
1372 res
= validate_compound_stmt(tree
);
1376 } /* validate_stmt() */
1379 /* small_stmt (';' small_stmt)* [';'] NEWLINE
1383 validate_simple_stmt(tree
)
1386 int nch
= NCH(tree
);
1387 int res
= (validate_ntype(tree
, simple_stmt
)
1389 && validate_small_stmt(CHILD(tree
, 0))
1390 && validate_newline(CHILD(tree
, nch
- 1)));
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)) {
1400 for (i
= 1; res
&& (i
< nch
); i
+= 2)
1401 res
= (validate_semi(CHILD(tree
, i
))
1402 && validate_small_stmt(CHILD(tree
, i
+ 1)));
1406 } /* validate_simple_stmt() */
1410 validate_small_stmt(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
)));
1426 res
= validate_node(CHILD(tree
, 0));
1427 else if (nch
== 1) {
1429 (void) sprintf(buffer
, "Unrecognized child node of small_stmt: %d.",
1430 TYPE(CHILD(tree
, 0)));
1435 } /* validate_small_stmt */
1439 * if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
1442 validate_compound_stmt(tree
)
1445 int res
= (validate_ntype(tree
, compound_stmt
)
1446 && validate_numnodes(tree
, 1, "compound_stmt"));
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
));
1459 res
= validate_node(tree
);
1462 (void) sprintf(buffer
, "Illegal compound statement type: %d.",
1468 } /* validate_compound_stmt() */
1472 validate_expr_stmt(tree
)
1476 int nch
= NCH(tree
);
1477 int res
= (validate_ntype(tree
, expr_stmt
)
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)));
1487 } /* validate_expr_stmt() */
1492 * 'print' (test ',')* [test]
1496 validate_print_stmt(tree
)
1500 int nch
= NCH(tree
);
1501 int res
= (validate_ntype(tree
, print_stmt
)
1503 && validate_name(CHILD(tree
, 0), "print"));
1505 if (res
&& is_even(nch
)) {
1506 res
= validate_test(CHILD(tree
, nch
- 1));
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
));
1517 } /* validate_print_stmt() */
1521 validate_del_stmt(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() */
1532 validate_return_stmt(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));
1545 } /* validate_return_stmt() */
1549 validate_raise_stmt(tree
)
1552 int nch
= NCH(tree
);
1553 int res
= (validate_ntype(tree
, raise_stmt
)
1554 && ((nch
== 1) || (nch
== 2) || (nch
== 4) || (nch
== 6)));
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)));
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)));
1576 } /* validate_raise_stmt() */
1581 * 'import' dotted_name (',' dotted_name)*
1582 * | 'from' dotted_name 'import' ('*' | NAME (',' NAME)*)
1585 validate_import_stmt(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)) {
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"));
1605 res
= ((TYPE(CHILD(tree
, 3)) == NAME
)
1606 || (TYPE(CHILD(tree
, 3)) == STAR
));
1608 err_string("Illegal import statement.");
1611 /* 'from' NAME 'import' NAME (',' NAME)+ */
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
));
1624 } /* validate_import_stmt() */
1628 validate_global_stmt(tree
)
1632 int nch
= NCH(tree
);
1633 int res
= (validate_ntype(tree
, global_stmt
)
1634 && is_even(nch
) && (nch
>= 2));
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
));
1645 } /* validate_global_stmt() */
1650 * 'exec' expr ['in' test [',' test]]
1653 validate_exec_stmt(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)));
1673 } /* validate_exec_stmt() */
1678 * 'assert' test [',' test]
1681 validate_assert_stmt(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)));
1699 } /* validate_assert_stmt() */
1703 validate_while(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)));
1721 } /* validate_while() */
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)));
1745 } /* validate_for() */
1749 * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
1750 * | 'try' ':' suite 'finally' ':' suite
1757 int nch
= NCH(tree
);
1759 int res
= (validate_ntype(tree
, try_stmt
)
1760 && (nch
>= 6) && ((nch
% 3) == 0));
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)));
1769 const char* name
= "execpt";
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
);
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)));
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)));
1791 if (nch
== (pos
+ 3)) {
1792 res
= ((strcmp(STR(CHILD(tree
, pos
)), "except") == 0)
1793 || (strcmp(STR(CHILD(tree
, pos
)), "else") == 0));
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"));
1804 res
= validate_numnodes(tree
, pos
+ 3, "try/except");
1809 } /* validate_try() */
1813 validate_except_clause(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)));
1829 } /* validate_except_clause() */
1836 int nch
= NCH(tree
);
1837 int res
= validate_ntype(tree
, test
) && is_odd(nch
);
1839 if (res
&& (TYPE(CHILD(tree
, 0)) == lambdef
))
1841 && validate_lambdef(CHILD(tree
, 0)));
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)));
1851 } /* validate_test() */
1855 validate_and_test(tree
)
1859 int nch
= NCH(tree
);
1860 int res
= (validate_ntype(tree
, and_test
)
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)));
1870 } /* validate_and_test() */
1874 validate_not_test(tree
)
1877 int nch
= NCH(tree
);
1878 int res
= validate_ntype(tree
, not_test
) && ((nch
== 1) || (nch
== 2));
1882 res
= (validate_name(CHILD(tree
, 0), "not")
1883 && validate_not_test(CHILD(tree
, 1)));
1885 res
= validate_comparison(CHILD(tree
, 0));
1889 } /* validate_not_test() */
1893 validate_comparison(tree
)
1897 int nch
= NCH(tree
);
1898 int res
= (validate_ntype(tree
, comparison
)
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)));
1908 } /* validate_comparison() */
1912 validate_comp_op(tree
)
1916 int nch
= NCH(tree
);
1918 if (!validate_ntype(tree
, comp_op
))
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
)) {
1937 res
= ((strcmp(STR(tree
), "in") == 0)
1938 || (strcmp(STR(tree
), "is") == 0));
1941 (void) sprintf(buff
, "Illegal operator: '%s'.", STR(tree
));
1946 err_string("Illegal comparison operator type.");
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.");
1962 } /* validate_comp_op() */
1970 int nch
= NCH(tree
);
1971 int res
= (validate_ntype(tree
, expr
)
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)));
1981 } /* validate_expr() */
1985 validate_xor_expr(tree
)
1989 int nch
= NCH(tree
);
1990 int res
= (validate_ntype(tree
, xor_expr
)
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
)));
2000 } /* validate_xor_expr() */
2004 validate_and_expr(tree
)
2008 int nch
= NCH(tree
);
2009 int res
= (validate_ntype(tree
, and_expr
)
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)));
2019 } /* validate_and_expr() */
2023 validate_chain_two_ops(tree
, termvalid
, op1
, op2
)
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
);
2038 res
= (*termvalid
)(CHILD(tree
, pos
+ 1));
2042 } /* validate_chain_two_ops() */
2046 validate_shift_expr(tree
)
2049 return (validate_ntype(tree
, shift_expr
)
2050 && validate_chain_two_ops(tree
, validate_arith_expr
,
2051 LEFTSHIFT
, RIGHTSHIFT
));
2053 } /* validate_shift_expr() */
2057 validate_arith_expr(tree
)
2060 return (validate_ntype(tree
, arith_expr
)
2061 && validate_chain_two_ops(tree
, validate_term
, PLUS
, MINUS
));
2063 } /* validate_arith_expr() */
2071 int nch
= NCH(tree
);
2072 int res
= (validate_ntype(tree
, term
)
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)));
2084 } /* validate_term() */
2089 * factor: ('+'|'-'|'~') factor | power
2092 validate_factor(tree
)
2095 int nch
= NCH(tree
);
2096 int res
= (validate_ntype(tree
, factor
)
2098 && ((TYPE(CHILD(tree
, 0)) == PLUS
)
2099 || (TYPE(CHILD(tree
, 0)) == MINUS
)
2100 || (TYPE(CHILD(tree
, 0)) == TILDE
))
2101 && validate_factor(CHILD(tree
, 1)))
2103 && validate_power(CHILD(tree
, 0)))));
2106 } /* validate_factor() */
2111 * power: atom trailer* ('**' factor)*
2114 validate_power(tree
)
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'.");
2129 for ( ; res
&& (pos
< (nch
- 1)); pos
+= 2)
2130 res
= (validate_doublestar(CHILD(tree
, pos
))
2131 && validate_factor(CHILD(tree
, pos
+ 1)));
2135 } /* validate_power() */
2143 int nch
= NCH(tree
);
2144 int res
= validate_ntype(tree
, atom
) && (nch
>= 1);
2147 switch (TYPE(CHILD(tree
, 0))) {
2150 && (validate_rparen(CHILD(tree
, nch
- 1))));
2152 if (res
&& (nch
== 3))
2153 res
= validate_testlist(CHILD(tree
, 1));
2157 && validate_ntype(CHILD(tree
, nch
- 1), RSQB
));
2159 if (res
&& (nch
== 3))
2160 res
= validate_testlist(CHILD(tree
, 1));
2164 && validate_ntype(CHILD(tree
, nch
- 1), RBRACE
));
2166 if (res
&& (nch
== 3))
2167 res
= validate_dictmaker(CHILD(tree
, 1));
2171 && validate_testlist(CHILD(tree
, 1))
2172 && validate_ntype(CHILD(tree
, 2), BACKQUOTE
));
2179 for (pos
= 1; res
&& (pos
< nch
); ++pos
)
2180 res
= validate_ntype(CHILD(tree
, pos
), STRING
);
2189 } /* validate_atom() */
2193 * 'def' NAME parameters ':' suite
2197 validate_funcdef(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() */
2212 validate_lambdef(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");
2229 } /* validate_lambdef() */
2234 * argument (',' argument)* [',']
2237 validate_arglist(tree
)
2240 return (validate_repeating_list(tree
, arglist
,
2241 validate_argument
, "arglist"));
2243 } /* validate_arglist() */
2252 validate_argument(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)));
2266 } /* validate_argument() */
2272 * '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
2275 validate_trailer(tree
)
2278 int nch
= NCH(tree
);
2279 int res
= validate_ntype(tree
, trailer
) && ((nch
== 2) || (nch
== 3));
2282 switch (TYPE(CHILD(tree
, 0))) {
2284 res
= validate_rparen(CHILD(tree
, nch
- 1));
2285 if (res
&& (nch
== 3))
2286 res
= validate_arglist(CHILD(tree
, 1));
2289 res
= (validate_numnodes(tree
, 3, "trailer")
2290 && validate_subscriptlist(CHILD(tree
, 1))
2291 && validate_ntype(CHILD(tree
, 2), RSQB
));
2294 res
= (validate_numnodes(tree
, 2, "trailer")
2295 && validate_ntype(CHILD(tree
, 1), NAME
));
2303 (void) validate_numnodes(tree
, 2, "trailer");
2307 } /* validate_trailer() */
2312 * subscript (',' subscript)* [',']
2315 validate_subscriptlist(tree
)
2318 return (validate_repeating_list(tree
, subscriptlist
,
2319 validate_subscript
, "subscriptlist"));
2321 } /* validate_subscriptlist() */
2326 * '.' '.' '.' | test | [test] ':' [test] [sliceop]
2329 validate_subscript(tree
)
2333 int nch
= NCH(tree
);
2334 int res
= validate_ntype(tree
, subscript
) && (nch
>= 1) && (nch
<= 4);
2337 if (!PyErr_Occurred())
2338 err_string("invalid number of arguments for subscript node");
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)));
2348 if (TYPE(CHILD(tree
, 0)) == test
)
2349 res
= validate_test(CHILD(tree
, 0));
2351 res
= validate_colon(CHILD(tree
, 0));
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));
2363 res
= validate_colon(CHILD(tree
, offset
));
2365 int rem
= nch
- ++offset
;
2367 if (TYPE(CHILD(tree
, offset
)) == test
) {
2368 res
= validate_test(CHILD(tree
, offset
));
2373 res
= validate_sliceop(CHILD(tree
, offset
));
2378 } /* validate_subscript() */
2382 validate_sliceop(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");
2392 res
= validate_colon(CHILD(tree
, 0));
2393 if (res
&& (nch
== 2))
2394 res
= validate_test(CHILD(tree
, 1));
2398 } /* validate_sliceop() */
2402 validate_exprlist(tree
)
2405 return (validate_repeating_list(tree
, exprlist
,
2406 validate_expr
, "exprlist"));
2408 } /* validate_exprlist() */
2412 validate_dictmaker(tree
)
2415 int nch
= NCH(tree
);
2416 int res
= (validate_ntype(tree
, dictmaker
)
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
));
2425 res
= ((nch
% 4) == 3);
2427 if (res
&& (nch
> 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)));
2440 } /* validate_dictmaker() */
2444 validate_eval_input(tree
)
2448 int nch
= NCH(tree
);
2449 int res
= (validate_ntype(tree
, eval_input
)
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
);
2459 } /* validate_eval_input() */
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)) {
2473 switch (TYPE(tree
)) {
2478 res
= validate_funcdef(tree
);
2481 res
= validate_class(tree
);
2484 * "Trivial" parse tree nodes.
2485 * (Why did I call these trivial?)
2488 res
= validate_stmt(tree
);
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
);
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
)));
2504 next
= CHILD(tree
, 0);
2506 err_string("Illegal flow_stmt type.");
2509 * Compound statements.
2512 res
= validate_simple_stmt(tree
);
2515 res
= validate_compound_stmt(tree
);
2518 * Fundemental statements.
2521 res
= validate_expr_stmt(tree
);
2524 res
= validate_print_stmt(tree
);
2527 res
= validate_del_stmt(tree
);
2530 res
= (validate_numnodes(tree
, 1, "pass")
2531 && validate_name(CHILD(tree
, 0), "pass"));
2534 res
= (validate_numnodes(tree
, 1, "break")
2535 && validate_name(CHILD(tree
, 0), "break"));
2538 res
= (validate_numnodes(tree
, 1, "continue")
2539 && validate_name(CHILD(tree
, 0), "continue"));
2542 res
= validate_return_stmt(tree
);
2545 res
= validate_raise_stmt(tree
);
2548 res
= validate_import_stmt(tree
);
2551 res
= validate_global_stmt(tree
);
2554 res
= validate_exec_stmt(tree
);
2557 res
= validate_assert_stmt(tree
);
2560 res
= validate_if(tree
);
2563 res
= validate_while(tree
);
2566 res
= validate_for(tree
);
2569 res
= validate_try(tree
);
2572 res
= validate_suite(tree
);
2578 res
= validate_testlist(tree
);
2581 res
= validate_test(tree
);
2584 res
= validate_and_test(tree
);
2587 res
= validate_not_test(tree
);
2590 res
= validate_comparison(tree
);
2593 res
= validate_exprlist(tree
);
2596 res
= validate_comp_op(tree
);
2599 res
= validate_expr(tree
);
2602 res
= validate_xor_expr(tree
);
2605 res
= validate_and_expr(tree
);
2608 res
= validate_shift_expr(tree
);
2611 res
= validate_arith_expr(tree
);
2614 res
= validate_term(tree
);
2617 res
= validate_factor(tree
);
2620 res
= validate_power(tree
);
2623 res
= validate_atom(tree
);
2627 /* Hopefully never reached! */
2628 err_string("Unrecogniged node type.");
2636 } /* validate_node() */
2640 validate_expr_tree(tree
)
2643 int res
= validate_eval_input(tree
);
2645 if (!res
&& !PyErr_Occurred())
2646 err_string("Could not validate expression tuple.");
2650 } /* validate_expr_tree() */
2654 * (NEWLINE | stmt)* ENDMARKER
2657 validate_file_input(tree
)
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
));
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!.");
2680 } /* validate_file_input() */
2684 pickle_constructor
= NULL
;
2688 parser__pickler(self
, args
)
2692 NOTE(ARGUNUSED(self
))
2693 PyObject
*result
= NULL
;
2694 PyObject
*ast
= NULL
;
2696 if (PyArg_ParseTuple(args
, "O!:_pickler", &PyAST_Type
, &ast
)) {
2700 if ((newargs
= Py_BuildValue("Oi", ast
, 1)) == NULL
)
2702 tuple
= parser_ast2tuple((PyAST_Object
*)NULL
, newargs
);
2703 if (tuple
!= NULL
) {
2704 result
= Py_BuildValue("O(O)", pickle_constructor
, tuple
);
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
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
}
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)) {
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
);
2788 PyList_Append(parser_method_list
, temp
);
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
)) {
2808 res
= PyObject_CallFunction(
2809 func
, "OOO", &PyAST_Type
, pickler
, pickle_constructor
);
2815 } /* initparser() */