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

📄 ccx.c

📁 F:反汇编源码代码学习disasm.ZIP
💻 C
📖 第 1 页 / 共 3 页
字号:

    if (BADSTATUS (tok)) {
        va_end(ap);
        RELEASE;
        return tok;
    }

    q = va_arg(ap,PARSER*);

     CALL(tok=(*q),m,a,52);

    va_end(ap);

    if (BADSTATUS (tok))    /* error */
    {
        REWIND;        /* remove this line for 1-token LA parsing */
        return tok;    /* fail */
    }

    pushDECR;
    RELEASE;

    return tok;        /* succeed */
}

STATUS p_starparse0n (VALUE *x,PARSER *p, ...)
/*
Monadic composition of parsers. Does
first p then q, where q can use x, which is the address of p's result.

Assume that q knows that x is an address!

Put p's instructions on the
top of the program stack, then layer q's above it.

This version has full rewind of the input stream on
failure, but this can be altered to single token
lookahead by deleting the line of code marked.
*/
{
    static PARSER *q=p_errparse0;
    va_list ap;

    static int m;
    static PARAM *a;
    static status  tok;

    MARK;

    va_start(ap,p);

    CALL(tok=(*p),m,a,53);
    
    if (BADSTATUS(tok)) {
        va_end(ap);
        RELEASE;
        return tok;
    }

    /* I intend that x be local so that if we later fail, this
     * value will disappear */

    *x = (VALUE)INSTATUS(tok);

    q = va_arg(ap,PARSER*);

        CALL(tok=(*q),m,a,54);

        va_end(ap);

        if (BADSTATUS (tok))    /* error */
        {
            REWIND;        /* remove this line for 1-token LA parsing */
            return tok;    /* fail */
        }
    
        pushDECR;
        RELEASE;
        return tok;        /* succeed */
}


STATUS   p_until0n(PARSER *p, ...)
/* skip until p succeeds. This should be the same as 
   foo = p | ? foo .		   ***** character mode only **********
 */
{
    va_list ap;
    static STATUS tok; 
    static int m;

    while (*pstr) {
        va_start(ap,p);
        CALL(tok=(*p),m,a,55);
        va_end(ap);

        if GOODSTATUS (tok)
            return tok;
        MOVEON;
    }
    return FAILURE;
}

STATUS p_orparse0n (PARSER *p, ...)
/*
alternate composition of parsers. Tries p first,
and if it doesnt work, tries q. Code corresponding
to the successful parse is placed on the program stack.
If both fail, the routine relies on p and q's auto-rewind
mechanisms to do the rewind for it.
*/
{
    va_list ap;

    static PARSER *q=p_errparse0;
    static int m;
    static status  tok;

    va_start(ap,p);

    
    CALL(tok=(*p),m,a,56);

    if (BADSTATUS (tok))    /* error */
    {
        q = va_arg(ap,PARSER*);
    
        CALL(tok=(*q),m,a,57);

    }

    va_end(ap);
    return tok;        /* succeed */
}

STATUS  p_hidden0n (PARSER *p, ...)
/*
parser which tries p, but doesnt moveon, just reports the result
of p.
*/
{
    static va_list ap;

    static int m;
    static status tok;
    MARK;

    va_start(ap,p);

    CALL(tok=(*p),m,a,58);

    va_end(ap);
        
    REWIND;
    if (GOODSTATUS(tok)) {
       pushVALUE(p_hidden0n);
    }

    return tok;
}


STATUS  p_option0n (PARSER *p, ...)
/*
parser which tries p, but doesnt worry if p fails,
just rewinds and considers itself happy with nothing at all.
*/
{
    static va_list ap;

    static int m;
    static status tok;

    va_start(ap,p);

    CALL(tok=(*p),m,a,59);

    va_end(ap);

    if (GOODSTATUS(tok))
        return tok;


    pushINCR;

    return(SUCCESS);

}


STATUS  p_many0n (PARSER *p, ...)
{
    static    va_list(ap);
    static status tok;
    int repeat=0;
    static int m;

/* to use this from a function which has parameters foo,m,a1,...,am
   use va_start(ap,foo) and call us */

loop:
    va_start(ap,p);

    CALL(tok=(*p),m,a,60);

    va_end(ap);

    if (GOODSTATUS(tok)) {
        repeat++;
        goto loop;
    }
    return SUCCESS;
}


STATUS p_uerror0n (PARSER *p, ...)
{
    static va_list(ap);

    static int m;

        va_start(ap,p);
        m=va_arg(ap,int);
        a=(PARAM*)ap;
        ap=(va_list)&a[m];

        /*m++; ?*/

        p_entry = p;  /* set the btck_error reentry pt */
        p_enargs= m;
        memcpy(p_eargv, a, m * sizeof(PARAM));

        va_end(ap);

        pushEXIT;
        pc=0;
        pc=p_evaluate ();
        pc=0;   /* we have to write the next program in the right place */

        if (yytchar!=EOF) /* then we can ask */
          
            {
                /* now we restart */
                realignbuffer();
            }

        passcount++;

        return SUCCESS;
}

