Index: Python/graminit.c =================================================================== --- Python/graminit.c (revision 41432) +++ Python/graminit.c (working copy) @@ -841,15 +841,26 @@ static arc arcs_39_7[1] = { {22, 9}, }; -static arc arcs_39_8[3] = { +static arc arcs_39_8[4] = { {95, 4}, - {91, 5}, + {91, 10}, + {96, 5}, {0, 8}, }; static arc arcs_39_9[1] = { {0, 9}, }; -static state states_39[10] = { +static arc arcs_39_10[1] = { + {21, 11}, +}; +static arc arcs_39_11[1] = { + {22, 12}, +}; +static arc arcs_39_12[2] = { + {96, 5}, + {0, 12}, +}; +static state states_39[13] = { {1, arcs_39_0}, {1, arcs_39_1}, {1, arcs_39_2}, @@ -858,8 +869,11 @@ {1, arcs_39_5}, {1, arcs_39_6}, {1, arcs_39_7}, - {3, arcs_39_8}, + {4, arcs_39_8}, {1, arcs_39_9}, + {1, arcs_39_10}, + {1, arcs_39_11}, + {2, arcs_39_12}, }; static arc arcs_40_0[1] = { {97, 1}, @@ -1754,7 +1768,7 @@ "\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"}, {294, "for_stmt", 0, 10, states_38, "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"}, - {295, "try_stmt", 0, 10, states_39, + {295, "try_stmt", 0, 13, states_39, "\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"}, {296, "except_clause", 0, 5, states_40, "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"}, Index: Python/ast.c =================================================================== --- Python/ast.c (revision 41432) +++ Python/ast.c (working copy) @@ -2708,61 +2708,66 @@ static stmt_ty ast_for_try_stmt(struct compiling *c, const node *n) { + int i; + const int nch = NCH(n); + int n_except = (nch - 3)/3; + asdl_seq *body, *orelse = NULL, *finally = NULL; + REQ(n, try_stmt); + + body = ast_for_suite(c, CHILD(n, 2)); + if (body == NULL) + return NULL; - if (TYPE(CHILD(n, 3)) == NAME) {/* must be 'finally' */ - /* try_stmt: 'try' ':' suite 'finally' ':' suite) */ - asdl_seq *s1, *s2; - s1 = ast_for_suite(c, CHILD(n, 2)); - if (!s1) - return NULL; - s2 = ast_for_suite(c, CHILD(n, 5)); - if (!s2) - return NULL; - - return TryFinally(s1, s2, LINENO(n)); - } - else if (TYPE(CHILD(n, 3)) == except_clause) { - /* try_stmt: ('try' ':' suite (except_clause ':' suite)+ - ['else' ':' suite] - */ - asdl_seq *suite_seq1, *suite_seq2; - asdl_seq *handlers; - int i, has_else = 0, n_except = NCH(n) - 3; - if (TYPE(CHILD(n, NCH(n) - 3)) == NAME) { - has_else = 1; - n_except -= 3; - } - n_except /= 3; - handlers = asdl_seq_new(n_except); - if (!handlers) - return NULL; - for (i = 0; i < n_except; i++) { - excepthandler_ty e = ast_for_except_clause(c, - CHILD(n, 3 + i * 3), - CHILD(n, 5 + i * 3)); - if (!e) + if (TYPE(CHILD(n, nch - 3)) == NAME) { + if (strcmp(STR(CHILD(n, nch - 3)), "finally") == 0) { + if (nch >= 6 && TYPE(CHILD(n, nch - 6)) == NAME) { + /* we can assume it's an "else", otherwise it would have a type of except_clause */ + orelse = ast_for_suite(c, CHILD(n, nch - 4)); + if (orelse == NULL) + return NULL; + n_except--; + } + + finally = ast_for_suite(c, CHILD(n, nch - 1)); + if (finally == NULL) return NULL; - asdl_seq_SET(handlers, i, e); + n_except--; } - - suite_seq1 = ast_for_suite(c, CHILD(n, 2)); - if (!suite_seq1) - return NULL; - if (has_else) { - suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1)); - if (!suite_seq2) + else { + /* we can assume it's an "else", otherwise it would have a type of except_clause */ + orelse = ast_for_suite(c, CHILD(n, nch - 1)); + if (orelse == NULL) return NULL; + n_except--; } - else - suite_seq2 = NULL; - - return TryExcept(suite_seq1, handlers, suite_seq2, LINENO(n)); } - else { + else if (TYPE(CHILD(n, nch - 3)) != except_clause) { PyErr_SetString(PyExc_Exception, "malformed 'try' statement"); return NULL; } + + if (n_except > 0) { + asdl_seq *inner, *handlers; + + handlers = asdl_seq_new(n_except); + if (handlers == NULL) + return NULL; + for (i = 0; i < n_except; i++) { + excepthandler_ty e = ast_for_except_clause(c, CHILD(n, 3 + i * 3), CHILD(n, 5 + i * 3)); + if (!e) + return NULL; + asdl_seq_SET(handlers, i, e); + } + + inner = asdl_seq_new(1); + if (inner == NULL) + return NULL; + asdl_seq_SET(inner, 0, TryExcept(body, handlers, orelse, LINENO(n))); + body = inner; + } + + return TryFinally(body, finally, LINENO(n)); } static stmt_ty Index: Grammar/Grammar =================================================================== --- Grammar/Grammar (revision 41432) +++ Grammar/Grammar (working copy) @@ -67,8 +67,7 @@ if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] while_stmt: 'while' test ':' suite ['else' ':' suite] for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] -try_stmt: ('try' ':' suite (except_clause ':' suite)+ #diagram:break - ['else' ':' suite] | 'try' ':' suite 'finally' ':' suite) +try_stmt: 'try' ':' suite ((except_clause ':' suite)+ ['else' ':' suite] ['finally' ':' suite] | 'finally' ':' suite) # NB compile.c makes sure that the default except clause is last except_clause: 'except' [test [',' test]] suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT