⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parsermodule.c

📁 python s60 1.4.5版本的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (TYPE(n) != t) {
        PyErr_Format(parser_error, "Expected node type %d, got %d.",
                     t, TYPE(n));
        return 0;
    }
    return 1;
}


/*  Verifies that the number of child nodes is exactly 'num', raising
 *  an exception if it isn't.  The exception message does not indicate
 *  the exact number of nodes, allowing this to be used to raise the
 *  "right" exception when the wrong number of nodes is present in a
 *  specific variant of a statement's syntax.  This is commonly used
 *  in that fashion.
 */
static int
validate_numnodes(node *n, int num, const char *const name)
{
    if (NCH(n) != num) {
        PyErr_Format(parser_error,
                     "Illegal number of children for %s node.", name);
        return 0;
    }
    return 1;
}


static int
validate_terminal(node *terminal, int type, char *string)
{
    int res = (validate_ntype(terminal, type)
               && ((string == 0) || (strcmp(string, STR(terminal)) == 0)));

    if (!res && !PyErr_Occurred()) {
        PyErr_Format(parser_error,
                     "Illegal terminal: expected \"%s\"", string);
    }
    return (res);
}


/*  X (',' X) [',']
 */
static int
validate_repeating_list(node *tree, int ntype, int (*vfunc)(node *),
                        const char *const name)
{
    int nch = NCH(tree);
    int res = (nch && validate_ntype(tree, ntype)
               && vfunc(CHILD(tree, 0)));

    if (!res && !PyErr_Occurred())
        (void) validate_numnodes(tree, 1, name);
    else {
        if (is_even(nch))
            res = validate_comma(CHILD(tree, --nch));
        if (res && nch > 1) {
            int pos = 1;
            for ( ; res && pos < nch; pos += 2)
                res = (validate_comma(CHILD(tree, pos))
                       && vfunc(CHILD(tree, pos + 1)));
        }
    }
    return (res);
}


/*  validate_class()
 *
 *  classdef:
 *      'class' NAME ['(' testlist ')'] ':' suite
 */
static int
validate_class(node *tree)
{
    int nch = NCH(tree);
    int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));

    if (res) {
        res = (validate_name(CHILD(tree, 0), "class")
               && validate_ntype(CHILD(tree, 1), NAME)
               && validate_colon(CHILD(tree, nch - 2))
               && validate_suite(CHILD(tree, nch - 1)));
    }
    else
        (void) validate_numnodes(tree, 4, "class");
    if (res && (nch == 7)) {
        res = (validate_lparen(CHILD(tree, 2))
               && validate_testlist(CHILD(tree, 3))
               && validate_rparen(CHILD(tree, 4)));
    }
    return (res);
}


/*  if_stmt:
 *      'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
 */
static int
validate_if(node *tree)
{
    int nch = NCH(tree);
    int res = (validate_ntype(tree, if_stmt)
               && (nch >= 4)
               && validate_name(CHILD(tree, 0), "if")
               && validate_test(CHILD(tree, 1))
               && validate_colon(CHILD(tree, 2))
               && validate_suite(CHILD(tree, 3)));

    if (res && ((nch % 4) == 3)) {
        /*  ... 'else' ':' suite  */
        res = (validate_name(CHILD(tree, nch - 3), "else")
               && validate_colon(CHILD(tree, nch - 2))
               && validate_suite(CHILD(tree, nch - 1)));
        nch -= 3;
    }
    else if (!res && !PyErr_Occurred())
        (void) validate_numnodes(tree, 4, "if");
    if ((nch % 4) != 0)
        /* Will catch the case for nch < 4 */
        res = validate_numnodes(tree, 0, "if");
    else if (res && (nch > 4)) {
        /*  ... ('elif' test ':' suite)+ ...  */
        int j = 4;
        while ((j < nch) && res) {
            res = (validate_name(CHILD(tree, j), "elif")
                   && validate_colon(CHILD(tree, j + 2))
                   && validate_test(CHILD(tree, j + 1))
                   && validate_suite(CHILD(tree, j + 3)));
            j += 4;
        }
    }
    return (res);
}


