diff options
author | Alexandre Vassalotti <alexandre@peadrop.com> | 2010-01-11 22:36:12 +0000 |
---|---|---|
committer | Alexandre Vassalotti <alexandre@peadrop.com> | 2010-01-11 22:36:12 +0000 |
commit | b646547bb45fe1df6abefd94f892c633798d91d2 (patch) | |
tree | ef1add045741d309129266726f5ba45562184091 /Modules/parsermodule.c | |
parent | 0ca7452794bef03b66f56cc996a73cac066d0ec1 (diff) | |
download | cpython-git-b646547bb45fe1df6abefd94f892c633798d91d2.tar.gz |
Issue #2333: Backport set and dict comprehensions syntax.
Diffstat (limited to 'Modules/parsermodule.c')
-rw-r--r-- | Modules/parsermodule.c | 88 |
1 files changed, 56 insertions, 32 deletions
diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 823d754fd8..af331eea17 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -938,9 +938,9 @@ VALIDATER(subscriptlist); VALIDATER(sliceop); VALIDATER(exprlist); VALIDATER(dictorsetmaker); VALIDATER(arglist); VALIDATER(argument); VALIDATER(listmaker); VALIDATER(yield_stmt); -VALIDATER(testlist1); VALIDATER(gen_for); -VALIDATER(gen_iter); VALIDATER(gen_if); -VALIDATER(testlist_gexp); VALIDATER(yield_expr); +VALIDATER(testlist1); VALIDATER(comp_for); +VALIDATER(comp_iter); VALIDATER(comp_if); +VALIDATER(testlist_comp); VALIDATER(yield_expr); VALIDATER(yield_or_testlist); VALIDATER(or_test); VALIDATER(old_test); VALIDATER(old_lambdef); @@ -1342,17 +1342,17 @@ validate_list_iter(node *tree) return res; } -/* gen_iter: gen_for | gen_if +/* comp_iter: comp_for | comp_if */ static int -validate_gen_iter(node *tree) +validate_comp_iter(node *tree) { - int res = (validate_ntype(tree, gen_iter) - && validate_numnodes(tree, 1, "gen_iter")); - if (res && TYPE(CHILD(tree, 0)) == gen_for) - res = validate_gen_for(CHILD(tree, 0)); + int res = (validate_ntype(tree, comp_iter) + && validate_numnodes(tree, 1, "comp_iter")); + if (res && TYPE(CHILD(tree, 0)) == comp_for) + res = validate_comp_for(CHILD(tree, 0)); else - res = validate_gen_if(CHILD(tree, 0)); + res = validate_comp_if(CHILD(tree, 0)); return res; } @@ -1379,18 +1379,18 @@ validate_list_for(node *tree) return res; } -/* gen_for: 'for' exprlist 'in' test [gen_iter] +/* comp_for: 'for' exprlist 'in' test [comp_iter] */ static int -validate_gen_for(node *tree) +validate_comp_for(node *tree) { int nch = NCH(tree); int res; if (nch == 5) - res = validate_gen_iter(CHILD(tree, 4)); + res = validate_comp_iter(CHILD(tree, 4)); else - res = validate_numnodes(tree, 4, "gen_for"); + res = validate_numnodes(tree, 4, "comp_for"); if (res) res = (validate_name(CHILD(tree, 0), "for") @@ -1421,18 +1421,18 @@ validate_list_if(node *tree) return res; } -/* gen_if: 'if' old_test [gen_iter] +/* comp_if: 'if' old_test [comp_iter] */ static int -validate_gen_if(node *tree) +validate_comp_if(node *tree) { int nch = NCH(tree); int res; if (nch == 3) - res = validate_gen_iter(CHILD(tree, 2)); + res = validate_comp_iter(CHILD(tree, 2)); else - res = validate_numnodes(tree, 2, "gen_if"); + res = validate_numnodes(tree, 2, "comp_if"); if (res) res = (validate_name(CHILD(tree, 0), "if") @@ -2459,7 +2459,7 @@ validate_atom(node *tree) if (TYPE(CHILD(tree, 1))==yield_expr) res = validate_yield_expr(CHILD(tree, 1)); else - res = validate_testlist_gexp(CHILD(tree, 1)); + res = validate_testlist_comp(CHILD(tree, 1)); } break; case LSQB: @@ -2539,26 +2539,26 @@ validate_listmaker(node *tree) return ok; } -/* testlist_gexp: - * test ( gen_for | (',' test)* [','] ) +/* testlist_comp: + * test ( comp_for | (',' test)* [','] ) */ static int -validate_testlist_gexp(node *tree) +validate_testlist_comp(node *tree) { int nch = NCH(tree); int ok = nch; if (nch == 0) - err_string("missing child nodes of testlist_gexp"); + err_string("missing child nodes of testlist_comp"); else { ok = validate_test(CHILD(tree, 0)); } /* - * gen_for | (',' test)* [','] + * comp_for | (',' test)* [','] */ - if (nch == 2 && TYPE(CHILD(tree, 1)) == gen_for) - ok = validate_gen_for(CHILD(tree, 1)); + if (nch == 2 && TYPE(CHILD(tree, 1)) == comp_for) + ok = validate_comp_for(CHILD(tree, 1)); else { /* (',' test)* [','] */ int i = 1; @@ -2571,7 +2571,7 @@ validate_testlist_gexp(node *tree) ok = validate_comma(CHILD(tree, i)); else if (i != nch) { ok = 0; - err_string("illegal trailing nodes for testlist_gexp"); + err_string("illegal trailing nodes for testlist_comp"); } } return ok; @@ -2746,7 +2746,7 @@ validate_arglist(node *tree) for (i=0; i<nch; i++) { if (TYPE(CHILD(tree, i)) == argument) { node *ch = CHILD(tree, i); - if (NCH(ch) == 2 && TYPE(CHILD(ch, 1)) == gen_for) { + if (NCH(ch) == 2 && TYPE(CHILD(ch, 1)) == comp_for) { err_string("need '(', ')' for generator expression"); return 0; } @@ -2813,7 +2813,7 @@ validate_arglist(node *tree) /* argument: * - * [test '='] test [gen_for] + * [test '='] test [comp_for] */ static int validate_argument(node *tree) @@ -2824,7 +2824,7 @@ validate_argument(node *tree) && validate_test(CHILD(tree, 0))); if (res && (nch == 2)) - res = validate_gen_for(CHILD(tree, 1)); + res = validate_comp_for(CHILD(tree, 1)); else if (res && (nch == 3)) res = (validate_equal(CHILD(tree, 1)) && validate_test(CHILD(tree, 2))); @@ -2965,12 +2965,19 @@ validate_exprlist(node *tree) } +/* + * dictorsetmaker: + * + * (test ':' test (comp_for | (',' test ':' test)* [','])) | + * (test (comp_for | (',' test)* [','])) + */ static int validate_dictorsetmaker(node *tree) { int nch = NCH(tree); int ok = validate_ntype(tree, dictorsetmaker); int i = 0; + int check_trailing_comma = 0; assert(nch > 0); @@ -2984,6 +2991,23 @@ validate_dictorsetmaker(node *tree) && validate_test(CHILD(tree, i+1))); i += 2; } + check_trailing_comma = 1; + } + else if (ok && TYPE(CHILD(tree, 1)) == comp_for) { + /* We got a set comprehension: + * test comp_for + */ + ok = (validate_test(CHILD(tree, 0)) + && validate_comp_for(CHILD(tree, 1))); + } + else if (ok && NCH(tree) > 3 && TYPE(CHILD(tree, 3)) == comp_for) { + /* We got a dict comprehension: + * test ':' test comp_for + */ + ok = (validate_test(CHILD(tree, 0)) + && validate_colon(CHILD(tree, 1)) + && validate_test(CHILD(tree, 2)) + && validate_comp_for(CHILD(tree, 3))); } else if (ok) { /* We got a dict: @@ -3007,9 +3031,9 @@ validate_dictorsetmaker(node *tree) && validate_test(CHILD(tree, i+3))); i += 4; } + check_trailing_comma = 1; } - /* Check for a trailing comma. */ - if (ok) { + if (ok && check_trailing_comma) { if (i == nch-1) ok = validate_comma(CHILD(tree, i)); else if (i != nch) { |