summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2000-06-20 19:10:44 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2000-06-20 19:10:44 (GMT)
commit94988067b96c6187fd940eaff99c2c5a68daac68 (patch)
tree681d7a64160eeab1ece2685bb234971d404ef0a6
parent56c807d318954222bb67167477d98eafb6b85d81 (diff)
downloadcpython-94988067b96c6187fd940eaff99c2c5a68daac68.zip
cpython-94988067b96c6187fd940eaff99c2c5a68daac68.tar.gz
cpython-94988067b96c6187fd940eaff99c2c5a68daac68.tar.bz2
Add new parser error code, E_OVERFLOW. This error is returned when
the number of children of a node exceeds the max possible value for the short that is used to count them. The Python runtime converts this parser error into the SyntaxError "expression too long."
-rw-r--r--Include/errcode.h1
-rw-r--r--Include/node.h2
-rw-r--r--Parser/node.c11
-rw-r--r--Parser/parser.c29
-rw-r--r--Python/pythonrun.c3
5 files changed, 28 insertions, 18 deletions
diff --git a/Include/errcode.h b/Include/errcode.h
index 5655782..f94c11c 100644
--- a/Include/errcode.h
+++ b/Include/errcode.h
@@ -52,6 +52,7 @@ PERFORMANCE OF THIS SOFTWARE.
#define E_DONE 16 /* Parsing complete */
#define E_ERROR 17 /* Execution error */
#define E_INDENT 18 /* Invalid indentation detected */
+#define E_OVERFLOW 19 /* Node had too many children */
#ifdef __cplusplus
}
diff --git a/Include/node.h b/Include/node.h
index 7f30923..3a564f7 100644
--- a/Include/node.h
+++ b/Include/node.h
@@ -46,7 +46,7 @@ typedef struct _node {
} node;
extern DL_IMPORT(node *) PyNode_New Py_PROTO((int type));
-extern DL_IMPORT(node *) PyNode_AddChild Py_PROTO((node *n, int type, char *str, int lineno));
+extern DL_IMPORT(int) PyNode_AddChild Py_PROTO((node *n, int type, char *str, int lineno));
extern DL_IMPORT(void) PyNode_Free Py_PROTO((node *n));
/* Node access functions */
diff --git a/Parser/node.c b/Parser/node.c
index c2308fd..3f593c8 100644
--- a/Parser/node.c
+++ b/Parser/node.c
@@ -29,10 +29,13 @@ PERFORMANCE OF THIS SOFTWARE.
******************************************************************/
+#include <limits.h>
+
/* Parse tree node implementation */
#include "pgenheaders.h"
#include "node.h"
+#include "errcode.h"
node *
PyNode_New(type)
@@ -52,7 +55,7 @@ PyNode_New(type)
#define XXX 3 /* Node alignment factor to speed up realloc */
#define XXXROUNDUP(n) ((n) == 1 ? 1 : ((n) + XXX - 1) / XXX * XXX)
-node *
+int
PyNode_AddChild(n1, type, str, lineno)
register node *n1;
int type;
@@ -62,12 +65,14 @@ PyNode_AddChild(n1, type, str, lineno)
register int nch = n1->n_nchildren;
register int nch1 = nch+1;
register node *n;
+ if (nch == SHRT_MAX || nch < 0)
+ return E_OVERFLOW;
if (XXXROUNDUP(nch) < nch1) {
n = n1->n_child;
nch1 = XXXROUNDUP(nch1);
PyMem_RESIZE(n, node, nch1);
if (n == NULL)
- return NULL;
+ return E_NOMEM;
n1->n_child = n;
}
n = &n1->n_child[n1->n_nchildren++];
@@ -76,7 +81,7 @@ PyNode_AddChild(n1, type, str, lineno)
n->n_lineno = lineno;
n->n_nchildren = 0;
n->n_child = NULL;
- return n;
+ return 0;
}
/* Forward */
diff --git a/Parser/parser.c b/Parser/parser.c
index 3b75dbc..00299af 100644
--- a/Parser/parser.c
+++ b/Parser/parser.c
@@ -153,11 +153,11 @@ shift(s, type, str, newstate, lineno)
int newstate;
int lineno;
{
+ int err;
assert(!s_empty(s));
- if (PyNode_AddChild(s->s_top->s_parent, type, str, lineno) == NULL) {
- fprintf(stderr, "shift: no mem in addchild\n");
- return -1;
- }
+ err = PyNode_AddChild(s->s_top->s_parent, type, str, lineno);
+ if (err)
+ return err;
s->s_top->s_state = newstate;
return 0;
}
@@ -172,13 +172,13 @@ push(s, type, d, newstate, lineno)
int newstate;
int lineno;
{
+ int err;
register node *n;
n = s->s_top->s_parent;
assert(!s_empty(s));
- if (PyNode_AddChild(n, type, (char *)NULL, lineno) == NULL) {
- fprintf(stderr, "push: no mem in addchild\n");
- return -1;
- }
+ err = PyNode_AddChild(n, type, (char *)NULL, lineno);
+ if (err)
+ return err;
s->s_top->s_state = newstate;
return s_push(s, d, CHILD(n, NCH(n)-1));
}
@@ -233,6 +233,7 @@ PyParser_AddToken(ps, type, str, lineno)
int lineno;
{
register int ilabel;
+ int err;
D(printf("Token %s/'%s' ... ", _PyParser_TokenNames[type], str));
@@ -260,20 +261,20 @@ PyParser_AddToken(ps, type, str, lineno)
int arrow = x & ((1<<7)-1);
dfa *d1 = PyGrammar_FindDFA(
ps->p_grammar, nt);
- if (push(&ps->p_stack, nt, d1,
- arrow, lineno) < 0) {
+ if ((err = push(&ps->p_stack, nt, d1,
+ arrow, lineno)) > 0) {
D(printf(" MemError: push\n"));
- return E_NOMEM;
+ return err;
}
D(printf(" Push ...\n"));
continue;
}
/* Shift the token */
- if (shift(&ps->p_stack, type, str,
- x, lineno) < 0) {
+ if ((err = shift(&ps->p_stack, type, str,
+ x, lineno)) > 0) {
D(printf(" MemError: shift.\n"));
- return E_NOMEM;
+ return err;
}
D(printf(" Shift.\n"));
/* Pop while we are in an accept-only state */
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 7760714..3a60e47 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -1033,6 +1033,9 @@ err_input(err)
case E_INDENT:
msg = "inconsistent use of tabs and spaces in indentation";
break;
+ case E_OVERFLOW:
+ msg = "expression too long";
+ break;
default:
fprintf(stderr, "error=%d\n", err->error);
msg = "unknown parsing error";