diff options
author | Mark Dickinson <mdickinson@enthought.com> | 2012-05-07 15:34:34 (GMT) |
---|---|---|
committer | Mark Dickinson <mdickinson@enthought.com> | 2012-05-07 15:34:34 (GMT) |
commit | 11c1dee183a39626a904f3f9e09b47dab3fd8117 (patch) | |
tree | c6e6fb5ba8ba5e13d475a46f72fe3ba7066c36ab /Modules/parsermodule.c | |
parent | cf360b92099d3ebcd31f637e45df501f393ff0b0 (diff) | |
download | cpython-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.c | 100 |
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; } |