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