cppexp.c: Redefine priority constants.
* cppexp.c: Redefine priority constants. (_cpp_parse_expr): Replace left and right priority scheme with single priority logic. Move LOGICAL to same place as COMPARE. Remove bogus check for multiple unary +/- operators. From-SVN: r32855
This commit is contained in:
parent
9ee70313bc
commit
dbac4affb5
@ -1,3 +1,10 @@
|
||||
2000-04-01 Neil Booth <NeilB@earthling.net>
|
||||
|
||||
* cppexp.c: Redefine priority constants.
|
||||
(_cpp_parse_expr): Replace left and right priority scheme with
|
||||
single priority logic. Move LOGICAL to same place as COMPARE.
|
||||
Remove bogus check for multiple unary +/- operators.
|
||||
|
||||
2000-04-01 Neil Booth <NeilB@earthling.net>
|
||||
|
||||
* cppexp.c: (_cpp_parse_expr): Numerical constants are pushed
|
||||
|
139
gcc/cppexp.c
139
gcc/cppexp.c
@ -106,7 +106,7 @@ static struct operation lex PARAMS ((cpp_reader *, int));
|
||||
struct operation
|
||||
{
|
||||
short op;
|
||||
U_CHAR rprio; /* Priority of op (relative to it right operand). */
|
||||
U_CHAR prio; /* Priority of op (relative to it right operand). */
|
||||
U_CHAR flags;
|
||||
U_CHAR unsignedp; /* true if value should be treated as unsigned */
|
||||
HOST_WIDEST_INT value; /* The value logically "right" of op. */
|
||||
@ -636,32 +636,60 @@ right_shift (pfile, a, unsignedp, b)
|
||||
return a >> b;
|
||||
}
|
||||
|
||||
/* These priorities are all even, so we can handle associatively. */
|
||||
#define PAREN_INNER_PRIO 2
|
||||
#define COMMA_PRIO 4
|
||||
#define COND_PRIO (COMMA_PRIO+2)
|
||||
#define OROR_PRIO (COND_PRIO+2)
|
||||
#define ANDAND_PRIO (OROR_PRIO+2)
|
||||
#define OR_PRIO (ANDAND_PRIO+2)
|
||||
#define XOR_PRIO (OR_PRIO+2)
|
||||
#define AND_PRIO (XOR_PRIO+2)
|
||||
#define EQUAL_PRIO (AND_PRIO+2)
|
||||
#define LESS_PRIO (EQUAL_PRIO+2)
|
||||
#define SHIFT_PRIO (LESS_PRIO+2)
|
||||
#define PLUS_PRIO (SHIFT_PRIO+2)
|
||||
#define MUL_PRIO (PLUS_PRIO+2)
|
||||
#define UNARY_PRIO (MUL_PRIO+2)
|
||||
#define PAREN_OUTER_PRIO (UNARY_PRIO+2)
|
||||
/* Operator precedence table.
|
||||
|
||||
After an operator is returned from the lexer, if it has priority less
|
||||
than or equal to the operator on the top of the stack, we reduce the
|
||||
stack one operator and repeat the test. As equal priorities reduce,
|
||||
this is naturally left-associative.
|
||||
|
||||
We handle right-associative operators by clearing the lower bit of all
|
||||
left-associative operators, and setting it for right-associative ones.
|
||||
After the reduction phase, when an operator is pushed onto the stack,
|
||||
its RIGHT_ASSOC bit is cleared. This means that at reduction time, a
|
||||
right-associative operator of otherwise equal precedence to the
|
||||
operator on the top of the stack will have a greater priority by 1,
|
||||
avoiding a reduction pass and making the logic right-associative.
|
||||
|
||||
The remaining cases are '(' and ')'. We handle '(' by skipping the
|
||||
reduction phase completely. ')' is given lower priority than
|
||||
everything else, including '(', effectively forcing a reduction of the
|
||||
parenthesised expression. If there is no matching '(', the expression
|
||||
will be reduced to the beginning, the ')' pushed, and the reduction
|
||||
pass forced by the next ')', or the end of the expression, will meet
|
||||
it and output an appropriate error message. */
|
||||
|
||||
#define RIGHT_ASSOC 1
|
||||
#define PREVENT_REDUCE_PRIO (0 << 1)
|
||||
#define FORCE_REDUCE_PRIO (1 << 1)
|
||||
#define CLOSE_PAREN_PRIO (2 << 1)
|
||||
#define OPEN_PAREN_PRIO (3 << 1)
|
||||
#define COMMA_PRIO (4 << 1)
|
||||
#define COND_PRIO ((5 << 1) + RIGHT_ASSOC)
|
||||
#define COLON_PRIO (6 << 1)
|
||||
#define OROR_PRIO (7 << 1)
|
||||
#define ANDAND_PRIO (8 << 1)
|
||||
#define OR_PRIO (9 << 1)
|
||||
#define XOR_PRIO (10 << 1)
|
||||
#define AND_PRIO (11 << 1)
|
||||
#define EQUAL_PRIO (12 << 1)
|
||||
#define LESS_PRIO (13 << 1)
|
||||
#define SHIFT_PRIO (14 << 1)
|
||||
#define PLUS_PRIO (15 << 1)
|
||||
#define MUL_PRIO (16 << 1)
|
||||
#define UNARY_PRIO ((17 << 1) + RIGHT_ASSOC)
|
||||
|
||||
#define LEFT_OPERAND_REQUIRED 1
|
||||
#define RIGHT_OPERAND_REQUIRED 2
|
||||
#define HAVE_VALUE 4
|
||||
#define SIGN_QUALIFIED 8
|
||||
|
||||
#define COMPARE(OP) \
|
||||
top->unsignedp = 0;\
|
||||
top->value = (unsigned1 || unsigned2) \
|
||||
? (unsigned HOST_WIDEST_INT) v1 OP (unsigned HOST_WIDEST_INT) v2 : (v1 OP v2)
|
||||
#define LOGICAL(OP) \
|
||||
top->value = v1 OP v2;\
|
||||
top->unsignedp = unsigned1 || unsigned2;
|
||||
|
||||
/* Parse and evaluate a C expression, reading from PFILE.
|
||||
Returns the truth value of the expression. */
|
||||
@ -685,16 +713,16 @@ _cpp_parse_expr (pfile)
|
||||
struct operation *stack = init_stack;
|
||||
struct operation *limit = stack + INIT_STACK_SIZE;
|
||||
register struct operation *top = stack;
|
||||
unsigned int lprio, rprio = 0;
|
||||
int skip_evaluation = 0;
|
||||
long old_written = CPP_WRITTEN (pfile);
|
||||
int result;
|
||||
|
||||
pfile->parsing_if_directive++;
|
||||
top->rprio = 0;
|
||||
top->prio = PREVENT_REDUCE_PRIO;
|
||||
top->flags = 0;
|
||||
for (;;)
|
||||
{
|
||||
unsigned int prio;
|
||||
struct operation op;
|
||||
U_CHAR flags = 0;
|
||||
|
||||
@ -730,59 +758,47 @@ _cpp_parse_expr (pfile)
|
||||
continue;
|
||||
|
||||
case '+': case '-':
|
||||
lprio = PLUS_PRIO;
|
||||
prio = PLUS_PRIO;
|
||||
if (top->flags & HAVE_VALUE)
|
||||
break;
|
||||
if (top->flags & SIGN_QUALIFIED)
|
||||
{
|
||||
cpp_error (pfile, "more than one sign operator given");
|
||||
goto syntax_error;
|
||||
}
|
||||
flags = SIGN_QUALIFIED;
|
||||
/* else fall through */
|
||||
case '!': case '~':
|
||||
flags |= RIGHT_OPERAND_REQUIRED;
|
||||
rprio = UNARY_PRIO; lprio = rprio + 1; goto maybe_reduce;
|
||||
prio = UNARY_PRIO; goto maybe_reduce;
|
||||
|
||||
case '*': case '/': case '%':
|
||||
lprio = MUL_PRIO; break;
|
||||
case '<': case '>': case LEQ: case GEQ:
|
||||
lprio = LESS_PRIO; break;
|
||||
case EQUAL: case NOTEQUAL:
|
||||
lprio = EQUAL_PRIO; break;
|
||||
case LSH: case RSH:
|
||||
lprio = SHIFT_PRIO; break;
|
||||
case '&': lprio = AND_PRIO; break;
|
||||
case '^': lprio = XOR_PRIO; break;
|
||||
case '|': lprio = OR_PRIO; break;
|
||||
case ANDAND: lprio = ANDAND_PRIO; break;
|
||||
case OROR: lprio = OROR_PRIO; break;
|
||||
case ',':
|
||||
lprio = COMMA_PRIO; break;
|
||||
case '(':
|
||||
lprio = PAREN_OUTER_PRIO; rprio = PAREN_INNER_PRIO + 1;
|
||||
goto skip_reduction;
|
||||
case '*':
|
||||
case '/':
|
||||
case '%': prio = MUL_PRIO; break;
|
||||
case '<':
|
||||
case '>':
|
||||
case LEQ:
|
||||
case GEQ: prio = LESS_PRIO; break;
|
||||
case NOTEQUAL:
|
||||
case EQUAL: prio = EQUAL_PRIO; break;
|
||||
case LSH:
|
||||
case RSH: prio = SHIFT_PRIO; break;
|
||||
case '&': prio = AND_PRIO; break;
|
||||
case '^': prio = XOR_PRIO; break;
|
||||
case '|': prio = OR_PRIO; break;
|
||||
case ANDAND: prio = ANDAND_PRIO; break;
|
||||
case OROR: prio = OROR_PRIO; break;
|
||||
case ',': prio = COMMA_PRIO; break;
|
||||
case '(': prio = OPEN_PAREN_PRIO; goto skip_reduction;
|
||||
case ')':
|
||||
lprio = PAREN_INNER_PRIO; rprio = PAREN_OUTER_PRIO;
|
||||
prio = CLOSE_PAREN_PRIO;
|
||||
flags = HAVE_VALUE; /* At least, we will have after reduction. */
|
||||
goto maybe_reduce;
|
||||
case ':':
|
||||
lprio = COND_PRIO; rprio = COND_PRIO + 1;
|
||||
goto maybe_reduce;
|
||||
case '?':
|
||||
lprio = COND_PRIO; rprio = COND_PRIO;
|
||||
goto maybe_reduce;
|
||||
case 0:
|
||||
lprio = 0; goto maybe_reduce;
|
||||
case ':': prio = COLON_PRIO; goto maybe_reduce;
|
||||
case '?': prio = COND_PRIO; goto maybe_reduce;
|
||||
case 0: prio = FORCE_REDUCE_PRIO; goto maybe_reduce;
|
||||
}
|
||||
|
||||
/* Binary operation. */
|
||||
flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
|
||||
rprio = lprio + 1;
|
||||
|
||||
maybe_reduce:
|
||||
/* Push an operator, and check if we can reduce now. */
|
||||
while (top->rprio > lprio)
|
||||
/* Check for reductions. Then push the operator. */
|
||||
while (prio <= top->prio)
|
||||
{
|
||||
HOST_WIDEST_INT v1 = top[-1].value, v2 = top[0].value;
|
||||
unsigned int unsigned1 = top[-1].unsignedp;
|
||||
@ -932,9 +948,6 @@ _cpp_parse_expr (pfile)
|
||||
else
|
||||
top->value = right_shift (pfile, v1, unsigned1, v2);
|
||||
break;
|
||||
#define LOGICAL(OP) \
|
||||
top->value = v1 OP v2;\
|
||||
top->unsignedp = unsigned1 || unsigned2;
|
||||
case '&': LOGICAL(&); break;
|
||||
case '^': LOGICAL(^); break;
|
||||
case '|': LOGICAL(|); break;
|
||||
@ -953,7 +966,7 @@ _cpp_parse_expr (pfile)
|
||||
top->unsignedp = unsigned2;
|
||||
break;
|
||||
case '?':
|
||||
cpp_error (pfile, "syntax error in #if");
|
||||
cpp_error (pfile, "syntax error '?' without following ':'");
|
||||
goto syntax_error;
|
||||
case ':':
|
||||
if (top[0].op != '?')
|
||||
@ -1027,7 +1040,7 @@ _cpp_parse_expr (pfile)
|
||||
}
|
||||
|
||||
top->flags = flags;
|
||||
top->rprio = rprio;
|
||||
top->prio = prio & ~RIGHT_ASSOC;
|
||||
top->op = op.op;
|
||||
|
||||
/* Handle short circuiting. */
|
||||
|
Loading…
Reference in New Issue
Block a user