Issue #2333: Backport set and dict comprehensions syntax.
diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c
index 823d754..af331ee 100644
--- a/Modules/parsermodule.c
+++ b/Modules/parsermodule.c
@@ -938,9 +938,9 @@
 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 @@
     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 @@
     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 @@
     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 @@
 		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 @@
     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 @@
             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 @@
         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 @@
 
 /*  argument:
  *
- *  [test '='] test [gen_for]
+ *  [test '='] test [comp_for]
  */
 static int
 validate_argument(node *tree)
@@ -2824,7 +2824,7 @@
                && 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 @@
 }
 
 
+/* 
+ * 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_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_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) {