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

📄 parse.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    stack[0].e_token = END;    next = lexer();    while ((sp > 1) || (next->e_token != END)) {        /* Find the top-most terminal. */        i = sp;        do {            top = &stack[i--];        } while (top->e_token == VALUE);        rel = prectable[top->e_token][next->e_token];        switch (rel) {            case L:            case E:            /* Push the token read. */            if (sp == (STACKSIZE - 1)) {                fprintf(cp_err, "Error: stack overflow\n");                return (NULL);            }            bcopy((char *) next, (char *) &stack[++sp],                    sizeof (struct element));            next = lexer();            continue;            case R:            fprintf(cp_err, "Syntax error: parsing expression.\n");            return (NULL);            case G:            /* Reduce. Make st and sp point to the elts on the             * stack at the end and beginning of the junk to             * reduce, then try and do some stuff. When scanning             * back for a <, ignore VALUES.             */            st = sp;            if (stack[sp].e_token == VALUE)                sp--;            while (sp > 0) {                if (stack[sp - 1].e_token == VALUE)                    i = 2;  /* No 2 pnodes together... */                else                    i = 1;                if (prectable[stack[sp - i].e_token]                         [stack[sp].e_token] == L)                    break;                else                    sp = sp - i;            }            if (stack[sp - 1].e_token == VALUE)                sp--;            /* Now try and see what we can make of this.             * The possibilities are: unop node             *            node op node             *            ( node )             *            func ( node )             *            node             *  node [ node ] is considered node op node.             */            if (st == sp) {                pn = makepnode(&stack[st]);                if (pn == NULL)                    goto err;            } else if (((stack[sp].e_token == UMINUS) ||                    (stack[sp].e_token == NOT)) &&                     (st == sp + 1)) {                lpn = makepnode(&stack[st]);                if (lpn == NULL)                        goto err;                pn = mkunode(stack[sp].e_token, lpn);            } else if ((stack[sp].e_token == LPAREN) &&                       (stack[st].e_token == RPAREN)) {                pn = makepnode(&stack[sp + 1]);                if (pn == NULL)                    goto err;            } else if ((stack[sp + 1].e_token == LPAREN) &&                       (stack[st].e_token == RPAREN)) {                lpn = makepnode(&stack[sp + 2]);                if ((lpn == NULL) || (stack[sp].e_type !=                        STRING))                    goto err;                if (!(pn = mkfnode(stack[sp].e_string, lpn)))                    return (NULL);            } else { /* node op node */                lpn = makepnode(&stack[sp]);                rpn = makepnode(&stack[st]);                if ((lpn == NULL) || (rpn == NULL))                    goto err;                pn = mkbnode(stack[sp + 1].e_token,                     lpn, rpn);            }            stack[sp].e_token = VALUE;            stack[sp].e_type = PNODE;            stack[sp].e_pnode = pn;            continue;        }    }    pn = makepnode(&stack[1]);    if (pn)        return (pn);err:    fprintf(cp_err, "Syntax error: expression not understood.\n");    return (NULL);}/* Given a pointer to an element, make a pnode out of it (if it already * is one, return a pointer to it). If it isn't of type VALUE, then return * NULL. */static struct pnode *makepnode(elem)    struct element *elem;{    if (elem->e_token != VALUE)        return (NULL);    switch (elem->e_type) {        case STRING:            return (mksnode(elem->e_string));        case NUM:            return (mknnode(elem->e_double));        case PNODE:            return (elem->e_pnode);        default:            return (NULL);    }   }/* Some auxiliary functions for building the parse tree. */staticstruct op ops[] = {         { PLUS, "+", 2, op_plus } ,        { MINUS, "-", 2, op_minus } ,        { TIMES, "*", 2, op_times } ,        { MOD, "%", 2, op_mod } ,        { DIVIDE, "/", 2, op_divide } ,        { COMMA, ",", 2, op_comma } ,        { POWER, "^", 2, op_power } ,        { EQ, "=", 2, op_eq } ,        { GT, ">", 2, op_gt } ,        { LT, "<", 2, op_lt } ,        { GE, ">=", 2, op_ge } ,        { LE, "<=", 2, op_le } ,        { NE, "<>", 2, op_ne } ,        { AND, "&", 2, op_and } ,        { OR, "|", 2, op_or } ,        { INDX, "[", 2, op_ind } ,        { RANGE, "[[", 2, op_range } ,        { 0, NULL, 0, NULL }} ;staticstruct op uops[] = {    { UMINUS, "-", 1, op_uminus } ,    { NOT, "~", 1, op_not } ,    { 0, NULL, 0, NULL }} ;/* We have 'v' declared as a function, because if we don't then the defines * we do for vm(), etc won't work. This is caught in evaluate(). Bad kludge. */struct func ft_funcs[] = {        { "mag",    cx_mag } ,        { "magnitude",  cx_mag } ,        { "ph",     cx_ph } ,        { "phase",  cx_ph } ,        { "j",      cx_j } ,        { "real",   cx_real } ,        { "re",     cx_real } ,        { "imag",   cx_imag } ,        { "im",     cx_imag } ,        { "db",     cx_db } ,        { "log",    cx_log } ,        { "log10",  cx_log } ,        { "ln",     cx_ln } ,        { "exp",    cx_exp } ,        { "abs",    cx_mag } ,        { "sqrt",   cx_sqrt } ,        { "sin",    cx_sin } ,        { "cos",    cx_cos } ,        { "tan",    cx_tan } ,        { "atan",   cx_atan } ,        { "norm",   cx_norm } ,        { "rnd",    cx_rnd } ,        { "pos",    cx_pos } ,        { "mean",   cx_mean } ,        { "vector", cx_vector } ,        { "unitvec",    cx_unitvec } ,        { "length", cx_length } ,        { "interpolate",cx_interpolate } ,        { "deriv",  cx_deriv } ,        { "v",      NULL } ,        { NULL,     NULL }} ;struct func func_uminus = { "minus", cx_uminus };struct func func_not = { "not", cx_not };/* Binop node. */static struct pnode *mkbnode(opnum, arg1, arg2)    struct pnode *arg1, *arg2;{    struct op *o;    struct pnode *p;    for (o = &ops[0]; o->op_name; o++)        if (o->op_num == opnum)            break;    if (!o->op_name)        fprintf(cp_err, "mkbnode: Internal Error: no such op num %d\n",                    opnum);    p = alloc(struct pnode);    p->pn_value = NULL;    p->pn_func = NULL;    p->pn_op = o;    p->pn_left = arg1;    p->pn_right = arg2;    p->pn_next = NULL;    return (p);}/* Unop node. */static struct pnode *mkunode(op, arg)    struct pnode *arg;{    struct pnode *p;    struct op *o;    p = alloc(struct pnode);    for (o = uops; o->op_name; o++)        if (o->op_num == op)            break;    if (!o->op_name)        fprintf(cp_err, "mkunode: Internal Error: no such op num %d\n",                op);    p->pn_op = o;    p->pn_value = NULL;    p->pn_func = NULL;    p->pn_left = arg;    p->pn_right = NULL;    p->pn_next = NULL;    return (p);}/* Function node. We have to worry about a lot of things here. Something * like f(a) could be three things -- a call to a standard function, which * is easiest to deal with, a variable name, in which case we do the * kludge with 0-length lists, or it could be a user-defined function, * in which case we have to figure out which one it is, substitute for * the arguments, and then return a copy of the expression that it was * defined to be. */static struct pnode *mkfnode(func, arg)    char *func;    struct pnode *arg;{    struct func *f;    struct pnode *p, *q;    struct dvec *d;    char buf[BSIZE_SP], *s;    (void) strcpy(buf, func);    for (s = buf; *s; s++)      /* Make sure the case is ok. */        if (isupper(*s))            *s = tolower(*s);    for (f = &ft_funcs[0]; f->fu_name; f++)        if (eq(f->fu_name, buf))            break;    if (f->fu_name == NULL) {        /* Give the user-defined functions a try. */        q = ft_substdef(func, arg);        if (q)            return (q);    }    if ((f->fu_name == NULL) && arg->pn_value) {        /* Kludge -- maybe it is really a variable name. */        (void) sprintf(buf, "%s(%s)", func, arg->pn_value->v_name);        d = vec_get(buf);        if (d == NULL) {            /* Well, too bad. */            fprintf(cp_err, "Error: no such function as %s.\n",                     func);            return (NULL);        }        /* (void) strcpy(buf, d->v_name); XXX */        return (mksnode(buf));    } else if (f->fu_name == NULL) {        fprintf(cp_err, "Error: no function as %s with that arity.\n",                func);            return (NULL);    }    if (!f->fu_func && arg->pn_op && arg->pn_op->op_num == COMMA) {	p = mkbnode(MINUS, mkfnode(func, arg->pn_left),		mkfnode(func, arg->pn_right));	tfree(arg);	return p;    }    p = alloc(struct pnode);    p->pn_name = NULL;    p->pn_value = NULL;    p->pn_func = f;    p->pn_op = NULL;    p->pn_left = arg;    p->pn_right = NULL;    p->pn_next = NULL;    return (p);}/* Number node. */static struct pnode *mknnode(number)    double number;{    struct pnode *p;    struct dvec *v;    char buf[BSIZE_SP];    p = alloc(struct pnode);    v = alloc(struct dvec);    ZERO(v, struct dvec);    p->pn_name = NULL;    p->pn_value = v;    p->pn_func = NULL;    p->pn_op = NULL;    p->pn_left = p->pn_right = NULL;    p->pn_next = NULL;    /* We don't use printnum because it screws up mkfnode above. We have     * to be careful to deal properly with node numbers that are quite     * large...     */    if (number < MAXPOSINT)        (void) sprintf(buf, "%d", (int) number);    else        (void) sprintf(buf, "%G", number);    v->v_name = copy(buf);    v->v_type = SV_NOTYPE;    v->v_flags = VF_REAL;    v->v_realdata = (double *) tmalloc(sizeof (double));    *v->v_realdata = number;    v->v_length = 1;    v->v_plot = NULL;    vec_new(v);    return (p);}/* String node. */static struct pnode *mksnode(string)    char *string;{    struct dvec *v, *nv, *vs, *newv = NULL, *end = NULL;    struct pnode *p;    p = alloc(struct pnode);    p->pn_name = NULL;    p->pn_func = NULL;    p->pn_op = NULL;    p->pn_left = p->pn_right = NULL;    p->pn_next = NULL;    v = vec_get(string);    if (v == NULL) {        nv = alloc(struct dvec);	ZERO(nv, struct dvec);        p->pn_value = nv;        nv->v_name = copy(string);        return (p);    }    p->pn_value = NULL;    /* It's not obvious that we should be doing this, but... */    for (vs = v; vs; vs = vs->v_link2) {        nv = vec_copy(vs);        vec_new(nv);        if (end)            end->v_link2 = nv;        else            newv = end = nv;        end = nv;    }    p->pn_value = newv;    return (p);}voidfree_pnode(t)    struct pnode *t;{    if (!t)	return;    free_pnode(t->pn_left);    free_pnode(t->pn_right);    free_pnode(t->pn_next);    tfree(t);}

⌨️ 快捷键说明

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