1*17748Sralph #ifndef lint 2*17748Sralph static char *sccsid ="@(#)scan.c 1.5 (Berkeley) 01/18/85"; 3*17748Sralph #endif lint 4*17748Sralph 59813Slinton # include "mfile1" 69813Slinton # include <a.out.h> 79813Slinton # include <stab.h> 89813Slinton # include <ctype.h> 99813Slinton /* temporarily */ 109813Slinton 119813Slinton int asm_esc = 0; /* asm escaped used in file */ 129813Slinton /* lexical actions */ 139813Slinton 149813Slinton # define A_ERR 0 /* illegal character */ 159813Slinton # define A_LET 1 /* saw a letter */ 169813Slinton # define A_DIG 2 /* saw a digit */ 179813Slinton # define A_1C 3 /* return a single character */ 189813Slinton # define A_STR 4 /* string */ 199813Slinton # define A_CC 5 /* character constant */ 209813Slinton # define A_BCD 6 /* GCOS BCD constant */ 219813Slinton # define A_SL 7 /* saw a / */ 229813Slinton # define A_DOT 8 /* saw a . */ 239813Slinton # define A_PL 9 /* + */ 249813Slinton # define A_MI 10 /* - */ 259813Slinton # define A_EQ 11 /* = */ 269813Slinton # define A_NOT 12 /* ! */ 279813Slinton # define A_LT 13 /* < */ 289813Slinton # define A_GT 14 /* > */ 299813Slinton # define A_AND 16 /* & */ 309813Slinton # define A_OR 17 /* | */ 319813Slinton # define A_WS 18 /* whitespace (not \n) */ 329813Slinton # define A_NL 19 /* \n */ 339813Slinton 349813Slinton /* character classes */ 359813Slinton 369813Slinton # define LEXLET 01 379813Slinton # define LEXDIG 02 389813Slinton # define LEXOCT 04 399813Slinton # define LEXHEX 010 409813Slinton # define LEXWS 020 419813Slinton # define LEXDOT 040 429813Slinton 439813Slinton /* reserved word actions */ 449813Slinton 459813Slinton # define AR_TY 0 /* type word */ 469813Slinton # define AR_RW 1 /* simple reserved word */ 479813Slinton # define AR_CL 2 /* storage class word */ 489813Slinton # define AR_S 3 /* struct */ 499813Slinton # define AR_U 4 /* union */ 509813Slinton # define AR_E 5 /* enum */ 519813Slinton # define AR_A 6 /* asm */ 529813Slinton 539813Slinton /* text buffer */ 549813Slinton #ifndef FLEXNAMES 559813Slinton # define LXTSZ 100 569813Slinton #else 579813Slinton #define LXTSZ BUFSIZ 589813Slinton #endif 599813Slinton char yytext[LXTSZ]; 609813Slinton char * lxgcp; 619813Slinton 629813Slinton extern int proflg; 639813Slinton extern int gdebug; 649905Ssam int oldway; /* allocate storage so lint will compile as well */ 659813Slinton #ifndef LINT 669813Slinton extern int lastloc; 679813Slinton #endif 689813Slinton 699813Slinton unsigned caloff(); 709813Slinton /* ARGSUSED */ 719813Slinton mainp1( argc, argv ) int argc; char *argv[]; { /* control multiple files */ 729813Slinton 739813Slinton register i; 749813Slinton register char *cp; 75*17748Sralph extern int idebug, bdebug, tdebug, edebug; 76*17748Sralph extern int ddebug, xdebug, gdebug, adebug; 779813Slinton extern unsigned int offsz; 789813Slinton int fdef = 0; 799813Slinton char *release = "PCC/364r1 vax uts3.0"; 809813Slinton 819813Slinton offsz = caloff(); 829813Slinton for( i=1; i<argc; ++i ){ 839813Slinton if( *(cp=argv[i]) == '-' && *++cp == 'X' ){ 849813Slinton while( *++cp ){ 859813Slinton switch( *cp ){ 869813Slinton 879813Slinton case 'r': 889813Slinton fprintf( stderr, "Release: %s\n", 899813Slinton release ); 909813Slinton break; 919813Slinton 929813Slinton case 'd': 939813Slinton ++ddebug; 949813Slinton break; 959813Slinton case 'i': 969813Slinton ++idebug; 979813Slinton break; 989813Slinton case 'b': 999813Slinton ++bdebug; 1009813Slinton break; 1019813Slinton case 't': 1029813Slinton ++tdebug; 1039813Slinton break; 1049813Slinton case 'e': 1059813Slinton ++edebug; 1069813Slinton break; 1079813Slinton case 'x': 1089813Slinton ++xdebug; 1099813Slinton break; 1109813Slinton case 'P': /* profiling */ 1119813Slinton ++proflg; 1129813Slinton break; 1139813Slinton case 'g': 1149813Slinton ++gdebug; 1159813Slinton break; 116*17748Sralph case 'a': 117*17748Sralph ++adebug; 118*17748Sralph break; 1199816Slinton case 'G': 1209816Slinton ++gdebug; 1219816Slinton oldway = 1; 1229816Slinton break; 1239813Slinton } 1249813Slinton } 1259813Slinton } 1269813Slinton else { 1279813Slinton if( *(argv[i]) != '-' ) switch( fdef++ ) { 1289813Slinton case 0: 1299813Slinton case 1: 1309813Slinton if( freopen(argv[i], fdef==1 ? "r" : "w", fdef==1 ? stdin : stdout) == NULL) { 1319813Slinton fprintf(stderr, "ccom:can't open %s\n", argv[i]); 1329813Slinton exit(1); 1339813Slinton } 1349813Slinton break; 1359813Slinton 1369813Slinton default: 1379813Slinton ; 1389813Slinton } 1399813Slinton } 1409813Slinton } 1419813Slinton 1429813Slinton # ifdef ONEPASS 1439813Slinton p2init( argc, argv ); 1449813Slinton # endif 1459813Slinton 1469813Slinton for( i=0; i<SYMTSZ; ++i ) stab[i].stype = TNULL; 1479813Slinton 14817601Sralph lineno = 1; 14917601Sralph 1509813Slinton lxinit(); 1519813Slinton tinit(); 1529813Slinton mkdope(); 1539813Slinton 1549813Slinton /* dimension table initialization */ 1559813Slinton 1569813Slinton dimtab[NULL] = 0; 1579813Slinton dimtab[CHAR] = SZCHAR; 1589813Slinton dimtab[INT] = SZINT; 1599813Slinton dimtab[FLOAT] = SZFLOAT; 1609813Slinton dimtab[DOUBLE] = SZDOUBLE; 1619813Slinton dimtab[LONG] = SZLONG; 1629813Slinton dimtab[SHORT] = SZSHORT; 1639813Slinton dimtab[UCHAR] = SZCHAR; 1649813Slinton dimtab[USHORT] = SZSHORT; 1659813Slinton dimtab[UNSIGNED] = SZINT; 1669813Slinton dimtab[ULONG] = SZLONG; 1679813Slinton /* starts past any of the above */ 1689813Slinton curdim = 16; 1699813Slinton reached = 1; 1709813Slinton 1719813Slinton yyparse(); 1729813Slinton yyaccpt(); 1739813Slinton 1749813Slinton ejobcode( nerrors ? 1 : 0 ); 1759813Slinton return(nerrors?1:0); 1769813Slinton 1779813Slinton } 1789813Slinton 1799813Slinton # ifdef ibm 1809813Slinton 1819813Slinton # define CSMASK 0377 1829813Slinton # define CSSZ 256 1839813Slinton 1849813Slinton # else 1859813Slinton 1869813Slinton # define CSMASK 0177 1879813Slinton # define CSSZ 128 1889813Slinton 1899813Slinton # endif 1909813Slinton 1919813Slinton short lxmask[CSSZ+1]; 1929813Slinton 1939813Slinton lxenter( s, m ) register char *s; register short m; { 1949813Slinton /* enter a mask into lxmask */ 1959813Slinton register c; 1969813Slinton 1979813Slinton while( c= *s++ ) lxmask[c+1] |= m; 1989813Slinton 1999813Slinton } 2009813Slinton 2019813Slinton 2029813Slinton # define lxget(c,m) (lxgcp=yytext,lxmore(c,m)) 2039813Slinton 2049813Slinton lxmore( c, m ) register c, m; { 2059813Slinton register char *cp; 2069813Slinton 2079813Slinton *(cp = lxgcp) = c; 2089813Slinton while( c=getchar(), lxmask[c+1]&m ){ 2099813Slinton if( cp < &yytext[LXTSZ-1] ){ 2109813Slinton *++cp = c; 2119813Slinton } 2129813Slinton } 2139813Slinton ungetc(c,stdin); 2149813Slinton *(lxgcp = cp+1) = '\0'; 2159813Slinton } 2169813Slinton 2179813Slinton struct lxdope { 2189813Slinton short lxch; /* the character */ 2199813Slinton short lxact; /* the action to be performed */ 2209813Slinton short lxtok; /* the token number to be returned */ 2219813Slinton short lxval; /* the value to be returned */ 2229813Slinton } lxdope[] = { 2239813Slinton 2249813Slinton '@', A_ERR, 0, 0, /* illegal characters go here... */ 2259813Slinton '_', A_LET, 0, 0, /* letters point here */ 2269813Slinton '0', A_DIG, 0, 0, /* digits point here */ 2279813Slinton ' ', A_WS, 0, 0, /* whitespace goes here */ 2289813Slinton '\n', A_NL, 0, 0, 2299813Slinton '"', A_STR, 0, 0, /* character string */ 2309813Slinton '\'', A_CC, 0, 0, /* character constant */ 2319813Slinton '`', A_BCD, 0, 0, /* GCOS BCD constant */ 2329813Slinton '(', A_1C, LP, 0, 2339813Slinton ')', A_1C, RP, 0, 2349813Slinton '{', A_1C, LC, 0, 2359813Slinton '}', A_1C, RC, 0, 2369813Slinton '[', A_1C, LB, 0, 2379813Slinton ']', A_1C, RB, 0, 2389813Slinton '*', A_1C, MUL, MUL, 2399813Slinton '?', A_1C, QUEST, 0, 2409813Slinton ':', A_1C, COLON, 0, 2419813Slinton '+', A_PL, PLUS, PLUS, 2429813Slinton '-', A_MI, MINUS, MINUS, 2439813Slinton '/', A_SL, DIVOP, DIV, 2449813Slinton '%', A_1C, DIVOP, MOD, 2459813Slinton '&', A_AND, AND, AND, 2469813Slinton '|', A_OR, OR, OR, 2479813Slinton '^', A_1C, ER, ER, 2489813Slinton '!', A_NOT, UNOP, NOT, 2499813Slinton '~', A_1C, UNOP, COMPL, 2509813Slinton ',', A_1C, CM, CM, 2519813Slinton ';', A_1C, SM, 0, 2529813Slinton '.', A_DOT, STROP, DOT, 2539813Slinton '<', A_LT, RELOP, LT, 2549813Slinton '>', A_GT, RELOP, GT, 2559813Slinton '=', A_EQ, ASSIGN, ASSIGN, 2569813Slinton -1, A_1C, 0, 0, 2579813Slinton }; 2589813Slinton 2599813Slinton struct lxdope *lxcp[CSSZ+1]; 2609813Slinton 2619813Slinton lxinit(){ 2629813Slinton register struct lxdope *p; 2639813Slinton register i; 2649813Slinton register char *cp; 2659813Slinton /* set up character classes */ 2669813Slinton 2679813Slinton lxenter( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$", LEXLET ); 2689813Slinton lxenter( "0123456789", LEXDIG ); 2699813Slinton lxenter( "0123456789abcdefABCDEF", LEXHEX ); 2709813Slinton /* \013 should become \v someday; \013 is OK for ASCII and EBCDIC */ 2719813Slinton lxenter( " \t\r\b\f\013", LEXWS ); 2729813Slinton lxenter( "01234567", LEXOCT ); 2739813Slinton lxmask['.'+1] |= LEXDOT; 2749813Slinton 2759813Slinton /* make lxcp point to appropriate lxdope entry for each character */ 2769813Slinton 2779813Slinton /* initialize error entries */ 2789813Slinton 2799813Slinton for( i= 0; i<=CSSZ; ++i ) lxcp[i] = lxdope; 2809813Slinton 2819813Slinton /* make unique entries */ 2829813Slinton 2839813Slinton for( p=lxdope; ; ++p ) { 2849813Slinton lxcp[p->lxch+1] = p; 2859813Slinton if( p->lxch < 0 ) break; 2869813Slinton } 2879813Slinton 2889813Slinton /* handle letters, digits, and whitespace */ 2899813Slinton /* by convention, first, second, and third places */ 2909813Slinton 2919813Slinton cp = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$"; 2929813Slinton while( *cp ) lxcp[*cp++ + 1] = &lxdope[1]; 2939813Slinton cp = "123456789"; 2949813Slinton while( *cp ) lxcp[*cp++ + 1] = &lxdope[2]; 2959813Slinton cp = "\t\b\r\f\013"; 2969813Slinton while( *cp ) lxcp[*cp++ + 1] = &lxdope[3]; 2979813Slinton 2989813Slinton /* first line might have title */ 2999813Slinton lxtitle(); 3009813Slinton 3019813Slinton } 3029813Slinton 3039813Slinton int lxmatch; /* character to be matched in char or string constant */ 3049813Slinton 3059813Slinton lxstr(ct){ 3069813Slinton /* match a string or character constant, up to lxmatch */ 3079813Slinton 3089813Slinton register c; 3099813Slinton register val; 3109813Slinton register i; 3119813Slinton 3129813Slinton i=0; 3139813Slinton while( (c=getchar()) != lxmatch ){ 3149813Slinton switch( c ) { 3159813Slinton 3169813Slinton case EOF: 3179813Slinton uerror( "unexpected EOF" ); 3189813Slinton break; 3199813Slinton 3209813Slinton case '\n': 3219813Slinton uerror( "newline in string or char constant" ); 3229813Slinton ++lineno; 3239813Slinton break; 3249813Slinton 3259813Slinton case '\\': 3269813Slinton switch( c = getchar() ){ 3279813Slinton 3289813Slinton case '\n': 3299813Slinton ++lineno; 3309813Slinton continue; 3319813Slinton 3329813Slinton default: 3339813Slinton val = c; 3349813Slinton goto mkcc; 3359813Slinton 3369813Slinton case 'n': 3379813Slinton val = '\n'; 3389813Slinton goto mkcc; 3399813Slinton 3409813Slinton case 'r': 3419813Slinton val = '\r'; 3429813Slinton goto mkcc; 3439813Slinton 3449813Slinton case 'b': 3459813Slinton val = '\b'; 3469813Slinton goto mkcc; 3479813Slinton 3489813Slinton case 't': 3499813Slinton val = '\t'; 3509813Slinton goto mkcc; 3519813Slinton 3529813Slinton case 'f': 3539813Slinton val = '\f'; 3549813Slinton goto mkcc; 3559813Slinton 3569813Slinton case 'v': 3579813Slinton val = '\013'; 3589813Slinton goto mkcc; 3599813Slinton 3609813Slinton case '0': 3619813Slinton case '1': 3629813Slinton case '2': 3639813Slinton case '3': 3649813Slinton case '4': 3659813Slinton case '5': 3669813Slinton case '6': 3679813Slinton case '7': 3689813Slinton val = c-'0'; 3699813Slinton c=getchar(); /* try for 2 */ 3709813Slinton if( lxmask[c+1] & LEXOCT ){ 3719813Slinton val = (val<<3) | (c-'0'); 3729813Slinton c = getchar(); /* try for 3 */ 3739813Slinton if( lxmask[c+1] & LEXOCT ){ 3749813Slinton val = (val<<3) | (c-'0'); 3759813Slinton } 3769813Slinton else ungetc( c ,stdin); 3779813Slinton } 3789813Slinton else ungetc( c ,stdin); 3799813Slinton 3809813Slinton goto mkcc1; 3819813Slinton 3829813Slinton } 3839813Slinton default: 3849813Slinton val =c; 3859813Slinton mkcc: 3869813Slinton val = CCTRANS(val); 3879813Slinton mkcc1: 3889813Slinton if( lxmatch == '\'' ){ 3899813Slinton val = CHARCAST(val); /* it is, after all, a "character" constant */ 3909813Slinton makecc( val, i ); 3919813Slinton } 3929813Slinton else { /* stash the byte into the string */ 3939813Slinton if( strflg ) { 3949813Slinton if( ct==0 || i<ct ) putbyte( val ); 3959813Slinton else if( i == ct ) werror( "non-null byte ignored in string initializer" ); 3969813Slinton } 3979813Slinton else bycode( val, i ); 3989813Slinton } 3999813Slinton ++i; 4009813Slinton continue; 4019813Slinton } 4029813Slinton break; 4039813Slinton } 4049813Slinton /* end of string or char constant */ 4059813Slinton 4069813Slinton if( lxmatch == '"' ){ 4079813Slinton if( strflg ){ /* end the string */ 4089813Slinton if( ct==0 || i<ct ) putbyte( 0 ); /* the null at the end */ 4099813Slinton } 4109813Slinton else { /* the initializer gets a null byte */ 4119813Slinton bycode( 0, i++ ); 4129813Slinton bycode( -1, i ); 4139813Slinton dimtab[curdim] = i; /* in case of later sizeof ... */ 4149813Slinton } 4159813Slinton } 4169813Slinton else { /* end the character constant */ 4179813Slinton if( i == 0 ) uerror( "empty character constant" ); 4189813Slinton if( i>(SZINT/SZCHAR) || ( (pflag||hflag)&&i>1) ) 4199813Slinton uerror( "too many characters in character constant" ); 4209813Slinton } 4219813Slinton } 4229813Slinton 4239813Slinton lxcom(){ 4249813Slinton register c; 4259813Slinton /* saw a /*: process a comment */ 4269813Slinton 4279813Slinton for(;;){ 4289813Slinton 4299813Slinton switch( c = getchar() ){ 4309813Slinton 4319813Slinton case EOF: 4329813Slinton uerror( "unexpected EOF" ); 4339813Slinton return; 4349813Slinton 4359813Slinton case '\n': 4369813Slinton ++lineno; 4379813Slinton 4389813Slinton default: 4399813Slinton continue; 4409813Slinton 4419813Slinton case '*': 4429813Slinton if( (c = getchar()) == '/' ) return; 4439813Slinton else ungetc( c ,stdin); 4449813Slinton continue; 4459813Slinton 4469813Slinton # ifdef LINT 4479813Slinton case 'V': 4489813Slinton lxget( c, LEXLET|LEXDIG ); 4499813Slinton { 4509813Slinton extern int vaflag; 4519813Slinton int i; 4529813Slinton i = yytext[7]?yytext[7]-'0':0; 4539813Slinton yytext[7] = '\0'; 4549813Slinton if( strcmp( yytext, "VARARGS" ) ) continue; 4559813Slinton vaflag = i; 4569813Slinton continue; 4579813Slinton } 4589813Slinton case 'L': 4599813Slinton lxget( c, LEXLET ); 4609813Slinton if( strcmp( yytext, "LINTLIBRARY" ) ) continue; 4619813Slinton { 4629813Slinton extern int libflag; 4639813Slinton libflag = 1; 4649813Slinton } 4659813Slinton continue; 4669813Slinton 4679813Slinton case 'A': 4689813Slinton lxget( c, LEXLET ); 4699813Slinton if( strcmp( yytext, "ARGSUSED" ) ) continue; 4709813Slinton { 4719813Slinton extern int argflag, vflag; 4729813Slinton argflag = 1; 4739813Slinton vflag = 0; 4749813Slinton } 4759813Slinton continue; 4769813Slinton 4779813Slinton case 'N': 4789813Slinton lxget( c, LEXLET ); 4799813Slinton if( strcmp( yytext, "NOTREACHED" ) ) continue; 4809813Slinton reached = 0; 4819813Slinton continue; 4829813Slinton # endif 4839813Slinton } 4849813Slinton } 4859813Slinton } 4869813Slinton 4879813Slinton yylex(){ 4889813Slinton for(;;){ 4899813Slinton 4909813Slinton register lxchar; 4919813Slinton register struct lxdope *p; 4929813Slinton register struct symtab *sp; 4939813Slinton int id; 4949813Slinton 4959813Slinton switch( (p=lxcp[(lxchar=getchar())+1])->lxact ){ 4969813Slinton 4979813Slinton onechar: 4989813Slinton ungetc( lxchar ,stdin); 4999813Slinton 5009813Slinton case A_1C: 5019813Slinton /* eat up a single character, and return an opcode */ 5029813Slinton 5039813Slinton yylval.intval = p->lxval; 5049813Slinton return( p->lxtok ); 5059813Slinton 5069813Slinton case A_ERR: 5079813Slinton uerror( "illegal character: %03o (octal)", lxchar ); 5089813Slinton break; 5099813Slinton 5109813Slinton case A_LET: 5119813Slinton /* collect an identifier, check for reserved word, and return */ 5129813Slinton lxget( lxchar, LEXLET|LEXDIG ); 5139813Slinton if( (lxchar=lxres()) > 0 ) return( lxchar ); /* reserved word */ 5149813Slinton if( lxchar== 0 ) continue; 5159813Slinton #ifdef FLEXNAMES 5169813Slinton id = lookup( hash(yytext), 5179813Slinton #else 5189813Slinton id = lookup( yytext, 5199813Slinton #endif 5209813Slinton /* tag name for struct/union/enum */ 5219813Slinton (stwart&TAGNAME)? STAG: 5229813Slinton /* member name for struct/union */ 5239813Slinton (stwart&(INSTRUCT|INUNION|FUNNYNAME))?SMOS:0 ); 5249813Slinton sp = &stab[id]; 5259813Slinton if( sp->sclass == TYPEDEF && !stwart ){ 5269813Slinton stwart = instruct; 5279813Slinton yylval.nodep = mkty( sp->stype, sp->dimoff, sp->sizoff ); 5289813Slinton return( TYPE ); 5299813Slinton } 5309813Slinton stwart = (stwart&SEENAME) ? instruct : 0; 5319813Slinton yylval.intval = id; 5329813Slinton return( NAME ); 5339813Slinton 5349813Slinton case A_DIG: 5359813Slinton /* collect a digit string, then look at last one... */ 5369813Slinton lastcon = 0; 5379813Slinton lxget( lxchar, LEXDIG ); 5389813Slinton switch( lxchar=getchar() ){ 5399813Slinton 5409813Slinton case 'x': 5419813Slinton case 'X': 5429813Slinton if( yytext[0] != '0' && !yytext[1] ) uerror( "illegal hex constant" ); 5439813Slinton lxmore( lxchar, LEXHEX ); 5449813Slinton /* convert the value */ 5459813Slinton { 5469813Slinton register char *cp; 5479813Slinton for( cp = yytext+2; *cp; ++cp ){ 5489813Slinton /* this code won't work for all wild character sets, 5499813Slinton but seems ok for ascii and ebcdic */ 5509813Slinton lastcon <<= 4; 5519813Slinton if( isdigit( *cp ) ) lastcon += *cp-'0'; 5529813Slinton else if( isupper( *cp ) ) lastcon += *cp - 'A'+ 10; 5539813Slinton else lastcon += *cp - 'a'+ 10; 5549813Slinton } 5559813Slinton } 5569813Slinton 5579813Slinton hexlong: 5589813Slinton /* criterion for longness for hex and octal constants is that it 5599813Slinton fit within 0177777 */ 5609813Slinton if( lastcon & ~0177777L ) yylval.intval = 1; 5619813Slinton else yylval.intval = 0; 5629813Slinton 5639813Slinton goto islong; 5649813Slinton 5659813Slinton case '.': 5669813Slinton lxmore( lxchar, LEXDIG ); 5679813Slinton 5689813Slinton getfp: 5699813Slinton if( (lxchar=getchar()) == 'e' || lxchar == 'E' ){ /* exponent */ 5709813Slinton 5719813Slinton case 'e': 5729813Slinton case 'E': 5739813Slinton if( (lxchar=getchar()) == '+' || lxchar == '-' ){ 5749813Slinton *lxgcp++ = 'e'; 5759813Slinton } 5769813Slinton else { 5779813Slinton ungetc(lxchar,stdin); 5789813Slinton lxchar = 'e'; 5799813Slinton } 5809813Slinton lxmore( lxchar, LEXDIG ); 5819813Slinton /* now have the whole thing... */ 5829813Slinton } 5839813Slinton else { /* no exponent */ 5849813Slinton ungetc( lxchar ,stdin); 5859813Slinton } 5869813Slinton return( isitfloat( yytext ) ); 5879813Slinton 5889813Slinton default: 5899813Slinton ungetc( lxchar ,stdin); 5909813Slinton if( yytext[0] == '0' ){ 5919813Slinton /* convert in octal */ 5929813Slinton register char *cp; 5939813Slinton for( cp = yytext+1; *cp; ++cp ){ 5949813Slinton lastcon <<= 3; 5959813Slinton lastcon += *cp - '0'; 5969813Slinton } 5979813Slinton goto hexlong; 5989813Slinton } 5999813Slinton else { 6009813Slinton /* convert in decimal */ 6019813Slinton register char *cp; 6029813Slinton for( cp = yytext; *cp; ++cp ){ 6039813Slinton lastcon = lastcon * 10 + *cp - '0'; 6049813Slinton } 6059813Slinton } 6069813Slinton 6079813Slinton /* decide if it is long or not (decimal case) */ 6089813Slinton 6099813Slinton /* if it is positive and fits in 15 bits, or negative and 6109813Slinton and fits in 15 bits plus an extended sign, it is int; otherwise long */ 6119813Slinton /* if there is an l or L following, all bets are off... */ 6129813Slinton 6139813Slinton { CONSZ v; 6149813Slinton v = lastcon & ~077777L; 6159813Slinton if( v == 0 || v == ~077777L ) yylval.intval = 0; 6169813Slinton else yylval.intval = 1; 6179813Slinton } 6189813Slinton 6199813Slinton islong: 6209813Slinton /* finally, look for trailing L or l */ 6219813Slinton if( (lxchar = getchar()) == 'L' || lxchar == 'l' ) yylval.intval = 1; 6229813Slinton else ungetc( lxchar ,stdin); 6239813Slinton return( ICON ); 6249813Slinton } 6259813Slinton 6269813Slinton case A_DOT: 6279813Slinton /* look for a dot: if followed by a digit, floating point */ 6289813Slinton lxchar = getchar(); 6299813Slinton if( lxmask[lxchar+1] & LEXDIG ){ 6309813Slinton ungetc(lxchar,stdin); 6319813Slinton lxget( '.', LEXDIG ); 6329813Slinton goto getfp; 6339813Slinton } 6349813Slinton stwart = FUNNYNAME; 6359813Slinton goto onechar; 6369813Slinton 6379813Slinton case A_STR: 6389813Slinton /* string constant */ 6399813Slinton lxmatch = '"'; 6409813Slinton return( STRING ); 6419813Slinton 6429813Slinton case A_CC: 6439813Slinton /* character constant */ 6449813Slinton lxmatch = '\''; 6459813Slinton lastcon = 0; 6469813Slinton lxstr(0); 6479813Slinton yylval.intval = 0; 6489813Slinton return( ICON ); 6499813Slinton 6509813Slinton case A_BCD: 6519813Slinton { 6529813Slinton register i; 6539813Slinton int j; 6549813Slinton for( i=0; i<LXTSZ; ++i ){ 6559813Slinton if( ( j = getchar() ) == '`' ) break; 6569813Slinton if( j == '\n' ){ 6579813Slinton uerror( "newline in BCD constant" ); 6589813Slinton break; 6599813Slinton } 6609813Slinton yytext[i] = j; 6619813Slinton } 6629813Slinton yytext[i] = '\0'; 6639813Slinton if( i>6 ) uerror( "BCD constant exceeds 6 characters" ); 6649813Slinton # ifdef gcos 6659813Slinton else strtob( yytext, &lastcon, i ); 6669813Slinton lastcon >>= 6*(6-i); 6679813Slinton # else 6689813Slinton uerror( "gcos BCD constant illegal" ); 6699813Slinton # endif 6709813Slinton yylval.intval = 0; /* not long */ 6719813Slinton return( ICON ); 6729813Slinton } 6739813Slinton 6749813Slinton case A_SL: 6759813Slinton /* / */ 6769813Slinton if( (lxchar=getchar()) != '*' ) goto onechar; 6779813Slinton lxcom(); 6789813Slinton case A_WS: 6799813Slinton continue; 6809813Slinton 6819813Slinton case A_NL: 6829813Slinton ++lineno; 6839813Slinton lxtitle(); 6849813Slinton continue; 6859813Slinton 6869813Slinton case A_NOT: 6879813Slinton /* ! */ 6889813Slinton if( (lxchar=getchar()) != '=' ) goto onechar; 6899813Slinton yylval.intval = NE; 6909813Slinton return( EQUOP ); 6919813Slinton 6929813Slinton case A_MI: 6939813Slinton /* - */ 6949813Slinton if( (lxchar=getchar()) == '-' ){ 6959813Slinton yylval.intval = DECR; 6969813Slinton return( INCOP ); 6979813Slinton } 6989813Slinton if( lxchar != '>' ) goto onechar; 6999813Slinton stwart = FUNNYNAME; 7009813Slinton yylval.intval=STREF; 7019813Slinton return( STROP ); 7029813Slinton 7039813Slinton case A_PL: 7049813Slinton /* + */ 7059813Slinton if( (lxchar=getchar()) != '+' ) goto onechar; 7069813Slinton yylval.intval = INCR; 7079813Slinton return( INCOP ); 7089813Slinton 7099813Slinton case A_AND: 7109813Slinton /* & */ 7119813Slinton if( (lxchar=getchar()) != '&' ) goto onechar; 7129813Slinton return( yylval.intval = ANDAND ); 7139813Slinton 7149813Slinton case A_OR: 7159813Slinton /* | */ 7169813Slinton if( (lxchar=getchar()) != '|' ) goto onechar; 7179813Slinton return( yylval.intval = OROR ); 7189813Slinton 7199813Slinton case A_LT: 7209813Slinton /* < */ 7219813Slinton if( (lxchar=getchar()) == '<' ){ 7229813Slinton yylval.intval = LS; 7239813Slinton return( SHIFTOP ); 7249813Slinton } 7259813Slinton if( lxchar != '=' ) goto onechar; 7269813Slinton yylval.intval = LE; 7279813Slinton return( RELOP ); 7289813Slinton 7299813Slinton case A_GT: 7309813Slinton /* > */ 7319813Slinton if( (lxchar=getchar()) == '>' ){ 7329813Slinton yylval.intval = RS; 7339813Slinton return(SHIFTOP ); 7349813Slinton } 7359813Slinton if( lxchar != '=' ) goto onechar; 7369813Slinton yylval.intval = GE; 7379813Slinton return( RELOP ); 7389813Slinton 7399813Slinton case A_EQ: 7409813Slinton /* = */ 7419813Slinton switch( lxchar = getchar() ){ 7429813Slinton 7439813Slinton case '=': 7449813Slinton yylval.intval = EQ; 7459813Slinton return( EQUOP ); 7469813Slinton 7479813Slinton case '+': 7489813Slinton yylval.intval = ASG PLUS; 7499813Slinton break; 7509813Slinton 7519813Slinton case '-': 7529813Slinton yylval.intval = ASG MINUS; 7539813Slinton 7549813Slinton warn: 7559813Slinton if( lxmask[ (lxchar=getchar())+1] & (LEXLET|LEXDIG|LEXDOT) ){ 7569813Slinton werror( "ambiguous assignment: assignment op taken" ); 7579813Slinton } 7589813Slinton ungetc( lxchar ,stdin); 7599813Slinton break; 7609813Slinton 7619813Slinton case '*': 7629813Slinton yylval.intval = ASG MUL; 7639813Slinton goto warn; 7649813Slinton 7659813Slinton case '/': 7669813Slinton yylval.intval = ASG DIV; 7679813Slinton break; 7689813Slinton 7699813Slinton case '%': 7709813Slinton yylval.intval = ASG MOD; 7719813Slinton break; 7729813Slinton 7739813Slinton case '&': 7749813Slinton yylval.intval = ASG AND; 7759813Slinton break; 7769813Slinton 7779813Slinton case '|': 7789813Slinton yylval.intval = ASG OR; 7799813Slinton break; 7809813Slinton 7819813Slinton case '^': 7829813Slinton yylval.intval = ASG ER; 7839813Slinton break; 7849813Slinton 7859813Slinton case '<': 7869813Slinton if( (lxchar=getchar()) != '<' ){ 7879813Slinton uerror( "=<%c illegal", lxchar ); 7889813Slinton } 7899813Slinton yylval.intval = ASG LS; 7909813Slinton break; 7919813Slinton 7929813Slinton case '>': 7939813Slinton if( (lxchar=getchar()) != '>' ){ 7949813Slinton uerror( "=>%c illegal", lxchar ); 7959813Slinton } 7969813Slinton yylval.intval = ASG RS; 7979813Slinton break; 7989813Slinton 7999813Slinton default: 8009813Slinton goto onechar; 8019813Slinton 8029813Slinton } 8039813Slinton 8049813Slinton return( ASOP ); 8059813Slinton 8069813Slinton default: 8079813Slinton cerror( "yylex error, character %03o (octal)", lxchar ); 8089813Slinton 8099813Slinton } 8109813Slinton 8119813Slinton /* ordinarily, repeat here... */ 8129813Slinton cerror( "out of switch in yylex" ); 8139813Slinton 8149813Slinton } 8159813Slinton 8169813Slinton } 8179813Slinton 8189813Slinton struct lxrdope { 8199813Slinton /* dope for reserved, in alphabetical order */ 8209813Slinton 8219813Slinton char *lxrch; /* name of reserved word */ 8229813Slinton short lxract; /* reserved word action */ 8239813Slinton short lxrval; /* value to be returned */ 8249813Slinton } lxrdope[] = { 8259813Slinton 8269813Slinton "asm", AR_A, 0, 8279813Slinton "auto", AR_CL, AUTO, 8289813Slinton "break", AR_RW, BREAK, 8299813Slinton "char", AR_TY, CHAR, 8309813Slinton "case", AR_RW, CASE, 8319813Slinton "continue", AR_RW, CONTINUE, 8329813Slinton "double", AR_TY, DOUBLE, 8339813Slinton "default", AR_RW, DEFAULT, 8349813Slinton "do", AR_RW, DO, 8359813Slinton "extern", AR_CL, EXTERN, 8369813Slinton "else", AR_RW, ELSE, 8379813Slinton "enum", AR_E, ENUM, 8389813Slinton "for", AR_RW, FOR, 8399813Slinton "float", AR_TY, FLOAT, 8409813Slinton "fortran", AR_CL, FORTRAN, 8419813Slinton "goto", AR_RW, GOTO, 8429813Slinton "if", AR_RW, IF, 8439813Slinton "int", AR_TY, INT, 8449813Slinton "long", AR_TY, LONG, 8459813Slinton "return", AR_RW, RETURN, 8469813Slinton "register", AR_CL, REGISTER, 8479813Slinton "switch", AR_RW, SWITCH, 8489813Slinton "struct", AR_S, 0, 8499813Slinton "sizeof", AR_RW, SIZEOF, 8509813Slinton "short", AR_TY, SHORT, 8519813Slinton "static", AR_CL, STATIC, 8529813Slinton "typedef", AR_CL, TYPEDEF, 8539813Slinton "unsigned", AR_TY, UNSIGNED, 8549813Slinton "union", AR_U, 0, 8559813Slinton "void", AR_TY, UNDEF, /* tymerge adds FTN */ 8569813Slinton "while", AR_RW, WHILE, 8579813Slinton "", 0, 0, /* to stop the search */ 8589813Slinton }; 8599813Slinton 8609813Slinton lxres() { 8619813Slinton /* check to see of yytext is reserved; if so, 8629813Slinton /* do the appropriate action and return */ 8639813Slinton /* otherwise, return -1 */ 8649813Slinton 8659813Slinton register c, ch; 8669813Slinton register struct lxrdope *p; 8679813Slinton 8689813Slinton ch = yytext[0]; 8699813Slinton 8709813Slinton if( !islower(ch) ) return( -1 ); 8719813Slinton 8729813Slinton switch( ch ){ 8739813Slinton 8749813Slinton case 'a': 8759813Slinton c=0; break; 8769813Slinton case 'b': 8779813Slinton c=2; break; 8789813Slinton case 'c': 8799813Slinton c=3; break; 8809813Slinton case 'd': 8819813Slinton c=6; break; 8829813Slinton case 'e': 8839813Slinton c=9; break; 8849813Slinton case 'f': 8859813Slinton c=12; break; 8869813Slinton case 'g': 8879813Slinton c=15; break; 8889813Slinton case 'i': 8899813Slinton c=16; break; 8909813Slinton case 'l': 8919813Slinton c=18; break; 8929813Slinton case 'r': 8939813Slinton c=19; break; 8949813Slinton case 's': 8959813Slinton c=21; break; 8969813Slinton case 't': 8979813Slinton c=26; break; 8989813Slinton case 'u': 8999813Slinton c=27; break; 9009813Slinton case 'v': 9019813Slinton c=29; break; 9029813Slinton case 'w': 9039813Slinton c=30; break; 9049813Slinton 9059813Slinton default: 9069813Slinton return( -1 ); 9079813Slinton } 9089813Slinton 9099813Slinton for( p= lxrdope+c; p->lxrch[0] == ch; ++p ){ 9109813Slinton if( !strcmp( yytext, p->lxrch ) ){ /* match */ 9119813Slinton switch( p->lxract ){ 9129813Slinton 9139813Slinton case AR_TY: 9149813Slinton /* type word */ 9159813Slinton stwart = instruct; 9169813Slinton yylval.nodep = mkty( (TWORD)p->lxrval, 0, p->lxrval ); 9179813Slinton return( TYPE ); 9189813Slinton 9199813Slinton case AR_RW: 9209813Slinton /* ordinary reserved word */ 9219813Slinton return( yylval.intval = p->lxrval ); 9229813Slinton 9239813Slinton case AR_CL: 9249813Slinton /* class word */ 9259813Slinton yylval.intval = p->lxrval; 9269813Slinton return( CLASS ); 9279813Slinton 9289813Slinton case AR_S: 9299813Slinton /* struct */ 9309813Slinton stwart = INSTRUCT|SEENAME|TAGNAME; 9319813Slinton yylval.intval = INSTRUCT; 9329813Slinton return( STRUCT ); 9339813Slinton 9349813Slinton case AR_U: 9359813Slinton /* union */ 9369813Slinton stwart = INUNION|SEENAME|TAGNAME; 9379813Slinton yylval.intval = INUNION; 9389813Slinton return( STRUCT ); 9399813Slinton 9409813Slinton case AR_E: 9419813Slinton /* enums */ 9429813Slinton stwart = SEENAME|TAGNAME; 9439813Slinton return( yylval.intval = ENUM ); 9449813Slinton 9459813Slinton case AR_A: 9469813Slinton /* asm */ 9479813Slinton asm_esc = 1; /* warn the world! */ 9489813Slinton lxget( ' ', LEXWS ); 9499813Slinton if( getchar() != '(' ) goto badasm; 9509813Slinton lxget( ' ', LEXWS ); 9519813Slinton if( getchar() != '"' ) goto badasm; 9529813Slinton # ifndef ONEPASS 9539813Slinton # ifndef LINT 9549813Slinton putchar(')'); 9559813Slinton # endif 9569813Slinton # endif 9579813Slinton while( (c=getchar()) != '"' ){ 9589813Slinton if( c=='\n' || c==EOF ) goto badasm; 9599813Slinton # ifndef LINT 9609813Slinton putchar(c); 9619813Slinton # endif 9629813Slinton } 9639813Slinton lxget( ' ', LEXWS ); 9649813Slinton if( getchar() != ')' ) goto badasm; 9659813Slinton # ifndef LINT 9669813Slinton putchar('\n'); 9679813Slinton # endif 9689813Slinton return( 0 ); 9699813Slinton 9709813Slinton badasm: 9719813Slinton uerror( "bad asm construction" ); 9729813Slinton return( 0 ); 9739813Slinton 9749813Slinton default: 9759813Slinton cerror( "bad AR_?? action" ); 9769813Slinton } 9779813Slinton } 9789813Slinton } 9799813Slinton return( -1 ); 9809813Slinton } 9819813Slinton 9829813Slinton extern int labelno; 9839813Slinton 9849813Slinton lxtitle(){ 9859813Slinton /* called after a newline; set linenumber and file name */ 9869813Slinton 9879813Slinton register c, val; 9889813Slinton register char *cp, *cq; 9899813Slinton 9909813Slinton for(;;){ /* might be several such lines in a row */ 9919813Slinton if( (c=getchar()) != '#' ){ 9929813Slinton if( c != EOF ) ungetc(c,stdin); 9939813Slinton #ifndef LINT 9949813Slinton if ( lastloc != PROG) return; 9959813Slinton cp = ftitle; 9969813Slinton cq = ititle; 9979813Slinton while ( *cp ) if (*cp++ != *cq++) return; 9989813Slinton if ( *cq ) return; 9999813Slinton psline(); 10009813Slinton #endif 10019813Slinton return; 10029813Slinton } 10039813Slinton 10049813Slinton lxget( ' ', LEXWS ); 10059813Slinton val = 0; 10069813Slinton for( c=getchar(); isdigit(c); c=getchar() ){ 10079813Slinton val = val*10+ c - '0'; 10089813Slinton } 1009*17748Sralph if( c == EOF ) 1010*17748Sralph continue; 10119813Slinton ungetc( c, stdin ); 10129813Slinton lineno = val; 10139813Slinton lxget( ' ', LEXWS ); 1014*17748Sralph if( (c=getchar()) != '\n' && c != EOF ){ 1015*17748Sralph for( cp=ftitle; c!=EOF && c!='\n'; c=getchar(),++cp ){ 10169813Slinton *cp = c; 10179813Slinton } 10189813Slinton *cp = '\0'; 10199813Slinton #ifndef LINT 10209813Slinton if (ititle[0] == '\0') { 10219813Slinton cp = ftitle; 10229813Slinton cq = ititle; 10239813Slinton while ( *cp ) 10249813Slinton *cq++ = *cp++; 10259813Slinton *cq = '\0'; 10269813Slinton *--cq = '\0'; 10279813Slinton #ifndef FLEXNAMES 10289813Slinton for ( cp = ititle+1; *(cp-1); cp += 8 ) { 10299813Slinton pstab(cp, N_SO); 10309813Slinton if (gdebug) printf("0,0,LL%d\n", labelno); 10319813Slinton } 10329813Slinton #else 10339813Slinton pstab(ititle+1, N_SO); 10349813Slinton if (gdebug) printf("0,0,LL%d\n", labelno); 10359813Slinton #endif 10369813Slinton 10379813Slinton *cq = '"'; 10389813Slinton printf("LL%d:\n", labelno++); 10399813Slinton } 10409813Slinton #endif 10419813Slinton } 10429813Slinton } 10439813Slinton } 10449813Slinton 10459813Slinton #ifdef FLEXNAMES 10469813Slinton #define NSAVETAB 4096 10479813Slinton char *savetab; 10489813Slinton int saveleft; 10499813Slinton 10509813Slinton char * 10519813Slinton savestr(cp) 10529813Slinton register char *cp; 10539813Slinton { 10549813Slinton register int len; 10559813Slinton 10569813Slinton len = strlen(cp) + 1; 10579813Slinton if (len > saveleft) { 10589813Slinton saveleft = NSAVETAB; 10599813Slinton if (len > saveleft) 10609813Slinton saveleft = len; 10619813Slinton savetab = (char *)malloc(saveleft); 10629813Slinton if (savetab == 0) 10639813Slinton cerror("Ran out of memory (savestr)"); 10649813Slinton } 10659813Slinton strncpy(savetab, cp, len); 10669813Slinton cp = savetab; 10679813Slinton savetab += len; 10689813Slinton saveleft -= len; 10699813Slinton return (cp); 10709813Slinton } 10719813Slinton 10729813Slinton /* 10739813Slinton * The definition for the segmented hash tables. 10749813Slinton */ 10759813Slinton #define MAXHASH 20 10769813Slinton #define HASHINC 1013 10779813Slinton struct ht { 10789813Slinton char **ht_low; 10799813Slinton char **ht_high; 10809813Slinton int ht_used; 10819813Slinton } htab[MAXHASH]; 10829813Slinton 10839813Slinton char * 10849813Slinton hash(s) 10859813Slinton char *s; 10869813Slinton { 10879813Slinton register char **h; 10889813Slinton register i; 10899813Slinton register char *cp; 10909813Slinton struct ht *htp; 10919813Slinton int sh; 10929813Slinton 10939813Slinton /* 10949813Slinton * The hash function is a modular hash of 10959813Slinton * the sum of the characters with the sum 10969813Slinton * doubled before each successive character 10979813Slinton * is added. 10989813Slinton */ 10999813Slinton cp = s; 11009813Slinton i = 0; 11019813Slinton while (*cp) 11029813Slinton i = i*2 + *cp++; 11039813Slinton sh = (i&077777) % HASHINC; 11049813Slinton cp = s; 11059813Slinton /* 11069813Slinton * There are as many as MAXHASH active 11079813Slinton * hash tables at any given point in time. 11089813Slinton * The search starts with the first table 11099813Slinton * and continues through the active tables 11109813Slinton * as necessary. 11119813Slinton */ 11129813Slinton for (htp = htab; htp < &htab[MAXHASH]; htp++) { 11139813Slinton if (htp->ht_low == 0) { 11149813Slinton register char **hp = 11159813Slinton (char **) calloc(sizeof (char **), HASHINC); 11169813Slinton if (hp == 0) 11179813Slinton cerror("ran out of memory (hash)"); 11189813Slinton htp->ht_low = hp; 11199813Slinton htp->ht_high = htp->ht_low + HASHINC; 11209813Slinton } 11219813Slinton h = htp->ht_low + sh; 11229813Slinton /* 11239813Slinton * quadratic rehash increment 11249813Slinton * starts at 1 and incremented 11259813Slinton * by two each rehash. 11269813Slinton */ 11279813Slinton i = 1; 11289813Slinton do { 11299813Slinton if (*h == 0) { 11309813Slinton if (htp->ht_used > (HASHINC * 3)/4) 11319813Slinton break; 11329813Slinton htp->ht_used++; 11339813Slinton *h = savestr(cp); 11349813Slinton return (*h); 11359813Slinton } 11369813Slinton if (**h == *cp && strcmp(*h, cp) == 0) 11379813Slinton return (*h); 11389813Slinton h += i; 11399813Slinton i += 2; 11409813Slinton if (h >= htp->ht_high) 11419813Slinton h -= HASHINC; 11429813Slinton } while (i < HASHINC); 11439813Slinton } 11449813Slinton cerror("ran out of hash tables"); 11459813Slinton } 11469813Slinton #endif 1147