summaryrefslogtreecommitdiff
path: root/Modules/parsermodule.c
diff options
context:
space:
mode:
authorAlexandre Vassalotti <alexandre@peadrop.com>2010-01-11 22:36:12 +0000
committerAlexandre Vassalotti <alexandre@peadrop.com>2010-01-11 22:36:12 +0000
commitb646547bb45fe1df6abefd94f892c633798d91d2 (patch)
treeef1add045741d309129266726f5ba45562184091 /Modules/parsermodule.c
parent0ca7452794bef03b66f56cc996a73cac066d0ec1 (diff)
downloadcpython-git-b646547bb45fe1df6abefd94f892c633798d91d2.tar.gz
Issue #2333: Backport set and dict comprehensions syntax.
Diffstat (limited to 'Modules/parsermodule.c')
-rw-r--r--Modules/parsermodule.c88
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) {