/*  parameters:
 *      '(' [varargslist] ')'
 *
 */
static int
validate_parameters(node *tree)
{
    int nch = NCH(tree);
    int res = validate_ntype(tree, parameters) && ((nch == 2) || (nch == 3));

    if (res) {
        res = (validate_lparen(CHILD(tree, 0))
               && validate_rparen(CHILD(tree, nch - 1)));
        if (res && (nch == 3))
            res = validate_varargslist(CHILD(tree, 1));
    }
    else {
        (void) validate_numnodes(tree, 2, "parameters");
    }
    return (res);
}


/*  validate_suite()
 *
 *  suite:
 *      simple_stmt
 *    | NEWLINE INDENT stmt+ DEDENT
 */
static int
validate_suite(node *tree)
{
    int nch = NCH(tree);
    int res = (validate_ntype(tree, suite) && ((nch == 1) || (nch >= 4)));

    if (res && (nch == 1))
        res = validate_simple_stmt(CHILD(tree, 0));
    else if (res) {
        /*  NEWLINE INDENT stmt+ DEDENT  */
        res = (validate_newline(CHILD(tree, 0))
               && validate_indent(CHILD(tree, 1))
               && validate_stmt(CHILD(tree, 2))
               && validate_dedent(CHILD(tree, nch - 1)));

        if (res && (nch > 4)) {
            int i = 3;
            --nch;                      /* forget the DEDENT     */
            for ( ; res && (i < nch); ++i)
                res = validate_stmt(CHILD(tree, i));
        }
        else if (nch < 4)
            res = validate_numnodes(tree, 4, "suite");
    }
    return (res);
}


static int
validate_testlist(node *tree)
{
    return (validate_repeating_list(tree, testlist,
                                    validate_test, "testlist"));
}


static int
validate_testlist_safe(node *tree)
{
    return (validate_repeating_list(tree, testlist_safe,
                                    validate_test, "testlist_safe"));
}


/* '*' NAME [',' '**' NAME] | '**' NAME
 */
static int
validate_varargslist_trailer(node *tree, int start)
{
    int nch = NCH(tree);
    int res = 0;
    int sym;

    if (nch <= start) {
        err_string("expected variable argument trailer for varargslist");
        return 0;
    }
    sym = TYPE(CHILD(tree, start));
    if (sym == STAR) {
        /*
         *  ('*' NAME [',' '**' NAME]
         */
        if (nch-start == 2)
            res = validate_name(CHILD(tree, start+1), NULL);
        else if (nch-start == 5)
            res = (validate_name(CHILD(tree, start+1), NULL)
                   && validate_comma(CHILD(tree, start+2))
                   && validate_doublestar(CHILD(tree, start+3))
                   && validate_name(CHILD(tree, start+4), NULL));
    }
    else if (sym == DOUBLESTAR) {
        /*
         *  '**' NAME
         */
        if (nch-start == 2)
            res = validate_name(CHILD(tree, start+1), NULL);
    }
    if (!res)
        err_string("illegal variable argument trailer for varargslist");
    return res;
}


/*  validate_varargslist()
 *
 *  varargslist:
 *      (fpdef ['=' test] ',')*
 *           ('*' NAME [',' '**' NAME]
 *         | '**' NAME)
 *    | fpdef ['=' test] (',' fpdef ['=' test])* [',']
 *
 */
