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