/*#ident "@(#)cpp:common/yylex.c 1.11"*/ #include "y.tab.h" #ifdef FLEXNAMES # define NCPS 128 #else # define NCPS 8 #endif extern int ncps; /* actual number of chars. */ #ifdef CXREF extern int xline; #endif extern int yylval; #define isid(a) ((fastab+COFF)[a]&IB) #define IB 1 /* #if '\377' < 0 it would be nice if this worked properly!!!!! */ #if pdp11 | vax #define COFF 128 #else #define COFF 0 #endif yylex() { static int ifdef = 0; static char *op2[] = {"||", "&&" , ">>", "<<", ">=", "<=", "!=", "=="}; static int val2[] = {OROR, ANDAND, RS, LS, GE, LE, NE, EQ}; static char *opc = "b\bt\tn\nf\fr\r\\\\"; extern char fastab[]; extern char *outp, *inp, *newp; extern int flslvl; register char savc, *s; char *skipbl(); int val; register char **p2; struct symtab { char *name; char *value; } *sp, *lookup(); for ( ;; ) { newp = skipbl( newp ); if ( *inp == '\n' ) /* end of #if */ return( stop ); savc = *newp; *newp = '\0'; if ( *inp == '/' && inp[1] == '*' ) { /* found a comment with -C option, still toss here */ *newp = savc; outp = inp = newp; continue; } for ( p2 = op2 + 8; --p2 >= op2; ) /* check 2-char ops */ if ( strcmp( *p2, inp ) == 0 ) { val = val2[ p2 - op2 ]; goto ret; } s = "+-*/%<>&^|?:!~(),"; /* check 1-char ops */ while ( *s ) if ( *s++ == *inp ) { val= *--s; goto ret; } if ( *inp<='9' && *inp>='0' ) /* a number */ { if ( *inp == '0' ) yylval= ( inp[1] == 'x' || inp[1] == 'X' ) ? tobinary( inp + 2, 16 ) : tobinary( inp + 1, 8 ); else yylval = tobinary( inp, 10 ); val = number; } else if ( isid( *inp ) ) { if ( strcmp( inp, "defined" ) == 0 ) { ifdef = 1; ++flslvl; val = DEFINED; } else { if ( ifdef != 0 ) { register char *p; register int savech; /* make sure names <= ncps chars */ if ( ( newp - inp ) > ncps ) p = inp + ncps; else p = newp; savech = *p; *p = '\0'; sp = lookup( inp, -1 ); *p = savech; ifdef = 0; --flslvl; } else sp = lookup( inp, -1 ); #ifdef CXREF ref(inp, xline); #endif yylval = ( sp->value == 0 ) ? 0 : 1; val = number; } } else if ( *inp == '\'' ) /* character constant */ { val = number; if ( inp[1] == '\\' ) /* escaped */ { char c; if ( newp[-1] == '\'' ) newp[-1] = '\0'; s = opc; while ( *s ) if ( *s++ != inp[2] ) ++s; else { yylval = *s; goto ret; } if ( inp[2] <= '9' && inp[2] >= '0' ) yylval = c = tobinary( inp + 2, 8 ); else yylval = inp[2]; } else yylval = inp[1]; } else if ( strcmp( "\\\n", inp ) == 0 ) { *newp = savc; continue; } else { *newp = savc; pperror( "Illegal character %c in preprocessor if", *inp ); continue; } ret: /* check for non-ident after defined (note need the paren!) */ if ( ifdef && val != '(' && val != DEFINED ) { pperror( "\"defined\" modifying non-identifier \"%s\" in preprocessor if", inp ); ifdef = 0; flslvl--; } *newp = savc; outp = inp = newp; return( val ); } } tobinary( st, b ) char *st; { int n, c, t; char *s; int warned = 0; n = 0; s = st; while ( c = *s++ ) { switch( c ) { case '8': case '9': if (b <= 8 && !warned) { ppwarn("Illegal octal number %s", st); warned = 1; } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': t = c - '0'; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': t = (c - 'a') + 10; if ( b > 10 ) break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': t = (c - 'A') + 10; if ( b > 10 ) break; default: t = -1; if ( c == 'l' || c == 'L' ) if ( *s == '\0' ) break; pperror( "Illegal number %s", st ); } if ( t < 0 ) break; n = n * b + t; } return( n ); }