STATUS  p_iter0n (int repeat, PARSER *p, ...)
{
    static va_list(ap);

    static int m;
    static status tok;
    static int k;
    MARK;

    k = repeat;

    while(k-->0){
        va_start(ap,p);
        CALL(tok=(*p),m,a,61);
        va_end(ap);

        if (BADSTATUS(tok)) {
            REWIND;
            return FAILURE;
        }
    }
    RELEASE;
    return SUCCESS;
}


STATUS p_prepend0n (ACTION *f, ...)
{
    static PARSER *p;
    static status tok;
    static int m;

    va_list(ap);
    MARK;

    va_start(ap,f);

        m=va_arg(ap,int);
        a=(PARAM*)ap;
        ap=(va_list)&a[m];
        m++;


    while(--m>0)
           pushPARAM(a[m-1]);

    pushACTION(f);

    p = va_arg(ap,PARSER *);

    CALL(tok=(*p),m,a,62);

    va_end(ap);

    if (GOODSTATUS(tok)){
        RELEASE;
        return tok;
    }

    REWIND;

    return tok;
}




STATUS  p_some0n (PARSER *p, ...)
/*
At least one repetition of parser p
*/
{
    static va_list(ap);

    int m;
    status  tok;

    va_start(ap,p);

    /* this should really be a call of p_many0v(p,ap) */

    CALL(tok=(*p),m,a,63);

    va_end(ap);
            
    if (GOODSTATUS(tok)) {
        switch(m-1){
        case 0: tok = p_many0n (p,0); break;
        case 1: tok = p_many0n (p,1,a[0]); break;
        case 2: tok = p_many0n (p,2,a[0],a[1]); break;
        case 3: tok = p_many0n (p,3,a[0],a[1],a[2]); break;
        case 4: tok = p_many0n (p,4,a[0],a[1],a[2],a[3]); break;
        case 5: tok = p_many0n (p,5,a[0],a[1],a[2],a[3],a[4]); break;
        case 6: tok = p_many0n (p,6,a[0],a[1],a[2],a[3],a[4],a[5]); break;
        case 7: tok = p_many0n (p,7,a[0],a[1],a[2],a[3],a[4],a[5],a[6]); break;
        case 8: tok = p_many0n (p,8,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]);
                break;
        case 9: tok = p_many0n (p,9,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],
                a[8]); break;
        case 10:tok = p_many0n (p,10,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],
                a[8],a[9]); break;
        case 11:tok = p_many0n (p,11,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],
                a[8],a[9],a[10]); break;
        case 12:tok = p_many0n (p,12,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],
                a[8],a[9],a[10],a[11]); break;
        case 13:tok = p_many0n (p,13,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],
                a[8],a[9],a[10],a[11],a[12]); break;
        case 14:tok = p_many0n (p,14,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],
                a[8],a[9],a[10],a[11],a[12],a[13]); break;
        case 15:tok = p_many0n (p,15,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],
                a[8],a[9],a[10],a[11],a[12],a[13],a[14]); break;
        case 16:tok = p_many0n (p,16,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],
                a[8],a[9],a[10],a[11],a[12],a[13],a[14],a[15]); break;
        default://printf("error: too many (%d) args in CALL\n",m-1);\
                p_exit(14); break;
        }

        pushDECR;
    }
    return tok;
}


STATUS  p_test0 (x)
/* succeed if x is 1, fail if x is 0 */
int x;
{
    if (x){
        pushVALUE((VALUE)x);
        return OK(x);
    }
    return FAILURE;
}


STATUS p_attach0n (PARSER *p, ...)
/*
attach an action to a parse.
*/
{
    va_list(ap);

    status tok;
    static int m;
    static ACTION *f;

    va_start(ap,p);
    
    CALL(tok=(*p),m,a,51);

    f=va_arg(ap,ACTION*);

    m=va_arg(ap,int);

    a=(PARAM*)ap;
    ap=(va_list)&a[m];
    m++;

    va_end(ap);

    if (GOODSTATUS(tok)){
        while(--m>0){
            pushPARAM(a[m-1]);
        }
        pushACTION(f);
    }
    return tok;
}

STATUS p_range0n (PREDICATE *p, ...)
{
    static va_list(ap);

    boolean tok;    /* could make this static, but range is always a leaf */
    static int m;        /* so it's hardly worth the bother. */

⌨️ 快捷键说明

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