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