static int
validate_varargslist(node *tree)
{
    int nch = NCH(tree);
    int res = validate_ntype(tree, varargslist) && (nch != 0);
    int sym;

    if (!res)
        return 0;
    if (nch < 1) {
        err_string("varargslist missing child nodes");
        return 0;
    }
    sym = TYPE(CHILD(tree, 0));
    if (sym == STAR || sym == DOUBLESTAR)
        /* whole thing matches:
         *      '*' NAME [',' '**' NAME] | '**' NAME
         */
        res = validate_varargslist_trailer(tree, 0);
    else if (sym == fpdef) {
        int i = 0;

        sym = TYPE(CHILD(tree, nch-1));
        if (sym == NAME) {
            /*
             *   (fpdef ['=' test] ',')+
             *       ('*' NAME [',' '**' NAME]
             *     | '**' NAME)
             */
            /* skip over (fpdef ['=' test] ',')+ */
            while (res && (i+2 <= nch)) {
                res = validate_fpdef(CHILD(tree, i));
                ++i;
                if (res && TYPE(CHILD(tree, i)) == EQUAL && (i+2 <= nch)) {
                    res = (validate_equal(CHILD(tree, i))
                           && validate_test(CHILD(tree, i+1)));
                    if (res)
                        i += 2;
                }
                if (res && i < nch) {
                    res = validate_comma(CHILD(tree, i));
                    ++i;
                    if (res && i < nch
                        && (TYPE(CHILD(tree, i)) == DOUBLESTAR
                            || TYPE(CHILD(tree, i)) == STAR))
                        break;
                }
            }
            /* ... '*' NAME [',' '**' NAME] | '**' NAME
             * i --^^^
             */
            if (res)
                res = validate_varargslist_trailer(tree, i);
        }
        else {
            /*
             *  fpdef ['=' test] (',' fpdef ['=' test])* [',']
             */
            /* strip trailing comma node */
            if (sym == COMMA) {
                res = validate_comma(CHILD(tree, nch-1));
                if (!res)
                    return 0;
                --nch;
            }
            /*
             *  fpdef ['=' test] (',' fpdef ['=' test])*
             */
            res = validate_fpdef(CHILD(tree, 0));
            ++i;
            if (res && (i+2 <= nch) && TYPE(CHILD(tree, i)) == EQUAL) {
                res = (validate_equal(CHILD(tree, i))
                       && validate_test(CHILD(tree, i+1)));
                i += 2;
            }
            /*
             *  ... (',' fpdef ['=' test])*
             *  i ---^^^
             */
            while (res && (nch - i) >= 2) {
                res = (validate_comma(CHILD(tree, i))
                       && validate_fpdef(CHILD(tree, i+1)));
                i += 2;
                if (res && (nch - i) >= 2 && TYPE(CHILD(tree, i)) == EQUAL) {
                    res = (validate_equal(CHILD(tree, i))
                           && validate_test(CHILD(tree, i+1)));
                    i += 2;
                }
            }
            if (res && nch - i != 0) {
                res = 0;
                err_string("illegal formation for varargslist");
            }
        }
    }
    return res;
}


/*  list_iter:  list_for | list_if
 */
static int
validate_list_iter(node *tree)
{
    int res = (validate_ntype(tree, list_iter)
               && validate_numnodes(tree, 1, "list_iter"));
    if (res && TYPE(CHILD(tree, 0)) == list_for)
        res = validate_list_for(CHILD(tree, 0));
    else
        res = validate_list_if(CHILD(tree, 0));

    return res;
}

/*  list_for:  'for' exprlist 'in' testlist [list_iter]
 */
static int
validate_list_for(node *tree)
{
    int nch = NCH(tree);
    int res;

    if (nch == 5)
        res = validate_list_iter(CHILD(tree, 4));
    else
        res = validate_numnodes(tree, 4, "list_for");

    if (res)
        res = (validate_name(CHILD(tree, 0), "for")
               && validate_exprlist(CHILD(tree, 1))
               && validate_name(CHILD(tree, 2), "in")
               && validate_testlist_safe(CHILD(tree, 3)));

    return res;
}

/*  list_if:  'if' test [list_iter]
 */
static int
validate_list_if(node *tree)
{
    int nch = NCH(tree);
    int res;

    if (nch == 3)
        res = validate_list_iter(CHILD(tree, 2));
    else
        res = validate_numnodes(tree, 2, "list_if");

    if (res)
        res = (validate_name(CHILD(tree, 0), "if")
               && validate_test(CHILD(tree, 1)));

    return res;
}


/*  validate_fpdef()
 *
 *  fpdef:
 *      NAME
 *    | '(' fplist ')'
 */
static int
validate_fpdef(node *tree)
{
    int nch = NCH(tree);
    int res = validate_ntype(tree, fpdef);

    if (res) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -