Kaydet (Commit) 94988067 authored tarafından Jeremy Hylton's avatar Jeremy Hylton

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."
üst 56c807d3
......@@ -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
}
......
......@@ -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 */
......
......@@ -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 */
......
......@@ -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 */
......
......@@ -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";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment