예제 #1
0
파일: ppproc.c 프로젝트: BR903/cppp
/* Partially preprocesses a #if expression. ifexp points to the text
 * immediately following the #if. The function seeks to the end of the
 * expression and evaluates it. The return value points to the text
 * immediately following the expression. If the expression has a
 * defined state, status receives either statDefined or statUndefined.
 * If the expression's contents are disjoint from the defined and
 * undefined symbols, status receives statUnaffected. Otherwise the
 * expression is in a partial state, in which case status receives
 * statPartDefined, and the original string is modified so as to
 * remove the parts of the expression that have a defined state.
 */
static char const *seqif(struct ppproc *ppp, char *ifexp, enum status *status)
{
    struct exptree *tree;
    char const *ret;
    char *str;
    int defined, n;

    tree = initexptree();
    *status = statUnaffected;

    n = geterrormark();
    ret = parseexptree(tree, ppp->cl, ifexp);
    if (errorsincemark(n)) {
	*status = statError;
	goto quit;
    }

    n = markdefined(tree, ppp->defs, TRUE) +
	markdefined(tree, ppp->undefs, FALSE);
    if (n) {
	*status = evaltree(tree, &defined) ? statDefined : statUndefined;
	if (!defined) {
	    *status = statPartDefined;
	    str = allocate(strlen(ifexp) + 1);
	    n = unparseevaluated(tree, str);
	    strcpy(str + n, ifexp + getexplength(tree));
	    strcpy(ifexp, str);
	    deallocate(str);
	}
    }

  quit:
    freeexptree(tree);
    return ret;
}
예제 #2
0
파일: exptree.c 프로젝트: pix/cppp
/* Creates and returns a new subtree, with pos being the index of
 * which child branch to insert the new subtree at.
 */
static struct exptree *addnewchild(struct exptree *t, int pos)
{
    struct exptree *child;

    child = initexptree();
    if (!addchild(t, child, pos)) {
	deallocate(child);
	return NULL;
    }
    return child;
}
예제 #3
0
파일: exptree.c 프로젝트: pix/cppp
/* Parses a C preprocessor expression from the C source code pointed
 * to by input, via the given lexer, and creates a expression tree
 * representing it. prec gives the precedence of the operator this
 * expression is attached to, or zero if there is no such operator.
 * The return value points to the source immediately following the
 * parsed expression.
 */
static char const *parseexp(struct exptree *t, struct clexer *cl,
			    char const *input, int prec)
{
    struct exptree *x;
    char const *tmp;
    int found, n;

    if (t->exp != expNone)
	return input;

    if (*input == '(') {
	tmp = input;
	input = skipwhite(cl, nextchar(cl, input));
	input = parseexp(t, cl, input, 0);
	if (t->exp == expNone) {
	    error(errSyntax);
	    goto failure;
	} else if (*input != ')') {
	    error(errOpenParenthesis);
	    goto failure;
	}
	t->begin = tmp;
	input = nextchar(cl, input);
	t->end = input;
	input = skipwhite(cl, input);
    } else {
	found = FALSE;
	for (n = 0 ; n < sizearray(prefixops) ; ++n) {
	    if (!memcmp(input, prefixops[n].symbol, prefixops[n].size)) {
		found = TRUE;
		break;
	    }
	}
	if (found) {
	    if (prefixops[n].prec < prec) {
		error(errMissingOperand);
		goto failure;
	    }
	    t->exp = expOperator;
	    t->op = prefixops[n].op;
	    t->begin = input;
	    input = nextchars(cl, input, prefixops[n].size);
	    input = skipwhite(cl, input);
	    x = addnewchild(t, -1);
	    input = parseexp(x, cl, input, prefixops[n].prec);
	    if (x->exp == expNone) {
		error(errSyntax);
		goto failure;
	    }
	    t->end = x->end;
	} else {
	    input = parseconstant(t, cl, input);
	    if (t->exp == expNone) {
		error(errSyntax);
		goto failure;
	    }
	}
    }

    for (;;) {
	found = FALSE;
	for (n = 0 ; n < sizearray(infixops) ; ++n) {
	    if (!memcmp(input, infixops[n].symbol, infixops[n].size)) {
		found = TRUE;
		break;
	    }
	}
	if (!found || infixops[n].prec < prec
		   || (infixops[n].prec == prec && infixops[n].l2r))
	    break;
	input = nextchars(cl, input, infixops[n].size);
	input = skipwhite(cl, input);
	x = initexptree();
	tmp = t->begin;
	*x = *t;
	clearexptree(t);
	t->exp = expOperator;
	t->op = infixops[n].op;
	t->begin = tmp;
	addchild(t, x, -1);
	x = addnewchild(t, -1);
	if (t->op == opConditional) {
	    input = parseexp(x, cl, input, infixops[n].prec);
	    if (x->exp == expNone) {
		error(errSyntax);
		goto failure;
	    }
	    if (*input != ':') {
		error(errSyntax);
		goto failure;
	    }
	    input = skipwhite(cl, nextchar(cl, input));
	    x = addnewchild(t, -1);
	}
	input = parseexp(x, cl, input, infixops[n].prec);
	if (x->exp == expNone) {
	    error(errSyntax);
	    goto failure;
	}
	t->end = x->end;
    }
    return input;

  failure:
    t->exp = expNone;
    return input;
}