[Python-checkins] CVS: python/dist/src/Modules parsermodule.c,2.56,2.57

Fred L. Drake python-dev@python.org
Tue, 12 Sep 2000 14:58:09 -0700


Update of /cvsroot/python/python/dist/src/Modules
In directory slayer.i.sourceforge.net:/tmp/cvs-serv8062

Modified Files:
	parsermodule.c 
Log Message:

Simplify some of the code.  Use PyErr_Format() instead of sprintf(), etc.
Reduces lines of code and compiled object size.


Index: parsermodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/parsermodule.c,v
retrieving revision 2.56
retrieving revision 2.57
diff -C2 -r2.56 -r2.57
*** parsermodule.c	2000/09/01 23:29:26	2.56
--- parsermodule.c	2000/09/12 21:58:06	2.57
***************
*** 580,660 ****
      NOTE(ARGUNUSED(self))
      PyObject *ast = 0;
!     PyObject *tuple = 0;
!     PyObject *temp = 0;
!     int ok;
!     int start_sym = 0;
  
      static char *keywords[] = {"sequence", NULL};
  
!     if (!PyArg_ParseTupleAndKeywords(args, kw, "O:tuple2ast", keywords,
                                       &tuple))
          return (0);
      if (!PySequence_Check(tuple)) {
          PyErr_SetString(PyExc_ValueError,
!                         "tuple2ast() requires a single sequence argument");
          return (0);
      }
      /*
!      *  This mess of tests is written this way so we can use the abstract
!      *  object interface (AOI).  Unfortunately, the AOI increments reference
!      *  counts, which requires that we store a pointer to retrieved object
!      *  so we can DECREF it after the check.  But we really should accept
!      *  lists as well as tuples at the very least.
       */
!     ok = PyObject_Size(tuple) >= 2;
!     if (ok) {
!         temp = PySequence_GetItem(tuple, 0);
!         ok = (temp != NULL) && PyInt_Check(temp);
!         if (ok)
!             /* this is used after the initial checks: */
!             start_sym = PyInt_AS_LONG(temp);
!         Py_XDECREF(temp);
!     }
!     if (ok) {
!         temp = PySequence_GetItem(tuple, 1);
!         ok = (temp != NULL) && PySequence_Check(temp);
!         Py_XDECREF(temp);
!     }
!     if (ok) {
!         temp = PySequence_GetItem(tuple, 1);
!         ok = (temp != NULL) && PyObject_Size(temp) >= 2;
!         if (ok) {
!             PyObject *temp2 = PySequence_GetItem(temp, 0);
!             if (temp2 != NULL) {
!                 ok = PyInt_Check(temp2);
!                 Py_DECREF(temp2);
!             }
          }
!         Py_XDECREF(temp);
!     }
!     /* If we've failed at some point, get out of here. */
!     if (!ok) {
!         err_string("malformed sequence for tuple2ast()");
!         return (0);
!     }
!     /*
!      *  This might be a valid parse tree, but let's do a quick check
!      *  before we jump the gun.
!      */
!     if (start_sym == eval_input) {
!         /*  Might be an eval form.  */
!         node* expression = build_node_tree(tuple);
! 
!         if ((expression != 0) && validate_expr_tree(expression))
!             ast = parser_newastobject(expression, PyAST_EXPR);
!     }
!     else if (start_sym == file_input) {
!         /*  This looks like an exec form so far.  */
!         node* suite_tree = build_node_tree(tuple);
! 
!         if ((suite_tree != 0) && validate_file_input(suite_tree))
!             ast = parser_newastobject(suite_tree, PyAST_SUITE);
      }
-     else
-         /*  This is a fragment, and is not yet supported.  Maybe they
-          *  will be if I find a use for them.
-          */
-         err_string("Fragmentary parse trees not supported.");
- 
      /*  Make sure we throw an exception on all errors.  We should never
       *  get this, but we'd do well to be sure something is done.
--- 580,618 ----
      NOTE(ARGUNUSED(self))
      PyObject *ast = 0;
!     PyObject *tuple;
!     node *tree;
  
      static char *keywords[] = {"sequence", NULL};
  
!     if (!PyArg_ParseTupleAndKeywords(args, kw, "O:sequence2ast", keywords,
                                       &tuple))
          return (0);
      if (!PySequence_Check(tuple)) {
          PyErr_SetString(PyExc_ValueError,
!                         "sequence2ast() requires a single sequence argument");
          return (0);
      }
      /*
!      *  Convert the tree to the internal form before checking it.
       */
!     tree = build_node_tree(tuple);
!     if (tree != 0) {
!         int start_sym = TYPE(tree);
!         if (start_sym == eval_input) {
!             /*  Might be an eval form.  */
!             if (validate_expr_tree(tree))
!                 ast = parser_newastobject(tree, PyAST_EXPR);
!         }
!         else if (start_sym == file_input) {
!             /*  This looks like an exec form so far.  */
!             if (validate_file_input(tree))
!                 ast = parser_newastobject(tree, PyAST_SUITE);
          }
!         else {
!             /*  This is a fragment, at best. */
!             PyNode_Free(tree);
!             err_string("Parse tree does not use a valid start symbol.");
!         }
      }
      /*  Make sure we throw an exception on all errors.  We should never
       *  get this, but we'd do well to be sure something is done.
***************
*** 667,715 ****
  
  
- /*  int check_terminal_tuple()
-  *
-  *  Check a tuple to determine that it is indeed a valid terminal
-  *  node.  The node is known to be required as a terminal, so we throw
-  *  an exception if there is a failure.
-  *
-  *  The format of an acceptable terminal tuple is "(is[i])": the fact
-  *  that elem is a tuple and the integer is a valid terminal symbol
-  *  has been established before this function is called.  We must
-  *  check the length of the tuple and the type of the second element
-  *  and optional third element.  We do *NOT* check the actual text of
-  *  the string element, which we could do in many cases.  This is done
-  *  by the validate_*() functions which operate on the internal
-  *  representation.
-  */
- static int
- check_terminal_tuple(PyObject *elem)
- {
-     int   len = PyObject_Size(elem);
-     int   res = 1;
-     char* str = "Illegal terminal symbol; bad node length.";
- 
-     if ((len == 2) || (len == 3)) {
-         PyObject *temp = PySequence_GetItem(elem, 1);
-         res = PyString_Check(temp);
-         str = "Illegal terminal symbol; expected a string.";
-         if (res && (len == 3)) {
-             PyObject* third = PySequence_GetItem(elem, 2);
-             res = PyInt_Check(third);
-             str = "Invalid third element of terminal node.";
-             Py_XDECREF(third);
-         }
-         Py_XDECREF(temp);
-     }
-     else {
-         res = 0;
-     }
-     if (!res) {
-         elem = Py_BuildValue("(os)", elem, str);
-         PyErr_SetObject(parser_error, elem);
-     }
-     return (res);
- }
- 
- 
  /*  node* build_node_children()
   *
--- 625,628 ----
***************
*** 727,731 ****
  
      for (i = 1; i < len; ++i) {
!         /* elem must always be a tuple, however simple */
          PyObject* elem = PySequence_GetItem(tuple, i);
          int ok = elem != NULL;
