Example #1
0
///<param name = "**line"> Line to parse </param>
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;// TODO: Remove GOTO

				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;// TODO: Remove GOTO

			}
			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;// TODO: Remove GOTO

				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;// TODO: Remove GOTO

				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);
}
Example #2
0
///<param name = "*fname"> The name of the function </param>
///<param name = "*arg"> The argument it is given </param>
static INPparseNode *mkfnode(char *fname, INPparseNode *arg)
{
	int i;
	INPparseNode *p = NULL;
	char buf[128], *name = NULL, *s = NULL;
	IFvalue temp;

	temp.nValue = 0;// this line is required by microsoft. Generates a C4700 error if this is not included
	/* 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));
			/* This block is reallocating the value variable. Although defined as a pointer, it is actually being used as a dynamic array*/
			for (i = 0; i < numvalues; i++)
			{
				if ((types[i] == IF_NODE) && (values[i].nValue == temp.nValue))
					break;
			}
			if (i == numvalues)
			{
				if (numvalues)
				{
					/*This is a test*/
					values = (IFvalue *)REALLOC((char *)values, (numvalues + 1) * sizeof(IFvalue)); /* values is becoming an array where each element is IFvalue. Dynamic Array Allocation */
					types = (int *)REALLOC((char *)types, (numvalues + 1) * sizeof(int));
				}
				else
				{
					/* If numvalues is 0, then the program will allocate values with 1 cell
						The program will only execute this block once						*/
					values = (IFvalue *)MALLOC(sizeof(IFvalue)); /* values is becoming an array where each element is 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);
}
Example #3
0
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);
}