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

📄 inpptree.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    stack[0].token = TOK_END;    next = PTlexer(line);    while ((sp > 1) || (next->token != TOK_END)) {        /* Find the top-most terminal. */        i = sp;        do {            top = &stack[i--];        } while (top->token == TOK_VALUE);        switch (prectable[top->token][next->token]) {        case L:        case E:            /* Push the token read. */            if (sp == (PT_STACKSIZE - 1)) {                fprintf(stderr, "Error: stack overflow\n");                return (NULL);            }            bcopy((char *) next, (char *) &stack[++sp],                    sizeof (PTelement));            next = PTlexer(line);            continue;        case R:            fprintf(stderr, "Syntax error.\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].token == TOK_VALUE)                sp--;            while (sp > 0) {                if (stack[sp - 1].token == TOK_VALUE)                    i = 2;  /* No 2 pnodes together... */                else                    i = 1;                if (prectable[stack[sp - i].token]                         [stack[sp].token] == L)                    break;                else                    sp = sp - i;            }            if (stack[sp - 1].token == TOK_VALUE)                sp--;            /* Now try and see what we can make of this.             * The possibilities are: - node             *            node op node             *            ( node )             *            func ( node )             *            func ( node, node, node, ... )	<- new             *            node             */            if (st == sp) {                pn = makepnode(&stack[st]);                if (pn == NULL)                    goto err;            } else if ((stack[sp].token == TOK_UMINUS) &&                    (st == sp + 1)) {                lpn = makepnode(&stack[st]);                if (lpn == NULL)                        goto err;                pn = mkfnode("-", lpn);            } else if ((stack[sp].token == TOK_LPAREN) &&                       (stack[st].token == TOK_RPAREN)) {                pn = makepnode(&stack[sp + 1]);                if (pn == NULL)                    goto err;            } else if ((stack[sp + 1].token == TOK_LPAREN) &&                       (stack[st].token == TOK_RPAREN)) {                lpn = makepnode(&stack[sp + 2]);                if ((lpn == NULL) || (stack[sp].type != TYP_STRING))                    goto err;                if (!(pn = mkfnode(stack[sp].value.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].token, lpn, rpn);            }            stack[sp].token = TOK_VALUE;            stack[sp].type = TYP_PNODE;            stack[sp].value.pnode = pn;            continue;        }    }    pn = makepnode(&stack[1]);    if (pn)        return (pn);err:    fprintf(stderr, "Syntax error.\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 INPparseNode *makepnode(elem)    PTelement *elem;{    if (elem->token != TOK_VALUE)        return (NULL);    switch (elem->type) {    case TYP_STRING:        return (mksnode(elem->value.string));    case TYP_NUM:        return (mknnode(elem->value.real));    case TYP_PNODE:        return (elem->value.pnode);    default:        fprintf(stderr, "Internal Error: bad token type\n");        return (NULL);    }   }/* Binop node. */static INPparseNode *mkbnode(opnum, arg1, arg2)    int opnum;    INPparseNode *arg1, *arg2;{    INPparseNode *p;    int i;    for (i = 0; i < NUM_OPS; i++)        if (ops[i].number == opnum)            break;    if (i == NUM_OPS) {        fprintf(stderr, "Internal Error: no such op num %d\n",                    opnum);        return (NULL);    }    p = (INPparseNode *) MALLOC(sizeof (INPparseNode));    p->type = opnum;    p->funcname = ops[i].name;    p->function = ops[i].funcptr;    p->left = arg1;    p->right = arg2;    return (p);}static INPparseNode *mkfnode(fname, arg)    char *fname;    INPparseNode *arg;{    int i;    INPparseNode *p;    char buf[128], *name, *s;    IFvalue temp;    /* Make sure the case is ok. */    (void) strcpy(buf, fname);    for (s = buf; *s; s++)        if (isupper(*s))            *s = tolower(*s);    p = (INPparseNode *) MALLOC(sizeof (INPparseNode));    if (!strcmp(buf, "v")) {        name = MALLOC(128);        if (arg->type == PT_PLACEHOLDER) {            strcpy(name, arg->funcname);        } else if (arg->type == PT_CONSTANT) {            (void) sprintf(name, "%d", (int) arg->constant);        } else if (arg->type != PT_COMMA) {            fprintf(stderr, "Error: badly formed node voltage\n");            return (NULL);        }        if (arg->type == PT_COMMA) {	    /* Change v(a,b) into v(a) - v(b) */	    p = mkb(PT_MINUS, mkfnode(fname, arg->left),		mkfnode(fname, arg->right));        } else {	    /* printf("getting a node called '%s'\n", name); */	    INPtermInsert(circuit, &name, tables, &(temp.nValue));	    for (i = 0; i < numvalues; i++)		if ((types[i] == IF_NODE) && (values[i].nValue ==			temp.nValue))		    break;	    if (i == numvalues) {		if (numvalues) {		    values = (IFvalue *) 	    REALLOC((char *) values, (numvalues + 1) * sizeof (IFvalue));		    types = (int *) 	    REALLOC((char *) types, (numvalues + 1) * sizeof (int));		} else {		    values = (IFvalue *) MALLOC(sizeof (IFvalue));		    types = (int *) MALLOC(sizeof (int));		}		values[i] = temp;		types[i] = IF_NODE;		numvalues++;	    }	    p->valueIndex = i;	    p->type = PT_VAR;	}    } else if (!strcmp(buf, "i")) {        name = MALLOC(128);        if (arg->type == PT_PLACEHOLDER)            strcpy(name, arg->funcname);        else if (arg->type == PT_CONSTANT)            (void) sprintf(name, "%d", (int) arg->constant);        else {            fprintf(stderr, "Error: badly formed branch current\n");            return (NULL);        }/* printf("getting a device called '%s'\n", name); */        INPinsert(&name, tables);        for (i = 0; i < numvalues; i++)            if ((types[i] == IF_INSTANCE) && (values[i].uValue ==                    temp.uValue))                break;        if (i == numvalues) {            if (numvalues) {                values = (IFvalue *)         REALLOC((char *) values, (numvalues + 1) * sizeof (IFvalue));                types = (int *)         REALLOC((char *) types, (numvalues + 1) * sizeof (int));            } else {                values = (IFvalue *) MALLOC(sizeof (IFvalue));                types = (int *) MALLOC(sizeof (int));            }            values[i].uValue = (IFuid) name;            types[i] = IF_INSTANCE;            numvalues++;        }        p->valueIndex = i;        p->type = PT_VAR;    } else {	for (i = 0; i < NUM_FUNCS; i++)	    if (!strcmp(funcs[i].name, buf))		break;		if (i == NUM_FUNCS) {	    fprintf(stderr, "Error: no such function '%s'\n", buf);	    return (NULL);	}	p->type = PT_FUNCTION;	p->left = arg;	p->funcname = funcs[i].name;	p->funcnum = funcs[i].number;	p->function = funcs[i].funcptr;    }    return (p);}/* Number node. */static INPparseNode *mknnode(number)    double number;{    struct INPparseNode *p;    p = (INPparseNode *) MALLOC(sizeof (INPparseNode));    p->type = PT_CONSTANT;    p->constant = number;    return (p);}/* String node. */static INPparseNode *mksnode(string)    char *string;{    int i, j;    char buf[128], *s;    INPparseNode *p;    /* Make sure the case is ok. */    (void) strcpy(buf, string);    for (s = buf; *s; s++)        if (isupper(*s))            *s = tolower(*s);    p = (INPparseNode *) MALLOC(sizeof (INPparseNode));    /* First see if it's something special. */    for (i = 0; i < ft_sim->numSpecSigs; i++)        if (!strcmp(ft_sim->specSigs[i], buf))            break;    if (i < ft_sim->numSpecSigs) {        for (j = 0; j < numvalues; j++)            if ((types[j] == IF_STRING) && !strcmp(buf,                    values[i].sValue))                break;        if (j == numvalues) {            if (numvalues) {                values = (IFvalue *)         REALLOC((char *) values, (numvalues + 1) * sizeof (IFvalue));                types = (int *)         REALLOC((char *) types, (numvalues + 1) * sizeof (int));            } else {                values = (IFvalue *) MALLOC(sizeof (IFvalue));                types = (int *) MALLOC(sizeof (int));            }            values[i].sValue = MALLOC(strlen(buf) + 1);            strcpy(values[i].sValue, buf);            types[i] = IF_STRING;            numvalues++;        }        p->valueIndex = i;        p->type = PT_VAR;        return (p);    }    for (i = 0; i < NUM_CONSTANTS; i++)        if (!strcmp(constants[i].name, buf))            break;        if (i == NUM_CONSTANTS) {        /* We'd better save this in case it's part of i(something). */        p->type = PT_PLACEHOLDER;        p->funcname = string;    } else {        p->type = PT_CONSTANT;        p->constant = constants[i].value;    }    return (p);}/* The lexical analysis routine. */static PTelement *PTlexer(line)    char **line;{    double td;    int err;    static PTelement el;    static char *specials = " \t()^+-*/,";    static int lasttoken = TOK_END, lasttype;    char *sbuf, *s;    sbuf = *line;#ifdef notdef    printf("entering lexer, sbuf = '%s', lastoken = %d, lasttype = %d\n",         sbuf, lasttoken, lasttype);#endif    while ((*sbuf == ' ') || (*sbuf == '\t') || (*sbuf == '='))        sbuf++;    switch (*sbuf) {    case '\0':        el.token = TOK_END;        break;    case ',':	el.token = TOK_COMMA;        sbuf++;	break;    case '-':        if ((lasttoken == TOK_VALUE) || (lasttoken == TOK_RPAREN))            el.token = TOK_MINUS;        else            el.token = TOK_UMINUS;        sbuf++;        break;    case '+':        el.token = TOK_PLUS;         sbuf++;        break;    case '*':        el.token = TOK_TIMES;         sbuf++;        break;    case '/':        el.token = TOK_DIVIDE;         sbuf++;        break;    case '^':        el.token = TOK_POWER;         sbuf++;        break;    case '(':        if (((lasttoken == TOK_VALUE) && ((lasttype == TYP_NUM))) ||                (lasttoken == TOK_RPAREN)) {            el.token = TOK_END;        } else {            el.token = TOK_LPAREN;             sbuf++;        }        break;    case ')':        el.token = TOK_RPAREN;         sbuf++;        break;        default:        if ((lasttoken == TOK_VALUE) || (lasttoken == TOK_RPAREN)) {            el.token = TOK_END;            break;        }	td = INPevaluate(&sbuf, &err, 0);        if (err == OK) {            el.token = TOK_VALUE;            el.type = TYP_NUM;            el.value.real = td;        } else {            el.token = TOK_VALUE;            el.type = TYP_STRING;            for (s = sbuf; *s; s++)                if (index(specials, *s))                    break;            el.value.string = MALLOC(s - sbuf + 1);            strncpy(el.value.string, sbuf, s - sbuf);            el.value.string[s - sbuf] = '\0';            sbuf = s;        }    }    lasttoken = el.token;    lasttype = el.type;    *line = sbuf;/* printf("PTlexer: token = %d, type = %d, left = '%s'\n",         el.token, el.type, sbuf); */    return (&el);}#ifdef notdef/* Debugging stuff. */#ifdef __STDC__void printTree(INPparseNode*);#else /* stdc */void printTree();#endif /* stdc */voidINPptPrint(str, ptree)    char *str;    IFparseTree *ptree;{    int i;    printf("%s\n\t", str);    printTree(((INPparseTree *) ptree)->tree);    printf("\n");    for (i = 0; i < ptree->numVars; i++) {        printf("d / d v%d : ", i);        printTree(((INPparseTree *) ptree)->derivs[i]);        printf("\n");    }    return;}voidprintTree(pt)    INPparseNode *pt;{    switch (pt->type) {        case PT_CONSTANT:        printf("%g", pt->constant);        break;        case PT_VAR:        printf("v%d", pt->valueIndex);        break;        case PT_PLUS:        printf("(");        printTree(pt->left);        printf(") + (");        printTree(pt->right);        printf(")");        break;        case PT_MINUS:        printf("(");        printTree(pt->left);        printf(") - (");        printTree(pt->right);        printf(")");        break;        case PT_TIMES:        printf("(");        printTree(pt->left);        printf(") * (");        printTree(pt->right);        printf(")");        break;        case PT_DIVIDE:        printf("(");        printTree(pt->left);        printf(") / (");        printTree(pt->right);        printf(")");        break;        case PT_POWER:        printf("(");        printTree(pt->left);        printf(") ^ (");        printTree(pt->right);        printf(")");        break;        case PT_FUNCTION:        printf("%s (", pt->funcname);        printTree(pt->left);        printf(")");        break;        default:        printf("oops");        break;    }    return;}#endif

⌨️ 快捷键说明

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