[Python-checkins] python/dist/src/Python ast.c, 1.1.2.49,
1.1.2.50 pythonrun.c, 2.161.2.12, 2.161.2.13
jhylton at users.sourceforge.net
jhylton at users.sourceforge.net
Wed Apr 21 13:45:14 EDT 2004
Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5803/Python
Modified Files:
Tag: ast-branch
ast.c pythonrun.c
Log Message:
Improved error handling inside ast.c; fixes test_syntax.
Add ast_error() that captures line number of error and
ast_finish_error() to assign filename and location. It's a little
complicated this way, but less intrusive than passing the filename to
every ast function that might raise an exception.
Need to pass filename to PyAST_FromNode() for error handling.
Index: ast.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/ast.c,v
retrieving revision 1.1.2.49
retrieving revision 1.1.2.50
diff -C2 -d -r1.1.2.49 -r1.1.2.50
*** ast.c 13 Apr 2004 17:11:43 -0000 1.1.2.49
--- ast.c 21 Apr 2004 17:45:09 -0000 1.1.2.50
***************
*** 42,45 ****
--- 42,103 ----
extern grammar _PyParser_Grammar; /* From graminit.c */
+ #ifndef LINENO
+ #define LINENO(n) ((n)->n_lineno)
+ #endif
+
+ #define NEW_IDENTIFIER(n) PyString_InternFromString(STR(n))
+
+ /* This routine provides an invalid object for the syntax error.
+ The outermost routine must unpack this error and create the
+ proper object. We do this so that we don't have to pass
+ the filename to everything function.
+
+ XXX Maybe we should just pass the filename...
+ */
+
+ static int
+ ast_error(const node *n, const char *errstr)
+ {
+ PyObject *u = Py_BuildValue("zi", errstr, LINENO(n));
+ if (!u)
+ return 0;
+ PyErr_SetObject(PyExc_SyntaxError, u);
+ Py_DECREF(u);
+ return 0;
+ }
+
+ static void
+ ast_error_finish(const char *filename)
+ {
+ PyObject *type, *value, *tback, *errstr, *loc, *tmp;
+ int lineno;
+
+ assert(PyErr_Occurred());
+ PyErr_Fetch(&type, &value, &tback);
+ errstr = PyTuple_GetItem(value, 0);
+ if (!errstr)
+ return;
+ Py_INCREF(errstr);
+ lineno = PyInt_AsLong(PyTuple_GetItem(value, 1));
+ if (lineno == -1)
+ return;
+ Py_DECREF(value);
+
+ loc = PyErr_ProgramText(filename, lineno);
+ if (!loc) {
+ Py_INCREF(Py_None);
+ loc = Py_None;
+ }
+ tmp = Py_BuildValue("(ziOO)", filename, lineno, Py_None, loc);
+ Py_DECREF(loc);
+ if (!tmp)
+ return;
+ value = Py_BuildValue("(OO)", errstr, tmp);
+ Py_DECREF(errstr);
+ Py_DECREF(tmp);
+ if (!value)
+ return;
+ PyErr_Restore(type, value, tback);
+ }
/* num_stmts() returns number of contained statements.
***************
*** 108,112 ****
mod_ty
! PyAST_FromNode(const node *n, PyCompilerFlags *flags)
{
int i, j, num;
--- 166,170 ----
mod_ty
! PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename)
{
int i, j, num;
***************
*** 125,129 ****
}
-
switch (TYPE(n)) {
case file_input:
--- 183,186 ----
***************
*** 167,171 ****
stmts = asdl_seq_new(1);
if (!stmts)
! return NULL;
asdl_seq_SET(stmts, 0, Pass(n->n_lineno));
return Interactive(stmts);
--- 224,228 ----
stmts = asdl_seq_new(1);
if (!stmts)
! goto error;
asdl_seq_SET(stmts, 0, Pass(n->n_lineno));
return Interactive(stmts);
***************
*** 176,182 ****
stmts = asdl_seq_new(num);
if (!stmts)
! return NULL;
if (num == 1) {
! asdl_seq_SET(stmts, 0, ast_for_stmt(&c, n));
}
else {
--- 233,242 ----
stmts = asdl_seq_new(num);
if (!stmts)
! goto error;
if (num == 1) {
! stmt_ty s = ast_for_stmt(&c, n);
! if (!s)
! goto error;
! asdl_seq_SET(stmts, 0, s);
}
else {
***************
*** 202,216 ****
if (stmts)
asdl_seq_free(stmts);
! fprintf(stderr, "error in PyAST_FromNode() exc? %c\n",
! PyErr_Occurred() ? 'Y': 'N');
return NULL;
}
- #ifndef LINENO
- #define LINENO(n) ((n)->n_lineno)
- #endif
-
- #define NEW_IDENTIFIER(n) PyString_InternFromString(STR(n))
-
/* Return the AST repr. of the operator represented as syntax (|, ^, etc.)
*/
--- 262,269 ----
if (stmts)
asdl_seq_free(stmts);
! ast_error_finish(filename);
return NULL;
}
/* Return the AST repr. of the operator represented as syntax (|, ^, etc.)
*/
***************
*** 275,279 ****
static int
! set_context(expr_ty e, expr_context_ty ctx)
{
asdl_seq *s = NULL;
--- 328,332 ----
static int
! set_context(expr_ty e, expr_context_ty ctx, const node *n)
{
asdl_seq *s = NULL;
***************
*** 281,314 ****
switch (e->kind) {
case Attribute_kind:
! e->v.Attribute.ctx = ctx;
! break;
case Subscript_kind:
! e->v.Subscript.ctx = ctx;
! break;
case Name_kind:
! e->v.Name.ctx = ctx;
! break;
case List_kind:
! e->v.List.ctx = ctx;
! s = e->v.List.elts;
! break;
case Tuple_kind:
! e->v.Tuple.ctx = ctx;
! s = e->v.Tuple.elts;
! break;
default:
! /* XXX It's not clear why were't getting into this code,
! although list comps seem like one possibility.
!
! This occurs in at least 2 cases:
! [x(i) for i in range(3)] # Call_kind (8)
! [i*2 for i in range(3)] # BinOp_kind (2)
!
! The byte code generated seems to work fine.
! Maybe there's a problem with nested list comps?
! */
! abort();
! fprintf(stderr, "can't set context for %d\n", e->kind);
! return 0;
}
if (s) {
--- 334,364 ----
switch (e->kind) {
case Attribute_kind:
! e->v.Attribute.ctx = ctx;
! break;
case Subscript_kind:
! e->v.Subscript.ctx = ctx;
! break;
case Name_kind:
! e->v.Name.ctx = ctx;
! break;
case List_kind:
! e->v.List.ctx = ctx;
! s = e->v.List.elts;
! break;
case Tuple_kind:
! e->v.Tuple.ctx = ctx;
! s = e->v.Tuple.elts;
! break;
! case Call_kind:
! if (ctx == Store)
! return ast_error(n, "can't assign to function call");
! else if (ctx == Del)
! return ast_error(n, "can't delete function call");
! else
! return ast_error(n, "unexpected operation on function call");
! break;
default:
! return ast_error(n, "unexpected node in assignment");
! break;
}
if (s) {
***************
*** 316,324 ****
for (i = 0; i < asdl_seq_LEN(s); i++) {
! if (set_context(asdl_seq_GET(s, i), ctx) < 0)
! return -1;
}
}
! return 0;
}
--- 366,374 ----
for (i = 0; i < asdl_seq_LEN(s); i++) {
! if (!set_context(asdl_seq_GET(s, i), ctx, n))
! return 0;
}
}
! return 1;
}
***************
*** 1348,1352 ****
}
else {
! int i, tmp;
asdl_seq *targets;
expr_ty expression;
--- 1398,1402 ----
}
else {
! int i;
asdl_seq *targets;
expr_ty expression;
***************
*** 1364,1369 ****
return NULL;
}
! tmp = set_context(e, Store);
! if (tmp == -1) {
asdl_seq_free(targets);
return NULL;
--- 1414,1418 ----
return NULL;
}
! if (!set_context(e, Store, CHILD(n, i))) {
asdl_seq_free(targets);
return NULL;
***************
*** 1430,1435 ****
}
if (context) {
! int context_result = set_context(e, context);
! if (context_result == -1)
return NULL;
}
--- 1479,1483 ----
}
if (context) {
! if (!set_context(e, context, CHILD(n, i)))
return NULL;
}
***************
*** 2037,2041 ****
if (!e)
return NULL;
! if (set_context(e, Store) == -1)
return NULL;
expression = ast_for_expr(c, CHILD(exc, 1));
--- 2085,2089 ----
if (!e)
return NULL;
! if (!set_context(e, Store, CHILD(exc, 3)))
return NULL;
expression = ast_for_expr(c, CHILD(exc, 1));
Index: pythonrun.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v
retrieving revision 2.161.2.12
retrieving revision 2.161.2.13
diff -C2 -d -r2.161.2.12 -r2.161.2.13
*** pythonrun.c 13 Apr 2004 15:04:01 -0000 2.161.2.12
--- pythonrun.c 21 Apr 2004 17:45:10 -0000 2.161.2.13
***************
*** 1175,1179 ****
PARSER_FLAGS(flags));
if (n) {
! mod = PyAST_FromNode(n, flags);
PyNode_Free(n);
return mod;
--- 1175,1179 ----
PARSER_FLAGS(flags));
if (n) {
! mod = PyAST_FromNode(n, flags, filename);
PyNode_Free(n);
return mod;
***************
*** 1195,1199 ****
ps1, ps2, &err, PARSER_FLAGS(flags));
if (n) {
! mod = PyAST_FromNode(n, flags);
PyNode_Free(n);
return mod;
--- 1195,1199 ----
ps1, ps2, &err, PARSER_FLAGS(flags));
if (n) {
! mod = PyAST_FromNode(n, flags, filename);
PyNode_Free(n);
return mod;
More information about the Python-checkins
mailing list