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