diff options
author | Neal Norwitz <nnorwitz@gmail.com> | 2005-12-17 21:33:47 (GMT) |
---|---|---|
committer | Neal Norwitz <nnorwitz@gmail.com> | 2005-12-17 21:33:47 (GMT) |
commit | f599f424a2c8cfc490111a11203c93d23706379f (patch) | |
tree | 972d455572879ef5b9b3979d16fb4dab0f44d9b4 /Python | |
parent | adb69fcdffdc50ee3e1d33b00cd874020197b445 (diff) | |
download | cpython-f599f424a2c8cfc490111a11203c93d23706379f.zip cpython-f599f424a2c8cfc490111a11203c93d23706379f.tar.gz cpython-f599f424a2c8cfc490111a11203c93d23706379f.tar.bz2 |
SF patch #1355913, PEP 341 - Unification of try/except and try/finally
Modified since ast-arenas was implemented.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ast.c | 112 | ||||
-rw-r--r-- | Python/graminit.c | 24 |
2 files changed, 81 insertions, 55 deletions
diff --git a/Python/ast.c b/Python/ast.c index 6585c8f..e56d165 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -2597,66 +2597,78 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body) static stmt_ty ast_for_try_stmt(struct compiling *c, const node *n) { + const int nch = NCH(n); + int n_except = (nch - 3)/3; + asdl_seq *body, *orelse = NULL, *finally = NULL; + REQ(n, try_stmt); - 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), c->c_arena); - } - 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, c->c_arena); - 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) { + body = ast_for_suite(c, CHILD(n, 2)); + if (body == NULL) + return NULL; + + if (TYPE(CHILD(n, nch - 3)) == NAME) { + if (strcmp(STR(CHILD(n, nch - 3)), "finally") == 0) { + if (nch >= 9 && TYPE(CHILD(n, nch - 6)) == NAME) { + /* we can assume it's an "else", + because nch >= 9 for try-else-finally and + it would otherwise 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), - c->c_arena); } - else { + else if (TYPE(CHILD(n, nch - 3)) != except_clause) { ast_error(n, "malformed 'try' statement"); return NULL; } + + if (n_except > 0) { + int i; + stmt_ty except_st; + /* process except statements to create a try ... except */ + asdl_seq *handlers = asdl_seq_new(n_except, c->c_arena); + 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); + } + + except_st = TryExcept(body, handlers, orelse, LINENO(n), c->c_arena); + if (!finally) + return except_st; + + /* if a 'finally' is present too, we nest the TryExcept within a + TryFinally to emulate try ... except ... finally */ + body = asdl_seq_new(1, c->c_arena); + if (body == NULL) + return NULL; + asdl_seq_SET(body, 0, except_st); + } + + /* must be a try ... finally (except clauses are in body, if any exist) */ + assert(finally != NULL); + return TryFinally(body, finally, LINENO(n), c->c_arena); } static stmt_ty diff --git a/Python/graminit.c b/Python/graminit.c index 769532a..a5bf3a4 100644 --- a/Python/graminit.c +++ b/Python/graminit.c @@ -841,15 +841,26 @@ static arc arcs_39_6[1] = { 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 @@ static state states_39[10] = { {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 @@ static dfa dfas[79] = { "\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"}, |