summaryrefslogtreecommitdiffstats
path: root/Modules/parsermodule.c
diff options
context:
space:
mode:
authorMark Dickinson <mdickinson@enthought.com>2012-05-07 15:36:33 (GMT)
committerMark Dickinson <mdickinson@enthought.com>2012-05-07 15:36:33 (GMT)
commit72f6095d4fc50c0e92ea0f88df898ffe67cdb67c (patch)
treecd4e893521406cd0efa2eb10a6f494722a9cc53f /Modules/parsermodule.c
parent0576f9b4cf7e4b373eff1e610d6c63682a0ce089 (diff)
parent11c1dee183a39626a904f3f9e09b47dab3fd8117 (diff)
downloadcpython-72f6095d4fc50c0e92ea0f88df898ffe67cdb67c.zip
cpython-72f6095d4fc50c0e92ea0f88df898ffe67cdb67c.tar.gz
cpython-72f6095d4fc50c0e92ea0f88df898ffe67cdb67c.tar.bz2
Issue #14697: Merge fix from 3.2.
Diffstat (limited to 'Modules/parsermodule.c')
-rw-r--r--Modules/parsermodule.c100
1 files changed, 79 insertions, 21 deletions
diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c
index af14657..994de49 100644
--- a/Modules/parsermodule.c
+++ b/Modules/parsermodule.c
@@ -2895,34 +2895,92 @@ validate_exprlist(node *tree)
validate_expr_or_star_expr, "exprlist"));
}
-
+/*
+ * dictorsetmaker:
+ *
+ * (test ':' test (comp_for | (',' test ':' test)* [','])) |
+ * (test (comp_for | (',' test)* [',']))
+ */
static int
validate_dictorsetmaker(node *tree)
{
int nch = NCH(tree);
- int res = (validate_ntype(tree, dictorsetmaker)
- && (nch >= 3)
- && validate_test(CHILD(tree, 0))
- && validate_colon(CHILD(tree, 1))
- && validate_test(CHILD(tree, 2)));
+ int res;
+ int i = 0;
+
+ res = validate_ntype(tree, dictorsetmaker);
+ if (!res)
+ return 0;
- if (res && ((nch % 4) == 0))
- res = validate_comma(CHILD(tree, --nch));
- else if (res)
- res = ((nch % 4) == 3);
-
- if (res && (nch > 3)) {
- int pos = 3;
- /* ( ',' test ':' test )* */
- while (res && (pos < nch)) {
- res = (validate_comma(CHILD(tree, pos))
- && validate_test(CHILD(tree, pos + 1))
- && validate_colon(CHILD(tree, pos + 2))
- && validate_test(CHILD(tree, pos + 3)));
- pos += 4;
+ if (nch - i < 1) {
+ (void) validate_numnodes(tree, 1, "dictorsetmaker");
+ return 0;
+ }
+
+ res = validate_test(CHILD(tree, i++));
+ if (!res)
+ return 0;
+
+ if (nch - i >= 2 && TYPE(CHILD(tree, i)) == COLON) {
+ /* Dictionary display or dictionary comprehension. */
+ res = (validate_colon(CHILD(tree, i++))
+ && validate_test(CHILD(tree, i++)));
+ if (!res)
+ return 0;
+
+ if (nch - i >= 1 && TYPE(CHILD(tree, i)) == comp_for) {
+ /* Dictionary comprehension. */
+ res = validate_comp_for(CHILD(tree, i++));
+ if (!res)
+ return 0;
+ }
+ else {
+ /* Dictionary display. */
+ while (nch - i >= 4) {
+ res = (validate_comma(CHILD(tree, i++))
+ && validate_test(CHILD(tree, i++))
+ && validate_colon(CHILD(tree, i++))
+ && validate_test(CHILD(tree, i++)));
+ if (!res)
+ return 0;
+ }
+ if (nch - i == 1) {
+ res = validate_comma(CHILD(tree, i++));
+ if (!res)
+ return 0;
+ }
}
}
- return (res);
+ else {
+ /* Set display or set comprehension. */
+ if (nch - i >= 1 && TYPE(CHILD(tree, i)) == comp_for) {
+ /* Set comprehension. */
+ res = validate_comp_for(CHILD(tree, i++));
+ if (!res)
+ return 0;
+ }
+ else {
+ /* Set display. */
+ while (nch - i >= 2) {
+ res = (validate_comma(CHILD(tree, i++))
+ && validate_test(CHILD(tree, i++)));
+ if (!res)
+ return 0;
+ }
+ if (nch - i == 1) {
+ res = validate_comma(CHILD(tree, i++));
+ if (!res)
+ return 0;
+ }
+ }
+ }
+
+ if (nch - i > 0) {
+ err_string("Illegal trailing nodes for dictorsetmaker.");
+ return 0;
+ }
+
+ return 1;
}