else if (!PyErr_Occurred()) { const char* name = "except"; if (TYPE(CHILD(tree, nch - 3)) != except_clause) name = STR(CHILD(tree, nch - 3)); PyErr_Format(parser_error, "Illegal number of children for try/%s node.", name); } /* Skip past except_clause sections: */ while (res && (TYPE(CHILD(tree, pos)) == except_clause)) { res = (validate_except_clause(CHILD(tree, pos)) && validate_colon(CHILD(tree, pos + 1)) && validate_suite(CHILD(tree, pos + 2))); pos += 3; } if (res && (pos < nch)) { res = validate_ntype(CHILD(tree, pos), NAME); if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0)) res = (validate_numnodes(tree, 6, "try/finally") && validate_colon(CHILD(tree, 4)) && validate_suite(CHILD(tree, 5))); else if (res) { if (nch == (pos + 3)) { res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0) || (strcmp(STR(CHILD(tree, pos)), "else") == 0)); if (!res) err_string("illegal trailing triple in try statement"); } else if (nch == (pos + 6)) { res = (validate_name(CHILD(tree, pos), "except") && validate_colon(CHILD(tree, pos + 1)) && validate_suite(CHILD(tree, pos + 2)) && validate_name(CHILD(tree, pos + 3), "else")); } else res = validate_numnodes(tree, pos + 3, "try/except"); } } return (res);} static intvalidate_except_clause(node *tree){ int nch = NCH(tree); int res = (validate_ntype(tree, except_clause) && ((nch == 1) || (nch == 2) || (nch == 4)) && validate_name(CHILD(tree, 0), "except")); if (res && (nch > 1)) res = validate_test(CHILD(tree, 1)); if (res && (nch == 4)) res = (validate_comma(CHILD(tree, 2)) && validate_test(CHILD(tree, 3))); return (res);} static intvalidate_test(node *tree){ int nch = NCH(tree); int res = validate_ntype(tree, test) && is_odd(nch); if (res && (TYPE(CHILD(tree, 0)) == lambdef)) res = ((nch == 1) && validate_lambdef(CHILD(tree, 0))); else if (res) { res = validate_or_test(CHILD(tree, 0)); res = (res && (nch == 1 || (nch == 5 && validate_name(CHILD(tree, 1), "if") && validate_or_test(CHILD(tree, 2)) && validate_name(CHILD(tree, 3), "else") && validate_test(CHILD(tree, 4))))); } return (res);} static intvalidate_old_test(node *tree){ int nch = NCH(tree); int res = validate_ntype(tree, old_test) && (nch == 1); if (res && (TYPE(CHILD(tree, 0)) == old_lambdef)) res = (validate_old_lambdef(CHILD(tree, 0))); else if (res) { res = (validate_or_test(CHILD(tree, 0))); } return (res);} static intvalidate_or_test(node *tree){ int nch = NCH(tree); int res = validate_ntype(tree, or_test) && is_odd(nch); if (res) { int pos; res = validate_and_test(CHILD(tree, 0)); for (pos = 1; res && (pos < nch); pos += 2) res = (validate_name(CHILD(tree, pos), "or") && validate_and_test(CHILD(tree, pos + 1))); } return (res);} static intvalidate_and_test(node *tree){ int pos; int nch = NCH(tree); int res = (validate_ntype(tree, and_test) && is_odd(nch) && validate_not_test(CHILD(tree, 0))); for (pos = 1; res && (pos < nch); pos += 2) res = (validate_name(CHILD(tree, pos), "and") && validate_not_test(CHILD(tree, 0))); return (res);} static intvalidate_not_test(node *tree){ int nch = NCH(tree); int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2)); if (res) { if (nch == 2) res = (validate_name(CHILD(tree, 0), "not") && validate_not_test(CHILD(tree, 1))); else if (nch == 1) res = validate_comparison(CHILD(tree, 0)); } return (res);} static intvalidate_comparison(node *tree){ int pos; int nch = NCH(tree); int res = (validate_ntype(tree, comparison) && is_odd(nch) && validate_expr(CHILD(tree, 0))); for (pos = 1; res && (pos < nch); pos += 2) res = (validate_comp_op(CHILD(tree, pos)) && validate_expr(CHILD(tree, pos + 1))); return (res);} static intvalidate_comp_op(node *tree){ int res = 0; int nch = NCH(tree); if (!validate_ntype(tree, comp_op)) return (0); if (nch == 1) { /* * Only child will be a terminal with a well-defined symbolic name * or a NAME with a string of either 'is' or 'in' */ tree = CHILD(tree, 0); switch (TYPE(tree)) { case LESS: case GREATER: case EQEQUAL: case EQUAL: case LESSEQUAL: case GREATEREQUAL: case NOTEQUAL: res = 1; break; case NAME: res = ((strcmp(STR(tree), "in") == 0) || (strcmp(STR(tree), "is") == 0)); if (!res) { PyErr_Format(parser_error, "illegal operator '%s'", STR(tree)); } break; default: err_string("illegal comparison operator type"); break; } } else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) { res = (validate_ntype(CHILD(tree, 0), NAME) && validate_ntype(CHILD(tree, 1), NAME) && (((strcmp(STR(CHILD(tree, 0)), "is") == 0) && (strcmp(STR(CHILD(tree, 1)), "not") == 0)) || ((strcmp(STR(CHILD(tree, 0)), "not") == 0) && (strcmp(STR(CHILD(tree, 1)), "in") == 0)))); if (!res && !PyErr_Occurred()) err_string("unknown comparison operator"); } return (res);} static intvalidate_expr(node *tree){ int j; int nch = NCH(tree); int res = (validate_ntype(tree, expr) && is_odd(nch) && validate_xor_expr(CHILD(tree, 0))); for (j = 2; res && (j < nch); j += 2) res = (validate_xor_expr(CHILD(tree, j)) && validate_vbar(CHILD(tree, j - 1))); return (res);} static intvalidate_xor_expr(node *tree){ int j; int nch = NCH(tree); int res = (validate_ntype(tree, xor_expr) && is_odd(nch) && validate_and_expr(CHILD(tree, 0))); for (j = 2; res && (j < nch); j += 2) res = (validate_circumflex(CHILD(tree, j - 1)) && validate_and_expr(CHILD(tree, j))); return (res);} static intvalidate_and_expr(node *tree){ int pos; int nch = NCH(tree); int res = (validate_ntype(tree, and_expr) && is_odd(nch) && validate_shift_expr(CHILD(tree, 0))); for (pos = 1; res && (pos < nch); pos += 2) res = (validate_ampersand(CHILD(tree, pos)) && validate_shift_expr(CHILD(tree, pos + 1))); return (res);} static intvalidate_chain_two_ops(node *tree, int (*termvalid)(node *), int op1, int op2) { int pos = 1; int nch = NCH(tree); int res = (is_odd(nch) && (*termvalid)(CHILD(tree, 0))); for ( ; res && (pos < nch); pos += 2) { if (TYPE(CHILD(tree, pos)) != op1) res = validate_ntype(CHILD(tree, pos), op2); if (res) res = (*termvalid)(CHILD(tree, pos + 1)); } return (res);} static intvalidate_shift_expr(node *tree){ return (validate_ntype(tree, shift_expr) && validate_chain_two_ops(tree, validate_arith_expr, LEFTSHIFT, RIGHTSHIFT));} static intvalidate_arith_expr(node *tree){ return (validate_ntype(tree, arith_expr) && validate_chain_two_ops(tree, validate_term, PLUS, MINUS));} static intvalidate_term(node *tree){ int pos = 1; int nch = NCH(tree); int res = (validate_ntype(tree, term) && is_odd(nch) && validate_factor(CHILD(tree, 0))); for ( ; res && (pos < nch); pos += 2) res = (((TYPE(CHILD(tree, pos)) == STAR) || (TYPE(CHILD(tree, pos)) == SLASH) || (TYPE(CHILD(tree, pos)) == DOUBLESLASH) || (TYPE(CHILD(tree, pos)) == PERCENT)) && validate_factor(CHILD(tree, pos + 1))); return (res);} /* factor: * * factor: ('+'|'-'|'~') factor | power */static intvalidate_factor(node *tree){ int nch = NCH(tree); int res = (validate_ntype(tree, factor) && (((nch == 2) && ((TYPE(CHILD(tree, 0)) == PLUS) || (TYPE(CHILD(tree, 0)) == MINUS) || (TYPE(CHILD(tree, 0)) == TILDE)) && validate_factor(CHILD(tree, 1))) || ((nch == 1) && validate_power(CHILD(tree, 0))))); return (res);} /* power: * * power: atom trailer* ('**' factor)* */static intvalidate_power(node *tree){ int pos = 1; int nch = NCH(tree); int res = (validate_ntype(tree, power) && (nch >= 1) && validate_atom(CHILD(tree, 0))); while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer)) res = validate_trailer(CHILD(tree, pos++)); if (res && (pos < nch)) { if (!is_even(nch - pos)) { err_string("illegal number of nodes for 'power'"); return (0); } for ( ; res && (pos < (nch - 1)); pos += 2) res = (validate_doublestar(CHILD(tree, pos)) && validate_factor(CHILD(tree, pos + 1))); } return (res);} static intvalidate_atom(node *tree){ int pos; int nch = NCH(tree); int res = validate_ntype(tree, atom); if (res && nch < 1) res = validate_numnodes(tree, nch+1, "atom"); if (res) { switch (TYPE(CHILD(tree, 0))) { case LPAR: res = ((nch <= 3) && (validate_rparen(CHILD(tree, nch - 1)))); if (res && (nch == 3)) { if (TYPE(CHILD(tree, 1))==yield_expr) res = validate_yield_expr(CHILD(tree, 1)); else res = validate_testlist_gexp(CHILD(tree, 1)); } break; case LSQB: if (nch == 2) res = validate_ntype(CHILD(tree, 1), RSQB); else if (nch == 3) res = (validate_listmaker(CHILD(tree, 1)) && validate_ntype(CHILD(tree, 2), RSQB)); else { res = 0; err_string("illegal list display atom"); } break; case LBRACE: res = ((nch <= 3) && validate_ntype(CHILD(tree, nch - 1), RBRACE)); if (res && (nch == 3)) res = validate_dictmaker(CHILD(tree, 1)); break; case BACKQUOTE: res = ((nch == 3) && validate_testlist1(CHILD(tree, 1)) && validate_ntype(CHILD(tree, 2), BACKQUOTE)); break; case NAME: case NUMBER: res = (nch == 1); break; case STRING: for (pos = 1; res && (pos < nch); ++pos) res = validate_ntype(CHILD(tree, pos), STRING); break; default: res = 0; break; } } return (res);} /* listmaker: * test ( list_for | (',' test)* [','] ) */static intvalidate_listmaker(node *tree){ int nch = NCH(tree); int ok = nch; if (nch == 0) err_string("missing child nodes of listmaker"); else ok = validate_test(CHILD(tree, 0)); /* * list_for | (',' test)* [','] */ if (nch == 2 && TYPE(CHILD(tree, 1)) == list_for) ok = validate_list_for(CHILD(tree, 1)); else { /* (',' test)* [','] */ int i = 1; while (ok && nch - i >= 2) { ok = (validate_comma(CHILD(tree, i)) && validate_test(CHILD(tree, i+1))); i += 2; } if (ok && i == nch-1) ok = validate_comma(CHILD(tree, i)); else if (i != nch) { ok = 0; err_string("illegal trailing nodes for listmaker"); } } return ok;} /* testlist_gexp: * test ( gen_for | (',' test)* [','] ) */static intvalidate_testlist_gexp(node *tree){ int nch = NCH(tree); int ok = nch; if (nch == 0) err_string("missing child nodes of testlist_gexp"); else { ok = validate_test(CHILD(tree, 0)); } /* * gen_for | (',' test)* [','] */ if (nch == 2 && TYPE(CHILD(tree, 1)) == gen_for) ok = validate_gen_for(CHILD(tree, 1)); else { /* (',' test)* [','] */ int i = 1; while (ok && nch - i >= 2) { ok = (validate_comma(CHILD(tree, i)) && validate_test(CHILD(tree, i+1))); i += 2; } if (ok && i == nch-1) ok = validate_comma(CHILD(tree, i)); else if (i != nch) { ok = 0; err_string("illegal trailing nodes for testlist_gexp"); } }Lines 2001–2500 of 3279. Previous lines Load more
else if (!PyErr_Occurred()) { const char* name = "except"; if (TYPE(CHILD(tree, nch - 3)) != except_clause) name = STR(CHILD(tree, nch - 3)); PyErr_Format(parser_error, "Illegal number of children for try/%s node.", name); } /* Skip past except_clause sections: */ while (res && (TYPE(CHILD(tree, pos)) == except_clause)) { res = (validate_except_clause(CHILD(tree, pos)) && validate_colon(CHILD(tree, pos + 1)) && validate_suite(CHILD(tree, pos + 2))); pos += 3; } if (res && (pos < nch)) { res = validate_ntype(CHILD(tree, pos), NAME); if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0)) res = (validate_numnodes(tree, 6, "try/finally") && validate_colon(CHILD(tree, 4)) && validate_suite(CHILD(tree, 5))); else if (res) { if (nch == (pos + 3)) { res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0) || (strcmp(STR(CHILD(tree, pos)), "else") == 0)); if (!res) err_string("illegal trailing triple in try statement"); } else if (nch == (pos + 6)) { res = (validate_name(CHILD(tree, pos), "except") && validate_colon(CHILD(tree, pos + 1)) && validate_suite(CHILD(tree, pos + 2)) && validate_name(CHILD(tree, pos + 3), "else")); } else res = validate_numnodes(tree, pos + 3, "try/except"); } } return (res); } static int validate_except_clause(node *tree) { int nch = NCH(tree); int res = (validate_ntype(tree, except_clause) && ((nch == 1) || (nch == 2) || (nch == 4)) && validate_name(CHILD(tree, 0), "except")); if (res && (nch > 1)) res = validate_test(CHILD(tree, 1)); if (res && (nch == 4)) res = (validate_comma(CHILD(tree, 2)) && validate_test(CHILD(tree, 3))); return (res); } static int validate_test(node *tree) { int nch = NCH(tree); int res = validate_ntype(tree, test) && is_odd(nch); if (res && (TYPE(CHILD(tree, 0)) == lambdef)) res = ((nch == 1) && validate_lambdef(CHILD(tree, 0))); else if (res) { res = validate_or_test(CHILD(tree, 0)); res = (res && (nch == 1 || (nch == 5 && validate_name(CHILD(tree, 1), "if") && validate_or_test(CHILD(tree, 2)) && validate_name(CHILD(tree, 3), "else") && validate_test(CHILD(tree, 4))))); } return (res); } static int validate_old_test(node *tree) { int nch = NCH(tree); int res = validate_ntype(tree, old_test) && (nch == 1); if (res && (TYPE(CHILD(tree, 0)) == old_lambdef)) res = (validate_old_lambdef(CHILD(tree, 0))); else if (res) { res = (validate_or_test(CHILD(tree, 0))); } return (res); } static int validate_or_test(node *tree) { int nch = NCH(tree); int res = validate_ntype(tree, or_test) && is_odd(nch); if (res) { int pos; res = validate_and_test(CHILD(tree, 0)); for (pos = 1; res && (pos < nch); pos += 2) res = (validate_name(CHILD(tree, pos), "or") && validate_and_test(CHILD(tree, pos + 1))); } return (res); } static int validate_and_test(node *tree) { int pos; int nch = NCH(tree); int res = (validate_ntype(tree, and_test) && is_odd(nch) && validate_not_test(CHILD(tree, 0))); for (pos = 1; res && (pos < nch); pos += 2) res = (validate_name(CHILD(tree, pos), "and") && validate_not_test(CHILD(tree, 0))); return (res); } static int validate_not_test(node *tree) { int nch = NCH(tree); int res = validate_ntype(tree, not_test) && ((nch == 1) || (nch == 2)); if (res) { if (nch == 2) res = (validate_name(CHILD(tree, 0), "not") && validate_not_test(CHILD(tree, 1))); else if (nch == 1) res = validate_comparison(CHILD(tree, 0)); } return (res); } static int validate_comparison(node *tree) { int pos; int nch = NCH(tree); int res = (validate_ntype(tree, comparison) && is_odd(nch) && validate_expr(CHILD(tree, 0))); for (pos = 1; res && (pos < nch); pos += 2) res = (validate_comp_op(CHILD(tree, pos)) && validate_expr(CHILD(tree, pos + 1))); return (res); } static int validate_comp_op(node *tree) { int res = 0; int nch = NCH(tree); if (!validate_ntype(tree, comp_op)) return (0); if (nch == 1) { /* * Only child will be a terminal with a well-defined symbolic name * or a NAME with a string of either 'is' or 'in' */ tree = CHILD(tree, 0); switch (TYPE(tree)) { case LESS: case GREATER: case EQEQUAL: case EQUAL: case LESSEQUAL: case GREATEREQUAL: case NOTEQUAL: res = 1; break; case NAME: res = ((strcmp(STR(tree), "in") == 0) || (strcmp(STR(tree), "is") == 0)); if (!res) { PyErr_Format(parser_error, "illegal operator '%s'", STR(tree)); } break; default: err_string("illegal comparison operator type"); break; } } else if ((res = validate_numnodes(tree, 2, "comp_op")) != 0) { res = (validate_ntype(CHILD(tree, 0), NAME) && validate_ntype(CHILD(tree, 1), NAME) && (((strcmp(STR(CHILD(tree, 0)), "is") == 0) && (strcmp(STR(CHILD(tree, 1)), "not") == 0)) || ((strcmp(STR(CHILD(tree, 0)), "not") == 0) && (strcmp(STR(CHILD(tree, 1)), "in") == 0)))); if (!res && !PyErr_Occurred()) err_string("unknown comparison operator"); } return (res); } static int validate_expr(node *tree) { int j; int nch = NCH(tree); int res = (validate_ntype(tree, expr) && is_odd(nch) && validate_xor_expr(CHILD(tree, 0))); for (j = 2; res && (j < nch); j += 2) res = (validate_xor_expr(CHILD(tree, j)) && validate_vbar(CHILD(tree, j - 1))); return (res); } static int validate_xor_expr(node *tree) { int j; int nch = NCH(tree); int res = (validate_ntype(tree, xor_expr) && is_odd(nch) && validate_and_expr(CHILD(tree, 0))); for (j = 2; res && (j < nch); j += 2) res = (validate_circumflex(CHILD(tree, j - 1)) && validate_and_expr(CHILD(tree, j))); return (res); } static int validate_and_expr(node *tree) { int pos; int nch = NCH(tree); int res = (validate_ntype(tree, and_expr) && is_odd(nch) && validate_shift_expr(CHILD(tree, 0))); for (pos = 1; res && (pos < nch); pos += 2) res = (validate_ampersand(CHILD(tree, pos)) && validate_shift_expr(CHILD(tree, pos + 1))); return (res); } static int validate_chain_two_ops(node *tree, int (*termvalid)(node *), int op1, int op2) { int pos = 1; int nch = NCH(tree); int res = (is_odd(nch) && (*termvalid)(CHILD(tree, 0))); for ( ; res && (pos < nch); pos += 2) { if (TYPE(CHILD(tree, pos)) != op1) res = validate_ntype(CHILD(tree, pos), op2); if (res) res = (*termvalid)(CHILD(tree, pos + 1)); } return (res); } static int validate_shift_expr(node *tree) { return (validate_ntype(tree, shift_expr) && validate_chain_two_ops(tree, validate_arith_expr, LEFTSHIFT, RIGHTSHIFT)); } static int validate_arith_expr(node *tree) { return (validate_ntype(tree, arith_expr) && validate_chain_two_ops(tree, validate_term, PLUS, MINUS)); } static int validate_term(node *tree) { int pos = 1; int nch = NCH(tree); int res = (validate_ntype(tree, term) && is_odd(nch) && validate_factor(CHILD(tree, 0))); for ( ; res && (pos < nch); pos += 2) res = (((TYPE(CHILD(tree, pos)) == STAR) || (TYPE(CHILD(tree, pos)) == SLASH) || (TYPE(CHILD(tree, pos)) == DOUBLESLASH) || (TYPE(CHILD(tree, pos)) == PERCENT)) && validate_factor(CHILD(tree, pos + 1))); return (res); } /* factor: * * factor: ('+'|'-'|'~') factor | power */ static int validate_factor(node *tree) { int nch = NCH(tree); int res = (validate_ntype(tree, factor) && (((nch == 2) && ((TYPE(CHILD(tree, 0)) == PLUS) || (TYPE(CHILD(tree, 0)) == MINUS) || (TYPE(CHILD(tree, 0)) == TILDE)) && validate_factor(CHILD(tree, 1))) || ((nch == 1) && validate_power(CHILD(tree, 0))))); return (res); } /* power: * * power: atom trailer* ('**' factor)* */ static int validate_power(node *tree) { int pos = 1; int nch = NCH(tree); int res = (validate_ntype(tree, power) && (nch >= 1) && validate_atom(CHILD(tree, 0))); while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer)) res = validate_trailer(CHILD(tree, pos++)); if (res && (pos < nch)) { if (!is_even(nch - pos)) { err_string("illegal number of nodes for 'power'"); return (0); } for ( ; res && (pos < (nch - 1)); pos += 2) res = (validate_doublestar(CHILD(tree, pos)) && validate_factor(CHILD(tree, pos + 1))); } return (res); } static int validate_atom(node *tree) { int pos; int nch = NCH(tree); int res = validate_ntype(tree, atom); if (res && nch < 1) res = validate_numnodes(tree, nch+1, "atom"); if (res) { switch (TYPE(CHILD(tree, 0))) { case LPAR: res = ((nch <= 3) && (validate_rparen(CHILD(tree, nch - 1)))); if (res && (nch == 3)) { if (TYPE(CHILD(tree, 1))==yield_expr) res = validate_yield_expr(CHILD(tree, 1)); else res = validate_testlist_gexp(CHILD(tree, 1)); } break; case LSQB: if (nch == 2) res = validate_ntype(CHILD(tree, 1), RSQB); else if (nch == 3) res = (validate_listmaker(CHILD(tree, 1)) && validate_ntype(CHILD(tree, 2), RSQB)); else { res = 0; err_string("illegal list display atom"); } break; case LBRACE: res = ((nch <= 3) && validate_ntype(CHILD(tree, nch - 1), RBRACE)); if (res && (nch == 3)) res = validate_dictmaker(CHILD(tree, 1)); break; case BACKQUOTE: res = ((nch == 3) && validate_testlist1(CHILD(tree, 1)) && validate_ntype(CHILD(tree, 2), BACKQUOTE)); break; case NAME: case NUMBER: res = (nch == 1); break; case STRING: for (pos = 1; res && (pos < nch); ++pos) res = validate_ntype(CHILD(tree, pos), STRING); break; default: res = 0; break; } } return (res); } /* listmaker: * test ( list_for | (',' test)* [','] ) */ static int validate_listmaker(node *tree) { int nch = NCH(tree); int ok = nch; if (nch == 0) err_string("missing child nodes of listmaker"); else ok = validate_test(CHILD(tree, 0)); /* * list_for | (',' test)* [','] */ if (nch == 2 && TYPE(CHILD(tree, 1)) == list_for) ok = validate_list_for(CHILD(tree, 1)); else { /* (',' test)* [','] */ int i = 1; while (ok && nch - i >= 2) { ok = (validate_comma(CHILD(tree, i)) && validate_test(CHILD(tree, i+1))); i += 2; } if (ok && i == nch-1) ok = validate_comma(CHILD(tree, i)); else if (i != nch) { ok = 0; err_string("illegal trailing nodes for listmaker"); } } return ok; } /* testlist_gexp: * test ( gen_for | (',' test)* [','] ) */ static int validate_testlist_gexp(node *tree) { int nch = NCH(tree); int ok = nch; if (nch == 0) err_string("missing child nodes of testlist_gexp"); else { ok = validate_test(CHILD(tree, 0)); } /* * gen_for | (',' test)* [','] */ if (nch == 2 && TYPE(CHILD(tree, 1)) == gen_for) ok = validate_gen_for(CHILD(tree, 1)); else { /* (',' test)* [','] */ int i = 1; while (ok && nch - i >= 2) { ok = (validate_comma(CHILD(tree, i)) && validate_test(CHILD(tree, i+1))); i += 2; } if (ok && i == nch-1) ok = validate_comma(CHILD(tree, i)); else if (i != nch) { ok = 0; err_string("illegal trailing nodes for testlist_gexp"); } }