home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
TOP
/
USR
/
SRC
/
scpp.t.Z
/
scpp.t
/
parse.c
< prev
next >
Wrap
Text File
|
2009-11-06
|
23KB
|
870 lines
# line 74 "parse.y"
typedef union {
int intval; /* yacc stack entries */
struct anode *lexval; /* everything in this file */
} YYSTYPE;
# define MUL 257
# define DIV 258
# define MOD 259
# define PLUS 260
# define MINUS 261
# define LS 262
# define RS 263
# define AND 264
# define OR 265
# define ER 266
# define LT 267
# define LE 268
# define GT 269
# define GE 270
# define EQ 271
# define NE 272
# define ANDAND 273
# define OROR 274
# define CM 275
# define QUEST 276
# define COLON 277
# define NOT 278
# define COMPL 279
# define LP 280
# define RP 281
# define INT 282
# define FLOAT 283
# define IDENT 284
# define QUOTE 285
# define DQUOTE 286
# define BACKS 287
# define OPENC 288
# define CLOSEC 289
# define WHITE 290
# define NL 291
# define QNL 292
# define COMMENT 293
# define OTHER 294
# define STRING 295
# define CHARS 296
# define POUNDLINE 297
# define DEFMAC 298
# line 86 "parse.y"
# include "scpp.h"
/*
* struct anode - the structure used to pass strings.
* Allocated by mknode();
* Deallocated by freenode().
* The string described will be in pend[] and is NOT NULL-TERMINATED.
*/
struct anode {
int an_val; /*
* lexical (token) value of this string.
* A value of 0 == this node is free.
*/
int an_ifval; /* integer result of this expression */
};
# define NODESIZ 100 /* max number of nodes in a #if expresssion */
struct anode nodepool[NODESIZ];
struct anode *mknode();
# define NIL ((struct anode *) 0)
#define yyclearin yychar = -1
#define yyerrok yyerrflag = 0
extern int yychar;
extern int yyerrflag;
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 150
#endif
YYSTYPE yylval, yyval;
typedef int yytabelem;
# define YYERRCODE 256
# line 289 "parse.y"
yyerror(s)
char *s;
{
struct anode *anp;
/* free all nodes */
for (anp = &nodepool[0]; anp < &nodepool[NODESIZ]; anp++) {
anp->an_val = 0;
}
warnf("syntax error in #if");
}
/*
* yylex() - the lexical analyzer for #if statements.
* yylex() reads from the stream of interpreted macros, skipping
* insignificant tokens, then sets yylval appropriately and returns
* the token number of the token.
*/
int
yylex()
{
int tok;
/*
* Skip whitespace, quoted newlines, and interpreted preprocessor
* directives;
* End-of-file or an unquoted newline marks the end of the parse;
* calculate the value of integers and character constants.
*/
if (!(yylval.lexval = mknode())) {
return(0);
}
while ((tok = gintok()) == WHITE || tok == COMMENT || tok == QNL)
;
if (tok == 0 || tok == NL) {
freenode(yylval.lexval);
yylval.lexval = NIL;
return(0);
}
yylval.lexval->an_val = tok;
if (tok == INT) {
yylval.lexval->an_ifval = inttok(curtext, nxtout);
} else if (tok == CHARS) {
yylval.lexval->an_val = INT;
yylval.lexval->an_ifval = chartok(curtext, nxtout);
}
return(yylval.lexval->an_val);
}
/*
* inttok - convert integer token.
* Given the bounds of a token of type INT, return the value of that integer.
*/
int
inttok(s, e)
char *s, *e;
{
char *str; /* points to a (dynamically alloc'ed) copy of the tok */
char *cp;
int base; /* the radix of this integer */
int value; /* the value to return */
int digit; /* the value of the current digit */
/*
* get a copy of the token (to remove ATTN bytes and null-terminate
* the string), and find out what the number base is.
*/
str = savtok(s, e);
cp = str;
if (*cp != '0') {
base = 10;
} else {
if (*cp && (*++cp == 'x' || *cp == 'X')) {
++cp;
base = 16;
} else {
base = 8;
}
}
/*
* convert the string
*/
value = 0;
for (;*cp; ++cp) {
if (*cp >= '0' && *cp <= '7') {
digit = (int)(*cp - '0');
} else if (*cp >= '8' && *cp <= '9' && base >= 10) {
digit = (int)(*cp - '0');
} else if (*cp >= 'a' && *cp <= 'f' && base == 16) {
digit = (int)(*cp - 'a') + 10;
} else if (*cp >= 'A' && *cp <= 'F' && base == 16) {
digit = (int)(*cp - 'A') + 10;
} else {
break;
}
value = value * base + digit;
}
free(str);
return(value);
}
/*
* chartok() - convert a character constant token.
* given the bounds of a character constant, return the integer value
* of that character constant.
*/
int
chartok(s, e)
char *s, *e;
{
char *str; /* (dynamically alloc'ed) copy of the token */
char *cp;
int value; /* value to return */
int cnt;
str = savtok(s, e);
cp = str + 1;
if (*cp != '\\') {
value = (int) *cp;
} else if (*++cp == 'n') {
value = (int) '\n';
} else if (*cp == 't') {
value = (int) '\t';
} else if (*cp == 'b') {
value = (int) '\b';
/*--read the book to find out the other chars supported--*/
} else if (*cp >= '0' && *cp <= '7') {
for (value = 0, cnt = 3; cnt >= 1 && *cp >= '0' && *cp <= '7';
--cnt, ++cp) {
value = value * 8 + (int)(*cp - '0');
}
} else {
value = (int) *cp;
}
free(str);
return(value);
}
struct anode *
mknode()
{
struct anode *anp;
for (anp = &nodepool[0];
anp < &nodepool[NODESIZ] && anp->an_val != 0; anp++)
;
if (anp >= &nodepool[NODESIZ]) {
warnf("#if expression too complex");
return(NIL);
}
anp->an_val = OTHER;
return(anp);
}
freenode(n)
struct anode *n;
{
n->an_val = 0;
}
yytabelem yyexca[] ={
-1, 1,
0, -1,
-2, 0,
};
# define YYNPROD 30
#define YYLAST 246
yytabelem yyact[]={
2, 11, 12, 13, 14, 15, 16, 17, 34, 11,
12, 13, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
53, 54, 11, 12, 13, 14, 15, 16, 17, 24,
26, 25, 18, 20, 19, 21, 22, 23, 27, 28,
30, 29, 4, 3, 1, 0, 55, 57, 31, 32,
33, 11, 12, 13, 14, 15, 0, 0, 0, 5,
6, 7, 0, 8, 0, 9, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 10,
11, 12, 13, 14, 15, 16, 17, 24, 26, 25,
18, 20, 19, 21, 22, 23, 27, 28, 30, 29,
56, 11, 12, 13, 14, 15, 16, 17, 24, 26,
25, 18, 20, 19, 21, 22, 23, 27, 28, 30,
29, 11, 12, 13, 14, 15, 16, 17, 24, 26,
25, 18, 20, 19, 21, 22, 23, 27, 28, 0,
29, 11, 12, 13, 14, 15, 16, 17, 24, 26,
25, 18, 20, 19, 21, 22, 23, 27, 11, 12,
13, 14, 15, 16, 17, 24, 26, 25, 18, 20,
19, 21, 22, 23, 11, 12, 13, 14, 15, 16,
17, 24, 0, 25, 18, 20, 19, 21, 22, 23,
11, 12, 13, 14, 15, 16, 17, 24, 0, 0,
18, 20, 19, 21, 22, 23, 11, 12, 13, 14,
15, 16, 17, 0, 0, 0, 18, 20, 19, 21,
22, 23, 11, 12, 13, 14, 15, 16, 17, 0,
0, 0, 18, 20, 19, 21 };
yytabelem yypact[]={
-209, -1000, -146, -1000, -209, -209, -209, -209, -1000, -1000,
-1000, -209, -209, -209, -209, -209, -209, -209, -209, -209,
-209, -209, -209, -209, -209, -209, -209, -209, -209, -209,
-209, -1000, -1000, -1000, -225, -1000, -1000, -1000, -248, -248,
-196, -196, -256, -256, -256, -256, -25, -25, -41, -57,
-73, -89, -106, -167, -126, -1000, -209, -126 };
yytabelem yypgo[]={
0, 54, 0, 53 };
yytabelem yyr1[]={
0, 1, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 3, 3, 3, 3, 3, 3, 3 };
yytabelem yyr2[]={
0, 3, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
11, 7, 3, 5, 5, 5, 7, 3, 3, 3 };
yytabelem yychk[]={
-1000, -1, -2, -3, 261, 278, 279, 280, 282, 284,
298, 257, 258, 259, 260, 261, 262, 263, 267, 269,
268, 270, 271, 272, 264, 266, 265, 273, 274, 276,
275, -3, -3, -3, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, 281, 277, -2 };
yytabelem yydef[]={
0, -2, 1, 22, 0, 0, 0, 0, 27, 28,
29, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 23, 24, 25, 0, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 0, 21, 26, 0, 20 };
typedef struct { char *t_name; int t_val; } yytoktype;
#ifndef YYDEBUG
#define YYDEBUG 0 /* don't allow debugging */
#endif
#ifdef YYDEBUG
yytoktype yytoks[] =
{
"MUL", 257,
"DIV", 258,
"MOD", 259,
"PLUS", 260,
"MINUS", 261,
"LS", 262,
"RS", 263,
"AND", 264,
"OR", 265,
"ER", 266,
"LT", 267,
"LE", 268,
"GT", 269,
"GE", 270,
"EQ", 271,
"NE", 272,
"ANDAND", 273,
"OROR", 274,
"CM", 275,
"QUEST", 276,
"COLON", 277,
"NOT", 278,
"COMPL", 279,
"LP", 280,
"RP", 281,
"INT", 282,
"FLOAT", 283,
"IDENT", 284,
"QUOTE", 285,
"DQUOTE", 286,
"BACKS", 287,
"OPENC", 288,
"CLOSEC", 289,
"WHITE", 290,
"NL", 291,
"QNL", 292,
"COMMENT", 293,
"OTHER", 294,
"STRING", 295,
"CHARS", 296,
"POUNDLINE", 297,
"DEFMAC", 298,
"-unknown-", -1 /* ends search */
};
char * yyreds[] =
{
"-no such reduction-",
"exp : e",
"e : e MUL e",
"e : e DIV e",
"e : e MOD e",
"e : e PLUS e",
"e : e MINUS e",
"e : e LS e",
"e : e RS e",
"e : e LT e",
"e : e GT e",
"e : e LE e",
"e : e GE e",
"e : e EQ e",
"e : e NE e",
"e : e AND e",
"e : e ER e",
"e : e OR e",
"e : e ANDAND e",
"e : e OROR e",
"e : e QUEST e COLON e",
"e : e CM e",
"e : term",
"term : MINUS term",
"term : NOT term",
"term : COMPL term",
"term : LP e RP",
"term : INT",
"term : IDENT",
"term : DEFMAC",
};
#endif /* YYDEBUG */
#define YYERROR goto yyerrlab
#define YYACCEPT return(0)
#define YYABORT return(1)
#define YYBACKUP( newtoken, newvalue )\
{ if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\
{yyerror( "syntax error - cannot backup" ); goto yyerrlab;}\
yychar = newtoken; yystate = *yyps; yylval = newvalue; goto yynewstate;\
}
#define YYRECOVERING() (!!yyerrflag)
#ifndef YYDEBUG
#define YYDEBUG 1
#endif
int yydebug;
#define YYFLAG (-1000)
YYSTYPE yyv[ YYMAXDEPTH ];
int yys[ YYMAXDEPTH ];
YYSTYPE *yypv;
int *yyps;
int yystate;
int yytmp;
int yynerrs;
int yyerrflag;
int yychar;
int
yyparse()
{
register YYSTYPE *yypvt;
yypv = &yyv[-1];
yyps = &yys[-1];
yystate = 0;
yytmp = 0;
yynerrs = 0;
yyerrflag = 0;
yychar = -1;
goto yystack;
{
register YYSTYPE *yy_pv;
register int *yy_ps;
register int yy_state;
register int yy_n;
yynewstate:
yy_pv = yypv;
yy_ps = yyps;
yy_state = yystate;
goto yy_newstate;
yystack:
yy_pv = yypv;
yy_ps = yyps;
yy_state = yystate;
yy_stack:
#ifdef YYDEBUG
if ( yydebug ){
register int yy_i;
printf( "State %d, token ", yy_state );
if ( yychar == 0 )
printf( "end-of-file\n" );
else if ( yychar < 0 )
printf( "-none-\n" );
else {
for(yy_i = 0; yytoks[yy_i].t_val >= 0;yy_i++){
if ( yytoks[yy_i].t_val == yychar ) break;
}
printf( "%s\n", yytoks[yy_i].t_name );
}
}
#endif /* YYDEBUG */
if ( ++yy_ps >= &yys[ YYMAXDEPTH ] ){
yyerror( "yacc stack overflow" );
YYABORT;
}
*yy_ps = yy_state;
_strass(++yy_pv, &yyval, sizeof(yyval));
yy_newstate:
if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG )
goto yydefault;
#ifdef YYDEBUG
yytmp = yychar < 0;
#endif
if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) )
yychar = 0;
#ifdef YYDEBUG
if ( yydebug && yytmp ){
register int yy_i;
printf( "Received token " );
if ( yychar == 0 )
printf( "end-of-file\n" );
else if ( yychar < 0 )
printf( "-none-\n" );
else {
for ( yy_i = 0; yytoks[yy_i].t_val >= 0;yy_i++){
if ( yytoks[yy_i].t_val == yychar ) break;
}
printf( "%s\n", yytoks[yy_i].t_name );
}
}
#endif /* YYDEBUG */
if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) )
goto yydefault;
if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar ){
yychar = -1;
_strass(&yyval, &yylval, sizeof(yyval));
yy_state = yy_n;
if ( yyerrflag > 0 )
yyerrflag--;
goto yy_stack;
}
yydefault:
if ( ( yy_n = yydef[ yy_state ] ) == -2 ){
#ifdef YYDEBUG
yytmp = yychar < 0;
#endif
if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) )
yychar = 0;
#ifdef YYDEBUG
if ( yydebug && yytmp ){
register int yy_i;
printf( "Received token " );
if ( yychar == 0 )
printf( "end-of-file\n" );
else if ( yychar < 0 )
printf( "-none-\n" );
else {
for (yy_i = 0;yytoks[yy_i].t_val >=0;yy_i++){
if ( yytoks[yy_i].t_val == yychar) break;
}
printf( "%s\n", yytoks[yy_i].t_name );
}
}
#endif /* YYDEBUG */
{
register int *yyxi = yyexca;
while ( ( *yyxi != -1 ) || ( yyxi[1] != yy_state )){
yyxi += 2;
}
while ( ( *(yyxi += 2) >= 0 ) && ( *yyxi != yychar));
if ( ( yy_n = yyxi[1] ) < 0 ) YYACCEPT;
}
}
if ( yy_n == 0 ){
switch ( yyerrflag ) {
case 0:
yyerror( "syntax error" );
goto skip_init;
yyerrlab:
yy_pv = yypv;
yy_ps = yyps;
yy_state = yystate;
yynerrs++;
skip_init:
case 1:
case 2:
yyerrflag = 3;
while ( yy_ps >= yys ){
yy_n = yypact[ *yy_ps ] + YYERRCODE;
if ( yy_n >= 0 && yy_n < YYLAST &&
yychk[yyact[yy_n]] == YYERRCODE){
yy_state = yyact[ yy_n ];
goto yy_stack;
}
#ifdef YYDEBUG
# define _POP_ "Error recovery pops state %d, uncovers state %d\n"
if ( yydebug )
printf( _POP_, *yy_ps,yy_ps[-1]);
# undef _POP_
#endif
yy_ps--;
yy_pv--;
}
YYABORT;
case 3:
#ifdef YYDEBUG
if ( yydebug ){
register int yy_i;
printf( "Error recovery discards " );
if ( yychar == 0 )
printf( "token end-of-file\n" );
else if ( yychar < 0 )
printf( "token -none-\n" );
else {
for ( yy_i = 0;yytoks[yy_i].t_val >=0;yy_i++){
if ( yytoks[yy_i].t_val == yychar) break;
}
printf( "token %s\n",yytoks[yy_i].t_name);
}
}
#endif /* YYDEBUG */
if ( yychar == 0 ) YYABORT;
yychar = -1;
goto yy_newstate;
}
}/* end if ( yy_n == 0 ) */
#ifdef YYDEBUG
if ( yydebug )
printf( "Reduce by (%d) \"%s\"\n",yy_n,yyreds[yy_n]);
#endif
yytmp = yy_n;
yypvt = yy_pv;
{
register int yy_len = yyr2[ yy_n ];
if ( !( yy_len & 01 ) ){
yy_len >>= 1;
_strass(&yyval, &(( yy_pv -= yy_len )[1]), sizeof(yyval));
yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] +
*( yy_ps -= yy_len ) + 1;
if ( yy_state >= YYLAST || yychk[yy_state = yyact[yy_state]] != -yy_n){
yy_state = yyact[ yypgo[ yy_n ] ];
}
goto yy_stack;
}
yy_len >>= 1;
_strass(&yyval, &(( yy_pv -= yy_len )[1]), sizeof(yyval));
yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] +
*( yy_ps -= yy_len ) + 1;
if(yy_state >= YYLAST || yychk[yy_state = yyact[yy_state]] != -yy_n){
yy_state = yyact[ yypgo[ yy_n ] ];
}
}
yystate = yy_state;
yyps = yy_ps;
yypv = yy_pv;
}
switch( yytmp ){
case 1:
# line 114 "parse.y"
{
/*
* If the expression can be evaluated, set the result
*/
if (yypvt[-0].lexval->an_val == INT) {
*curif |= yypvt[-0].lexval->an_ifval != 0 ?
IF_TRUE : IF_FALSE;
}
freenode(yypvt[-0].lexval);
} break;
case 2:
# line 127 "parse.y"
{
yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval * yypvt[-0].lexval->an_ifval;
binop:
yyval.lexval = yypvt[-2].lexval;
if (yypvt[-2].lexval->an_val == INT && yypvt[-0].lexval->an_val == INT) {
yyval.lexval->an_val == INT;
} else {
yyval.lexval->an_val = OTHER;
}
freenode(yypvt[-1].lexval);
freenode(yypvt[-0].lexval);
} break;
case 3:
# line 140 "parse.y"
{
if (yypvt[-0].lexval->an_ifval == 0 && yypvt[-0].lexval->an_val == INT) {
yypvt[-0].lexval->an_val = OTHER;
warnf("division by zero in #if");
} else {
yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval / yypvt[-0].lexval->an_ifval;
}
goto binop;
} break;
case 4:
# line 150 "parse.y"
{
if (yypvt[-0].lexval->an_ifval == 0 && yypvt[-0].lexval->an_val == INT) {
yypvt[-0].lexval->an_val = OTHER;
warnf("mod by zero in #if");
} else {
yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval % yypvt[-0].lexval->an_ifval;
}
goto binop;
} break;
case 5:
# line 160 "parse.y"
{yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval + yypvt[-0].lexval->an_ifval; goto binop;} break;
case 6:
# line 162 "parse.y"
{yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval - yypvt[-0].lexval->an_ifval; goto binop;} break;
case 7:
# line 164 "parse.y"
{yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval << yypvt[-0].lexval->an_ifval; goto binop;} break;
case 8:
# line 166 "parse.y"
{yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval >> yypvt[-0].lexval->an_ifval; goto binop;} break;
case 9:
# line 168 "parse.y"
{yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval < yypvt[-0].lexval->an_ifval; goto binop;} break;
case 10:
# line 170 "parse.y"
{yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval > yypvt[-0].lexval->an_ifval; goto binop;} break;
case 11:
# line 172 "parse.y"
{yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval <= yypvt[-0].lexval->an_ifval; goto binop;} break;
case 12:
# line 174 "parse.y"
{yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval >= yypvt[-0].lexval->an_ifval; goto binop;} break;
case 13:
# line 176 "parse.y"
{yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval == yypvt[-0].lexval->an_ifval; goto binop;} break;
case 14:
# line 178 "parse.y"
{yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval != yypvt[-0].lexval->an_ifval; goto binop;} break;
case 15:
# line 180 "parse.y"
{yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval & yypvt[-0].lexval->an_ifval; goto binop;} break;
case 16:
# line 182 "parse.y"
{yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval ^ yypvt[-0].lexval->an_ifval; goto binop;} break;
case 17:
# line 184 "parse.y"
{yypvt[-2].lexval->an_ifval = yypvt[-2].lexval->an_ifval | yypvt[-0].lexval->an_ifval; goto binop;} break;
case 18:
# line 186 "parse.y"
{
/*
* since this is a logical AND, its value
* is known if either subexpression is false.
*/
yyval.lexval = yypvt[-2].lexval;
if (yypvt[-2].lexval->an_val == INT && yypvt[-0].lexval->an_val == INT) {
/* both subexpressions are known */
yyval.lexval->an_ifval = yypvt[-2].lexval->an_ifval && yypvt[-0].lexval->an_ifval;
} else {
if ((yypvt[-2].lexval->an_val == INT && !yypvt[-2].lexval->an_ifval) ||
(yypvt[-0].lexval->an_val == INT && !yypvt[-0].lexval->an_ifval)) {
yyval.lexval->an_val = INT;
yyval.lexval->an_ifval = FALSE;
} else {
yyval.lexval->an_val = OTHER;
}
}
freenode(yypvt[-1].lexval); freenode(yypvt[-0].lexval);
} break;
case 19:
# line 208 "parse.y"
{
/*
* since this is a logical OR, its value
* is known if either subexpression is true.
*/
yyval.lexval = yypvt[-2].lexval;
if (yypvt[-2].lexval->an_val == INT && yypvt[-0].lexval->an_val == INT) {
/* both subexpressions are known */
yyval.lexval->an_ifval = yypvt[-2].lexval->an_ifval || yypvt[-0].lexval->an_ifval;
} else {
if ((yypvt[-2].lexval->an_val == INT && yypvt[-2].lexval->an_ifval) ||
(yypvt[-0].lexval->an_val == INT && yypvt[-0].lexval->an_ifval)) {
yyval.lexval->an_val = INT;
yyval.lexval->an_ifval = TRUE;
} else {
yyval.lexval->an_val = OTHER;
}
}
freenode(yypvt[-1].lexval); freenode(yypvt[-0].lexval);
} break;
case 20:
# line 230 "parse.y"
{
/*
* since this is an IF-ELSE, its value is known
* in some cases even if one subexpression is unknown.
*/
yyval.lexval = yypvt[-4].lexval;
if (yypvt[-4].lexval->an_val == INT) {
if (yypvt[-4].lexval->an_ifval) {
yyval.lexval->an_val = yypvt[-2].lexval->an_val;
yyval.lexval->an_ifval = yypvt[-2].lexval->an_ifval;
} else {
yyval.lexval->an_val = yypvt[-0].lexval->an_val;
yyval.lexval->an_ifval = yypvt[-0].lexval->an_ifval;
}
} else {
yyval.lexval->an_val = OTHER;
}
freenode(yypvt[-3].lexval); freenode(yypvt[-2].lexval); freenode(yypvt[-1].lexval);
freenode(yypvt[-0].lexval);
} break;
case 21:
# line 252 "parse.y"
{
/*
* since this is a comma operator, the value of
* the first expression is irrelevant.
*/
yyval.lexval = yypvt[-0].lexval;
freenode(yypvt[-2].lexval);
freenode(yypvt[-1].lexval);
} break;
case 22:
# line 263 "parse.y"
{yyval.lexval = yypvt[-0].lexval;} break;
case 23:
# line 267 "parse.y"
{
yypvt[-0].lexval->an_ifval = -(yypvt[-0].lexval->an_ifval);
unop:
yyval.lexval = yypvt[-0].lexval;
freenode(yypvt[-1].lexval);
} break;
case 24:
# line 274 "parse.y"
{yypvt[-0].lexval->an_ifval = !(yypvt[-0].lexval->an_ifval); goto unop;} break;
case 25:
# line 276 "parse.y"
{yypvt[-0].lexval->an_ifval = ~(yypvt[-0].lexval->an_ifval); goto unop;} break;
case 26:
# line 278 "parse.y"
{
yyval.lexval = yypvt[-1].lexval;
freenode(yypvt[-2].lexval); freenode(yypvt[-0].lexval);
} break;
case 27:
# line 283 "parse.y"
{yyval.lexval= yypvt[-0].lexval;} break;
case 28:
# line 285 "parse.y"
{/* an uninterpreted macro */ yyval.lexval = yypvt[-0].lexval;} break;
case 29:
# line 287 "parse.y"
{/* an uninterpreted 'defined(x)' invocation */ yyval.lexval = yypvt[-0].lexval;} break;
}
goto yystack;
}