[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
*/