summaryrefslogtreecommitdiffstats
path: root/Modules/parsermodule.c
diff options
context:
space:
mode:
authorMark Dickinson <mdickinson@enthought.com>2012-05-07 15:34:34 (GMT)
committerMark Dickinson <mdickinson@enthought.com>2012-05-07 15:34:34 (GMT)
commit11c1dee183a39626a904f3f9e09b47dab3fd8117 (patch)
treec6e6fb5ba8ba5e13d475a46f72fe3ba7066c36ab /Modules/parsermodule.c
parentcf360b92099d3ebcd31f637e45df501f393ff0b0 (diff)
downloadcpython-11c1dee183a39626a904f3f9e09b47dab3fd8117.zip
cpython-11c1dee183a39626a904f3f9e09b47dab3fd8117.tar.gz
cpython-11c1dee183a39626a904f3f9e09b47dab3fd8117.tar.bz2
Issue #14697: Fix missing parser module support for set displays and set comprehensions.
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 89ad978..05861ed 100644
--- a/Modules/parsermodule.c
+++ b/Modules/parsermodule.c
@@ -2865,34 +2865,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;
}