--- 640,644 ----
  
      for (i = 1; i < len; ++i) {
!         /* elem must always be a sequence, however simple */
          PyObject* elem = PySequence_GetItem(tuple, i);
          int ok = elem != NULL;
***************
*** 748,752 ****
          if (!ok) {
              PyErr_SetObject(parser_error,
!                             Py_BuildValue("(os)", elem,
                                            "Illegal node construct."));
              Py_XDECREF(elem);
--- 661,665 ----
          if (!ok) {
              PyErr_SetObject(parser_error,
!                             Py_BuildValue("os", elem,
                                            "Illegal node construct."));
              Py_XDECREF(elem);
***************
*** 754,776 ****
          }
          if (ISTERMINAL(type)) {
!             if (check_terminal_tuple(elem)) {
!                 PyObject *temp = PySequence_GetItem(elem, 1);
  
!                 /* check_terminal_tuple() already verified it's a string */
!                 strn = (char *)PyMem_MALLOC(PyString_GET_SIZE(temp) + 1);
!                 if (strn != NULL)
!                     (void) strcpy(strn, PyString_AS_STRING(temp));
                  Py_DECREF(temp);
! 
!                 if (PyObject_Size(elem) == 3) {
!                     PyObject* temp = PySequence_GetItem(elem, 2);
!                     *line_num = PyInt_AsLong(temp);
!                     Py_DECREF(temp);
!                 }
              }
!             else {
!                 Py_XDECREF(elem);
!                 return (0);
              }
          }
          else if (!ISNONTERMINAL(type)) {
--- 667,710 ----
          }
          if (ISTERMINAL(type)) {
!             int len = PyObject_Size(elem);
!             PyObject *temp;
  
!             if ((len != 2) && (len != 3)) {
!                 err_string("Terminal nodes must have 2 or 3 entries.");
!                 return 0;
!             }
!             temp = PySequence_GetItem(elem, 1);
!             if (temp == NULL)
!                 return 0;
!             if (!PyString_Check(temp)) {
!                 PyErr_Format(parser_error,
!                              "Second item in terminal node must be a string,"
!                              " found %s.",
!                              ((PyTypeObject*)PyObject_Type(temp))->tp_name);
                  Py_DECREF(temp);
!                 return 0;
              }
!             if (len == 3) {
!                 PyObject *o = PySequence_GetItem(elem, 2);
!                 if (o != NULL) {
!                     if (PyInt_Check(o))
!                         *line_num = PyInt_AS_LONG(o);
!                     else {
!                         PyErr_Format(parser_error,
!                                      "Third item in terminal node must be an"
!                                      " integer, found %s.",
!                                 ((PyTypeObject*)PyObject_Type(temp))->tp_name);
!                         Py_DECREF(o);
!                         Py_DECREF(temp);
!                         return 0;
!                     }
!                     Py_DECREF(o);
!                 }
              }
+             len = PyString_GET_SIZE(temp) + 1;
+             strn = (char *)PyMem_MALLOC(len);
+             if (strn != NULL)
+                 (void) memcpy(strn, PyString_AS_STRING(temp), len);
+             Py_DECREF(temp);
          }
          else if (!ISNONTERMINAL(type)) {
***************
*** 780,785 ****
               */
              PyErr_SetObject(parser_error,
!                             Py_BuildValue("(os)", elem,
!                                           "Unknown node type."));
              Py_XDECREF(elem);
              return (0);
--- 714,718 ----
               */
              PyErr_SetObject(parser_error,
!                             Py_BuildValue("os", elem, "Unknown node type."));
              Py_XDECREF(elem);
              return (0);
***************
*** 809,813 ****
      node* res = 0;
      PyObject *temp = PySequence_GetItem(tuple, 0);
!     long  num = -1;
  
      if (temp != NULL)
--- 742,746 ----
      node* res = 0;
      PyObject *temp = PySequence_GetItem(tuple, 0);
!     long num = -1;
  
      if (temp != NULL)
***************
*** 819,824 ****
           *  Throw an exception now and be done with it.
           */
!         tuple = Py_BuildValue("(os)", tuple,
!                     "Illegal ast tuple; cannot start with terminal symbol.");
          PyErr_SetObject(parser_error, tuple);
      }
--- 752,757 ----
           *  Throw an exception now and be done with it.
           */
!         tuple = Py_BuildValue("os", tuple,
!                       "Illegal ast tuple; cannot start with terminal symbol.");
          PyErr_SetObject(parser_error, tuple);
      }
***************
*** 837,844 ****
      else
          /*  The tuple is illegal -- if the number is neither TERMINAL nor
!          *  NONTERMINAL, we can't use it.
           */
          PyErr_SetObject(parser_error,
!                         Py_BuildValue("(os)", tuple,
                                        "Illegal component tuple."));
  
--- 770,778 ----
      else
          /*  The tuple is illegal -- if the number is neither TERMINAL nor
!          *  NONTERMINAL, we can't use it.  Not sure the implementation
!          *  allows this condition, but the API doesn't preclude it.
           */
          PyErr_SetObject(parser_error,
!                         Py_BuildValue("os", tuple,
                                        "Illegal component tuple."));
  
***************
*** 847,853 ****
  
  
- #define VALIDATER(n)    static int validate_##n(node *tree)
- 
- 
  /*
   *  Validation routines used within the validation section:
--- 781,784 ----
***************
*** 872,875 ****
--- 803,808 ----
  #define validate_name(ch, str)  validate_terminal(ch,       NAME, str)
  
+ #define VALIDATER(n)    static int validate_##n(node *tree)
+ 
  VALIDATER(node);                VALIDATER(small_stmt);
  VALIDATER(class);               VALIDATER(node);
***************
*** 900,903 ****
--- 833,837 ----
  VALIDATER(listmaker);
  
+ #undef VALIDATER
  
  #define is_even(n)      (((n) & 1) == 0)
***************
*** 908,919 ****
  validate_ntype(node *n, int t)
  {
!     int res = (TYPE(n) == t);
! 
!     if (!res) {
!         char buffer[128];
!         (void) sprintf(buffer, "Expected node type %d, got %d.", t, TYPE(n));
!         err_string(buffer);
      }
!     return (res);
  }
  
--- 842,851 ----
  validate_ntype(node *n, int t)
  {
!     if (TYPE(n) != t) {
!         PyErr_Format(parser_error, "Expected node type %d, got %d.",
!                      t, TYPE(n));
!         return 0;
      }
!     return 1;
  }
  
***************
*** 930,938 ****
  {
      if (NCH(n) != num) {
!         char buff[60];
!         (void) sprintf(buff, "Illegal number of children for %s node.", name);
!         err_string(buff);
      }
!     return (NCH(n) == num);
  }
  
--- 862,870 ----
  {
      if (NCH(n) != num) {
!         PyErr_Format(parser_error,
!                      "Illegal number of children for %s node.", name);
!         return 0;
      }
!     return 1;
  }
  
***************
*** 945,951 ****
  
      if (!res && !PyErr_Occurred()) {
!         char buffer[60];
!         (void) sprintf(buffer, "Illegal terminal: expected \"%s\"", string);
!         err_string(buffer);
      }
      return (res);
--- 877,882 ----
  
      if (!res && !PyErr_Occurred()) {
!         PyErr_Format(parser_error,
!                      "Illegal terminal: expected \"%s\"", string);
      }
      return (res);
***************
*** 1396,1417 ****
  {
      int nch = NCH(tree);
!     int res = (validate_numnodes(tree, 1, "small_stmt")
!                && ((TYPE(CHILD(tree, 0)) == expr_stmt)
!                    || (TYPE(CHILD(tree, 0)) == print_stmt)
!                    || (TYPE(CHILD(tree, 0)) == del_stmt)
!                    || (TYPE(CHILD(tree, 0)) == pass_stmt)
!                    || (TYPE(CHILD(tree, 0)) == flow_stmt)
!                    || (TYPE(CHILD(tree, 0)) == import_stmt)
!                    || (TYPE(CHILD(tree, 0)) == global_stmt)
!                    || (TYPE(CHILD(tree, 0)) == assert_stmt)
!                    || (TYPE(CHILD(tree, 0)) == exec_stmt)));
  
!     if (res)
!         res = validate_node(CHILD(tree, 0));
      else if (nch == 1) {
!         char buffer[60];
!         (void) sprintf(buffer, "Unrecognized child node of small_stmt: %d.",
!                        TYPE(CHILD(tree, 0)));
!         err_string(buffer);
      }
      return (res);
--- 1327,1355 ----
  {
      int nch = NCH(tree);
!     int res = validate_numnodes(tree, 1, "small_stmt");
  
!     if (res) {
!         int ntype = TYPE(CHILD(tree, 0));
! 
!         if (  (ntype == expr_stmt)
!               || (ntype == print_stmt)
!               || (ntype == del_stmt)
!               || (ntype == pass_stmt)
!               || (ntype == flow_stmt)
!               || (ntype == import_stmt)
!               || (ntype == global_stmt)
!               || (ntype == assert_stmt)
!               || (ntype == exec_stmt))
!             res = validate_node(CHILD(tree, 0));
!         else {
!             res = 0;
!             err_string("illegal small_stmt child type");
!         }
!     }
      else if (nch == 1) {
!         res = 0;
!         PyErr_Format(parser_error,
!                      "Unrecognized child node of small_stmt: %d.",
!                      TYPE(CHILD(tree, 0)));
      }
      return (res);
***************
*** 1427,1430 ****
--- 1365,1369 ----
      int res = (validate_ntype(tree, compound_stmt)
                 && validate_numnodes(tree, 1, "compound_stmt"));
+     int ntype;
  
      if (!res)
***************
*** 1432,1448 ****
  
      tree = CHILD(tree, 0);
!     res = ((TYPE(tree) == if_stmt)
!            || (TYPE(tree) == while_stmt)
!            || (TYPE(tree) == for_stmt)
!            || (TYPE(tree) == try_stmt)
!            || (TYPE(tree) == funcdef)
!            || (TYPE(tree) == classdef));
!     if (res)
          res = validate_node(tree);
      else {
!         char buffer[60];
!         (void) sprintf(buffer, "Illegal compound statement type: %d.",
!                        TYPE(tree));
!         err_string(buffer);
      }
      return (res);
--- 1371,1386 ----
  
      tree = CHILD(tree, 0);
!     ntype = TYPE(tree);
!     if (  (ntype == if_stmt)
!           || (ntype == while_stmt)
!           || (ntype == for_stmt)
!           || (ntype == try_stmt)
!           || (ntype == funcdef)
!           || (ntype == classdef))
          res = validate_node(tree);
      else {
!         res = 0;
!         PyErr_Format(parser_error,
!                      "Illegal compound statement type: %d.", TYPE(tree));
      }
      return (res);
***************
*** 1815,1826 ****
                 && validate_colon(CHILD(tree, nch - 2))
                 && validate_suite(CHILD(tree, nch - 1)));
!     else {
          const char* name = "except";
-         char buffer[60];
          if (TYPE(CHILD(tree, nch - 3)) != except_clause)
              name = STR(CHILD(tree, nch - 3));
!         (void) sprintf(buffer,
!                        "Illegal number of children for try/%s node.", name);
!         err_string(buffer);
      }
      /*  Skip past except_clause sections:  */
--- 1753,1763 ----
                 && validate_colon(CHILD(tree, nch - 2))
                 && validate_suite(CHILD(tree, nch - 1)));
!     else if (!PyErr_Occurred()) {
          const char* name = "except";
          if (TYPE(CHILD(tree, nch - 3)) != except_clause)
              name = STR(CHILD(tree, nch - 3));
! 
!         PyErr_Format(parser_error,
!                      "Illegal number of children for try/%s node.", name);
      }
      /*  Skip past except_clause sections:  */
***************
*** 1975,1981 ****
                       || (strcmp(STR(tree), "is") == 0));
                if (!res) {
!                   char buff[128];
!                   (void) sprintf(buff, "Illegal operator: '%s'.", STR(tree));
!                   err_string(buff);
                }
                break;
--- 1912,1917 ----
                       || (strcmp(STR(tree), "is") == 0));
                if (!res) {
!                   PyErr_Format(parser_error,
!                                "Illegal operator: '%s'.", STR(tree));
                }
                break;
***************
*** 2583,2587 ****
            case small_stmt:
              /*
!              *  expr_stmt | print_stmt  | del_stmt | pass_stmt | flow_stmt
               *  | import_stmt | global_stmt | exec_stmt | assert_stmt
               */
--- 2519,2523 ----
            case small_stmt:
              /*
!              *  expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
               *  | import_stmt | global_stmt | exec_stmt | assert_stmt
               */