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

📄 inpptree.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
#define L 2			/* Less than. */#define E 3			/* Equal. */#define R 4			/* Error. */static char prectable[11][11] = {    /* $  +  -  *  /  ^  u- (  )  v  , *//* $ */ {R, L, L, L, L, L, L, L, R, L, R},/* + */ {G, G, G, L, L, L, L, L, G, L, G},/* - */ {G, G, G, L, L, L, L, L, G, L, G},/* * */ {G, G, G, G, G, L, L, L, G, L, G},/* / */ {G, G, G, G, G, L, L, L, G, L, G},/* ^ */ {G, G, G, G, G, L, L, L, G, L, G},/* u-*/ {G, G, G, G, G, G, G, L, G, L, R},/* ( */ {R, L, L, L, L, L, L, L, E, L, L},/* ) */ {G, G, G, G, G, G, G, R, G, R, G},/* v */ {G, G, G, G, G, G, G, G, G, R, G},/* , */ {G, L, L, L, L, L, L, L, G, L, G}};/* Return an expr. */static INPparseNode *PTparse(char **line){    PTelement stack[PT_STACKSIZE];    int sp = 0, st, i;    PTelement *top, *next;    INPparseNode *pn, *lpn, *rpn;    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(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(int opnum, INPparseNode * arg1,			     INPparseNode * 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(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(double number){    struct INPparseNode *p;    p = (INPparseNode *) MALLOC(sizeof(INPparseNode));    p->type = PT_CONSTANT;    p->constant = number;    return (p);}/* String node. */static INPparseNode *mksnode(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(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, 1);	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. */void printTree(INPparseNode *);void INPptPrint(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;}void printTree(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 + -