1: #if !defined(lint) && defined(DOSCCS) 2: static char *sccsid ="@(#)scan.c 2.1.1 (2.11BSD GTE) 1/17/95"; 3: #endif lint 4: 5: # include "pass1.h" 6: # include <a.out.h> 7: # include <stab.h> 8: # include <ctype.h> 9: # include <signal.h> 10: 11: /* temporarily */ 12: 13: int asm_esc = 0; /* asm escaped used in file */ 14: /* lexical actions */ 15: 16: # define A_ERR 0 /* illegal character */ 17: # define A_LET 1 /* saw a letter */ 18: # define A_DIG 2 /* saw a digit */ 19: # define A_1C 3 /* return a single character */ 20: # define A_STR 4 /* string */ 21: # define A_CC 5 /* character constant */ 22: # define A_BCD 6 /* GCOS BCD constant */ 23: # define A_SL 7 /* saw a / */ 24: # define A_DOT 8 /* saw a . */ 25: # define A_PL 9 /* + */ 26: # define A_MI 10 /* - */ 27: # define A_EQ 11 /* = */ 28: # define A_NOT 12 /* ! */ 29: # define A_LT 13 /* < */ 30: # define A_GT 14 /* > */ 31: # define A_AND 16 /* & */ 32: # define A_OR 17 /* | */ 33: # define A_WS 18 /* whitespace (not \n) */ 34: # define A_NL 19 /* \n */ 35: 36: /* character classes */ 37: 38: # define LEXLET 01 39: # define LEXDIG 02 40: # define LEXOCT 04 41: # define LEXHEX 010 42: # define LEXWS 020 43: # define LEXDOT 040 44: 45: /* reserved word actions */ 46: 47: # define AR_TY 0 /* type word */ 48: # define AR_RW 1 /* simple reserved word */ 49: # define AR_CL 2 /* storage class word */ 50: # define AR_S 3 /* struct */ 51: # define AR_U 4 /* union */ 52: # define AR_E 5 /* enum */ 53: # define AR_A 6 /* asm */ 54: 55: /* text buffer */ 56: #ifndef FLEXNAMES 57: # define LXTSZ 100 58: #else 59: #define LXTSZ 512 /* was BUFSIZ */ 60: #endif 61: char yytext[LXTSZ]; 62: char * lxgcp; 63: 64: extern int proflg; 65: extern int gdebug; 66: extern int fpe(); 67: struct sigvec fpe_sigvec; 68: int oldway; /* allocate storage so lint will compile as well */ 69: #ifndef LINT 70: extern int lastloc; 71: #endif 72: 73: OFFSZ caloff(); 74: /* ARGSUSED */ 75: mainp1( argc, argv ) int argc; char *argv[]; { /* control multiple files */ 76: 77: register i; 78: register char *cp; 79: extern int idebug, bdebug, tdebug, edebug; 80: extern int ddebug, xdebug, gdebug, adebug; 81: extern OFFSZ offsz; 82: int fdef = 0; 83: char *release = "PCC/3.0 (2.11BSD) 7/23/91"; 84: 85: offsz = caloff(); 86: for( i=1; i<argc; ++i ){ 87: if( *(cp=argv[i]) == '-' && *++cp == 'X' ){ 88: while( *++cp ){ 89: switch( *cp ){ 90: 91: case 'r': 92: fprintf( stderr, "Release: %s\n", 93: release ); 94: break; 95: 96: case 'd': 97: ++ddebug; 98: break; 99: case 'i': 100: ++idebug; 101: break; 102: case 'b': 103: ++bdebug; 104: break; 105: case 't': 106: ++tdebug; 107: break; 108: case 'e': 109: ++edebug; 110: break; 111: case 'x': 112: ++xdebug; 113: break; 114: case 'P': /* profiling */ 115: ++proflg; 116: break; 117: #ifdef never 118: case 'g': 119: ++gdebug; 120: break; 121: #endif 122: case 'a': 123: ++adebug; 124: break; 125: #ifdef never 126: case 'G': 127: ++gdebug; 128: oldway = 1; 129: break; 130: #endif 131: } 132: } 133: } 134: else { 135: if( *(argv[i]) != '-' ) switch( fdef++ ) { 136: case 0: 137: case 1: 138: if( freopen(argv[i], fdef==1 ? "r" : "w", fdef==1 ? stdin : stdout) == NULL) { 139: fprintf(stderr, "ccom:can't open %s\n", argv[i]); 140: exit(1); 141: } 142: break; 143: 144: default: 145: ; 146: } 147: } 148: } 149: 150: # ifdef ONEPASS 151: p2init( argc, argv ); 152: # endif 153: 154: for( i=0; i<SYMTSZ; ++i ) stab[i].stype = TNULL; 155: 156: lineno = 1; 157: 158: lxinit(); 159: tinit(); 160: mkdope(); 161: 162: /* dimension table initialization */ 163: 164: dimtab[NULL] = 0; 165: dimtab[CHAR] = SZCHAR; 166: dimtab[INT] = SZINT; 167: dimtab[FLOAT] = SZFLOAT; 168: dimtab[DOUBLE] = SZDOUBLE; 169: dimtab[LONG] = SZLONG; 170: dimtab[SHORT] = SZSHORT; 171: dimtab[UCHAR] = SZCHAR; 172: dimtab[USHORT] = SZSHORT; 173: dimtab[UNSIGNED] = SZINT; 174: dimtab[ULONG] = SZLONG; 175: /* starts past any of the above */ 176: curdim = 16; 177: reached = 1; 178: 179: fpe_sigvec.sv_handler = fpe; 180: (void) sigvec(SIGFPE, &fpe_sigvec, (struct sigvec *) NULL); 181: 182: yyparse(); 183: yyaccpt(); 184: 185: ejobcode( nerrors ? 1 : 0 ); 186: return(nerrors?1:0); 187: 188: } 189: 190: # ifdef ibm 191: 192: # define CSMASK 0377 193: # define CSSZ 256 194: 195: # else 196: 197: # define CSMASK 0177 198: # define CSSZ 128 199: 200: # endif 201: 202: short lxmask[CSSZ+1]; 203: 204: lxenter( s, m ) register char *s; register short m; { 205: /* enter a mask into lxmask */ 206: register c; 207: 208: while( c= *s++ ) lxmask[c+1] |= m; 209: 210: } 211: 212: 213: # define lxget(c,m) (lxgcp=yytext,lxmore(c,m)) 214: 215: lxmore( c, m ) register c, m; { 216: register char *cp; 217: 218: *(cp = lxgcp) = c; 219: while( c=getchar(), lxmask[c+1]&m ){ 220: if( cp < &yytext[LXTSZ-1] ){ 221: *++cp = c; 222: } 223: } 224: ungetc(c,stdin); 225: *(lxgcp = cp+1) = '\0'; 226: } 227: 228: struct lxdope { 229: short lxch; /* the character */ 230: short lxact; /* the action to be performed */ 231: short lxtok; /* the token number to be returned */ 232: short lxval; /* the value to be returned */ 233: } lxdope[] = { 234: 235: '@', A_ERR, 0, 0, /* illegal characters go here... */ 236: '_', A_LET, 0, 0, /* letters point here */ 237: '0', A_DIG, 0, 0, /* digits point here */ 238: ' ', A_WS, 0, 0, /* whitespace goes here */ 239: '\n', A_NL, 0, 0, 240: '"', A_STR, 0, 0, /* character string */ 241: '\'', A_CC, 0, 0, /* character constant */ 242: '`', A_BCD, 0, 0, /* GCOS BCD constant */ 243: '(', A_1C, LP, 0, 244: ')', A_1C, RP, 0, 245: '{', A_1C, LC, 0, 246: '}', A_1C, RC, 0, 247: '[', A_1C, LB, 0, 248: ']', A_1C, RB, 0, 249: '*', A_1C, MUL, MUL, 250: '?', A_1C, QUEST, 0, 251: ':', A_1C, COLON, 0, 252: '+', A_PL, PLUS, PLUS, 253: '-', A_MI, MINUS, MINUS, 254: '/', A_SL, DIVOP, DIV, 255: '%', A_1C, DIVOP, MOD, 256: '&', A_AND, AND, AND, 257: '|', A_OR, OR, OR, 258: '^', A_1C, ER, ER, 259: '!', A_NOT, UNOP, NOT, 260: '~', A_1C, UNOP, COMPL, 261: ',', A_1C, CM, CM, 262: ';', A_1C, SM, 0, 263: '.', A_DOT, STROP, DOT, 264: '<', A_LT, RELOP, LT, 265: '>', A_GT, RELOP, GT, 266: '=', A_EQ, ASSIGN, ASSIGN, 267: -1, A_1C, 0, 0, 268: }; 269: 270: struct lxdope *lxcp[CSSZ+1]; 271: 272: lxinit(){ 273: register struct lxdope *p; 274: register i; 275: register char *cp; 276: /* set up character classes */ 277: 278: lxenter( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$", LEXLET ); 279: lxenter( "0123456789", LEXDIG ); 280: lxenter( "0123456789abcdefABCDEF", LEXHEX ); 281: /* \013 should become \v someday; \013 is OK for ASCII and EBCDIC */ 282: lxenter( " \t\r\b\f\013", LEXWS ); 283: lxenter( "01234567", LEXOCT ); 284: lxmask['.'+1] |= LEXDOT; 285: 286: /* make lxcp point to appropriate lxdope entry for each character */ 287: 288: /* initialize error entries */ 289: 290: for( i= 0; i<=CSSZ; ++i ) lxcp[i] = lxdope; 291: 292: /* make unique entries */ 293: 294: for( p=lxdope; ; ++p ) { 295: lxcp[p->lxch+1] = p; 296: if( p->lxch < 0 ) break; 297: } 298: 299: /* handle letters, digits, and whitespace */ 300: /* by convention, first, second, and third places */ 301: 302: cp = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$"; 303: while( *cp ) lxcp[*cp++ + 1] = &lxdope[1]; 304: cp = "123456789"; 305: while( *cp ) lxcp[*cp++ + 1] = &lxdope[2]; 306: cp = "\t\b\r\f\013"; 307: while( *cp ) lxcp[*cp++ + 1] = &lxdope[3]; 308: 309: /* first line might have title */ 310: lxtitle(); 311: 312: } 313: 314: int lxmatch; /* character to be matched in char or string constant */ 315: 316: lxstr(ct){ 317: /* match a string or character constant, up to lxmatch */ 318: 319: register c; 320: register val; 321: register i; 322: 323: i=0; 324: while( (c=getchar()) != lxmatch ){ 325: switch( c ) { 326: 327: case EOF: 328: uerror("unexpected EOF" ); 329: break; 330: 331: case '\n': 332: uerror("newline in string or char constant" ); 333: ++lineno; 334: break; 335: 336: case '\\': 337: switch( c = getchar() ){ 338: 339: case '\n': 340: ++lineno; 341: continue; 342: 343: default: 344: val = c; 345: goto mkcc; 346: 347: case 'n': 348: val = '\n'; 349: goto mkcc; 350: 351: case 'r': 352: val = '\r'; 353: goto mkcc; 354: 355: case 'b': 356: val = '\b'; 357: goto mkcc; 358: 359: case 't': 360: val = '\t'; 361: goto mkcc; 362: 363: case 'f': 364: val = '\f'; 365: goto mkcc; 366: 367: case 'v': 368: val = '\013'; 369: goto mkcc; 370: 371: case '0': 372: case '1': 373: case '2': 374: case '3': 375: case '4': 376: case '5': 377: case '6': 378: case '7': 379: val = c-'0'; 380: c=getchar(); /* try for 2 */ 381: if( lxmask[c+1] & LEXOCT ){ 382: val = (val<<3) | (c-'0'); 383: c = getchar(); /* try for 3 */ 384: if( lxmask[c+1] & LEXOCT ){ 385: val = (val<<3) | (c-'0'); 386: } 387: else ungetc( c ,stdin); 388: } 389: else ungetc( c ,stdin); 390: 391: goto mkcc1; 392: 393: } 394: default: 395: val =c; 396: mkcc: 397: val = CCTRANS(val); 398: mkcc1: 399: if( lxmatch == '\'' ){ 400: val = CHARCAST(val); /* it is, after all, a "character" constant */ 401: makecc( val, i ); 402: } 403: else { /* stash the byte into the string */ 404: if( strflg ) { 405: if( ct==0 || i<ct ) putbyte( val ); 406: else if( i == ct ) werror("non-null byte ignored in string initializer" ); 407: } 408: else bycode( val, i ); 409: } 410: ++i; 411: continue; 412: } 413: break; 414: } 415: /* end of string or char constant */ 416: 417: if( lxmatch == '"' ){ 418: if( strflg ){ /* end the string */ 419: if( ct==0 || i<ct ) putbyte( 0 ); /* the null at the end */ 420: } 421: else { /* the initializer gets a null byte */ 422: bycode( 0, i++ ); 423: bycode( -1, i ); 424: dimtab[curdim] = i; /* in case of later sizeof ... */ 425: } 426: } 427: else { /* end the character constant */ 428: if( i == 0 ) uerror("empty character constant" ); 429: if( i>(SZINT/SZCHAR) || ( (pflag||hflag)&&i>1) ) 430: uerror("too many characters in character constant" ); 431: } 432: } 433: 434: lxcom(){ 435: register c; 436: /* saw a /*: process a comment */ 437: 438: for(;;){ 439: 440: switch( c = getchar() ){ 441: 442: case EOF: 443: uerror("unexpected EOF" ); 444: return; 445: 446: case '\n': 447: ++lineno; 448: 449: default: 450: continue; 451: 452: case '*': 453: if( (c = getchar()) == '/' ) return; 454: else ungetc( c ,stdin); 455: continue; 456: 457: # ifdef LINT 458: case 'V': 459: lxget( c, LEXLET|LEXDIG ); 460: { 461: extern int vaflag; 462: int i; 463: i = yytext[7]?yytext[7]-'0':0; 464: yytext[7] = '\0'; 465: if( strcmp( yytext, "VARARGS" ) ) continue; 466: vaflag = i; 467: continue; 468: } 469: case 'L': 470: lxget( c, LEXLET ); 471: if( strcmp( yytext, "LINTLIBRARY" ) ) continue; 472: { 473: extern int libflag; 474: libflag = 1; 475: } 476: continue; 477: 478: case 'A': 479: lxget( c, LEXLET ); 480: if( strcmp( yytext, "ARGSUSED" ) ) continue; 481: { 482: extern int argflag, vflag; 483: argflag = 1; 484: vflag = 0; 485: } 486: continue; 487: 488: case 'N': 489: lxget( c, LEXLET ); 490: if( strcmp( yytext, "NOTREACHED" ) ) continue; 491: reached = 0; 492: continue; 493: # endif 494: } 495: } 496: } 497: 498: yylex(){ 499: for(;;){ 500: 501: register lxchar; 502: register struct lxdope *p; 503: register struct symtab *sp; 504: int id; 505: 506: switch( (p=lxcp[(lxchar=getchar())+1])->lxact ){ 507: 508: onechar: 509: ungetc( lxchar ,stdin); 510: 511: case A_1C: 512: /* eat up a single character, and return an opcode */ 513: 514: yylval.intval = p->lxval; 515: return( p->lxtok ); 516: 517: case A_ERR: 518: uerror("illegal character: %03o (octal)", lxchar ); 519: break; 520: 521: case A_LET: 522: /* collect an identifier, check for reserved word, and return */ 523: lxget( lxchar, LEXLET|LEXDIG ); 524: if( (lxchar=lxres()) > 0 ) return( lxchar ); /* reserved word */ 525: if( lxchar== 0 ) continue; 526: #ifdef FLEXNAMES 527: id = lookup( hash(yytext), 528: #else 529: id = lookup( yytext, 530: #endif 531: /* tag name for struct/union/enum */ 532: (stwart&TAGNAME)? STAG: 533: /* member name for struct/union */ 534: (stwart&(INSTRUCT|INUNION|FUNNYNAME))?SMOS:0 ); 535: sp = &stab[id]; 536: if( sp->sclass == TYPEDEF && !stwart ){ 537: stwart = instruct; 538: yylval.nodep = mkty( sp->stype, sp->dimoff, sp->sizoff ); 539: return( TYPE ); 540: } 541: stwart = (stwart&SEENAME) ? instruct : 0; 542: yylval.intval = id; 543: return( NAME ); 544: 545: case A_DIG: 546: /* collect a digit string, then look at last one... */ 547: lastcon = 0; 548: lxget( lxchar, LEXDIG ); 549: switch( lxchar=getchar() ){ 550: 551: case 'x': 552: case 'X': 553: if( yytext[0] != '0' && !yytext[1] ) uerror("illegal hex constant" ); 554: lxmore( lxchar, LEXHEX ); 555: /* convert the value */ 556: { 557: register char *cp; 558: for( cp = yytext+2; *cp; ++cp ){ 559: /* this code won't work for all wild character sets, 560: but seems ok for ascii and ebcdic */ 561: lastcon <<= 4; 562: if( isdigit( *cp ) ) lastcon += *cp-'0'; 563: else if( isupper( *cp ) ) lastcon += *cp - 'A'+ 10; 564: else lastcon += *cp - 'a'+ 10; 565: } 566: } 567: 568: hexlong: 569: /* criterion for longness for hex and octal constants is that it 570: fit within 0177777 */ 571: if( lastcon & ~0177777L ) yylval.intval = 1; 572: else yylval.intval = 0; 573: 574: goto islong; 575: 576: case '.': 577: lxmore( lxchar, LEXDIG ); 578: 579: getfp: 580: if( (lxchar=getchar()) == 'e' || lxchar == 'E' ){ /* exponent */ 581: 582: case 'e': 583: case 'E': 584: if( (lxchar=getchar()) == '+' || lxchar == '-' ){ 585: *lxgcp++ = 'e'; 586: } 587: else { 588: ungetc(lxchar,stdin); 589: lxchar = 'e'; 590: } 591: lxmore( lxchar, LEXDIG ); 592: /* now have the whole thing... */ 593: } 594: else { /* no exponent */ 595: ungetc( lxchar ,stdin); 596: } 597: return( isitfloat( yytext ) ); 598: 599: default: 600: ungetc( lxchar ,stdin); 601: if( yytext[0] == '0' ){ 602: /* convert in octal */ 603: register char *cp; 604: for( cp = yytext+1; *cp; ++cp ){ 605: lastcon <<= 3; 606: lastcon += *cp - '0'; 607: } 608: goto hexlong; 609: } 610: else { 611: /* convert in decimal */ 612: register char *cp; 613: for( cp = yytext; *cp; ++cp ){ 614: lastcon = lastcon * 10 + *cp - '0'; 615: } 616: } 617: 618: /* decide if it is long or not (decimal case) */ 619: 620: /* if it is positive and fits in 15 bits, or negative and 621: and fits in 15 bits plus an extended sign, it is int; otherwise long */ 622: /* if there is an l or L following, all bets are off... */ 623: 624: { CONSZ v; 625: v = lastcon & ~077777L; 626: if( v == 0 || v == ~077777L ) yylval.intval = 0; 627: else yylval.intval = 1; 628: } 629: 630: islong: 631: /* finally, look for trailing L or l */ 632: if( (lxchar = getchar()) == 'L' || lxchar == 'l' ) yylval.intval = 1; 633: else ungetc( lxchar ,stdin); 634: return( ICON ); 635: } 636: 637: case A_DOT: 638: /* look for a dot: if followed by a digit, floating point */ 639: lxchar = getchar(); 640: if( lxmask[lxchar+1] & LEXDIG ){ 641: ungetc(lxchar,stdin); 642: lxget( '.', LEXDIG ); 643: goto getfp; 644: } 645: stwart = FUNNYNAME; 646: goto onechar; 647: 648: case A_STR: 649: /* string constant */ 650: lxmatch = '"'; 651: return( STRING ); 652: 653: case A_CC: 654: /* character constant */ 655: lxmatch = '\''; 656: lastcon = 0; 657: lxstr(0); 658: yylval.intval = 0; 659: return( ICON ); 660: 661: case A_BCD: 662: { 663: register i; 664: int j; 665: for( i=0; i<LXTSZ; ++i ){ 666: if( ( j = getchar() ) == '`' ) break; 667: if( j == '\n' ){ 668: uerror("newline in BCD constant" ); 669: break; 670: } 671: yytext[i] = j; 672: } 673: yytext[i] = '\0'; 674: if( i>6 ) uerror("BCD constant exceeds 6 characters" ); 675: # ifdef gcos 676: else strtob( yytext, &lastcon, i ); 677: lastcon >>= 6*(6-i); 678: # else 679: uerror("gcos BCD constant illegal" ); 680: # endif 681: yylval.intval = 0; /* not long */ 682: return( ICON ); 683: } 684: 685: case A_SL: 686: /* / */ 687: if( (lxchar=getchar()) != '*' ) goto onechar; 688: lxcom(); 689: case A_WS: 690: continue; 691: 692: case A_NL: 693: ++lineno; 694: lxtitle(); 695: continue; 696: 697: case A_NOT: 698: /* ! */ 699: if( (lxchar=getchar()) != '=' ) goto onechar; 700: yylval.intval = NE; 701: return( EQUOP ); 702: 703: case A_MI: 704: /* - */ 705: if( (lxchar=getchar()) == '-' ){ 706: yylval.intval = DECR; 707: return( INCOP ); 708: } 709: if( lxchar != '>' ) goto onechar; 710: stwart = FUNNYNAME; 711: yylval.intval=STREF; 712: return( STROP ); 713: 714: case A_PL: 715: /* + */ 716: if( (lxchar=getchar()) != '+' ) goto onechar; 717: yylval.intval = INCR; 718: return( INCOP ); 719: 720: case A_AND: 721: /* & */ 722: if( (lxchar=getchar()) != '&' ) goto onechar; 723: return( yylval.intval = ANDAND ); 724: 725: case A_OR: 726: /* | */ 727: if( (lxchar=getchar()) != '|' ) goto onechar; 728: return( yylval.intval = OROR ); 729: 730: case A_LT: 731: /* < */ 732: if( (lxchar=getchar()) == '<' ){ 733: yylval.intval = LS; 734: return( SHIFTOP ); 735: } 736: if( lxchar != '=' ) goto onechar; 737: yylval.intval = LE; 738: return( RELOP ); 739: 740: case A_GT: 741: /* > */ 742: if( (lxchar=getchar()) == '>' ){ 743: yylval.intval = RS; 744: return(SHIFTOP ); 745: } 746: if( lxchar != '=' ) goto onechar; 747: yylval.intval = GE; 748: return( RELOP ); 749: 750: case A_EQ: 751: /* = */ 752: switch( lxchar = getchar() ){ 753: 754: case '=': 755: yylval.intval = EQ; 756: return( EQUOP ); 757: 758: case '+': 759: yylval.intval = ASG PLUS; 760: break; 761: 762: case '-': 763: yylval.intval = ASG MINUS; 764: 765: warn: 766: if( lxmask[ (lxchar=getchar())+1] & (LEXLET|LEXDIG|LEXDOT) ){ 767: werror("ambiguous assignment: assignment op taken" ); 768: } 769: ungetc( lxchar ,stdin); 770: break; 771: 772: case '*': 773: yylval.intval = ASG MUL; 774: goto warn; 775: 776: case '/': 777: yylval.intval = ASG DIV; 778: break; 779: 780: case '%': 781: yylval.intval = ASG MOD; 782: break; 783: 784: case '&': 785: yylval.intval = ASG AND; 786: break; 787: 788: case '|': 789: yylval.intval = ASG OR; 790: break; 791: 792: case '^': 793: yylval.intval = ASG ER; 794: break; 795: 796: case '<': 797: if( (lxchar=getchar()) != '<' ){ 798: uerror("=<%c illegal", lxchar ); 799: } 800: yylval.intval = ASG LS; 801: break; 802: 803: case '>': 804: if( (lxchar=getchar()) != '>' ){ 805: uerror("=>%c illegal", lxchar ); 806: } 807: yylval.intval = ASG RS; 808: break; 809: 810: default: 811: goto onechar; 812: 813: } 814: 815: return( ASOP ); 816: 817: default: 818: cerror("yylex error, character %03o (octal)", lxchar ); 819: 820: } 821: 822: /* ordinarily, repeat here... */ 823: cerror("out of switch in yylex" ); 824: 825: } 826: 827: } 828: 829: struct lxrdope { 830: /* dope for reserved, in alphabetical order */ 831: 832: char *lxrch; /* name of reserved word */ 833: short lxract; /* reserved word action */ 834: short lxrval; /* value to be returned */ 835: } lxrdope[] = { 836: 837: "asm", AR_A, 0, 838: "auto", AR_CL, AUTO, 839: "break", AR_RW, BREAK, 840: "char", AR_TY, CHAR, 841: "case", AR_RW, CASE, 842: "continue", AR_RW, CONTINUE, 843: "double", AR_TY, DOUBLE, 844: "default", AR_RW, DEFAULT, 845: "do", AR_RW, DO, 846: "extern", AR_CL, EXTERN, 847: "else", AR_RW, ELSE, 848: "enum", AR_E, ENUM, 849: "for", AR_RW, FOR, 850: "float", AR_TY, FLOAT, 851: "fortran", AR_CL, FORTRAN, 852: "goto", AR_RW, GOTO, 853: "if", AR_RW, IF, 854: "int", AR_TY, INT, 855: "long", AR_TY, LONG, 856: "return", AR_RW, RETURN, 857: "register", AR_CL, REGISTER, 858: "switch", AR_RW, SWITCH, 859: "struct", AR_S, 0, 860: "sizeof", AR_RW, SIZEOF, 861: "short", AR_TY, SHORT, 862: "static", AR_CL, STATIC, 863: "typedef", AR_CL, TYPEDEF, 864: "unsigned", AR_TY, UNSIGNED, 865: "union", AR_U, 0, 866: "void", AR_TY, UNDEF, /* tymerge adds FTN */ 867: "while", AR_RW, WHILE, 868: "", 0, 0, /* to stop the search */ 869: }; 870: 871: lxres() { 872: /* check to see of yytext is reserved; if so, 873: /* do the appropriate action and return */ 874: /* otherwise, return -1 */ 875: 876: register c, ch; 877: register struct lxrdope *p; 878: 879: ch = yytext[0]; 880: 881: if( !islower(ch) ) return( -1 ); 882: 883: switch( ch ){ 884: 885: case 'a': 886: c=0; break; 887: case 'b': 888: c=2; break; 889: case 'c': 890: c=3; break; 891: case 'd': 892: c=6; break; 893: case 'e': 894: c=9; break; 895: case 'f': 896: c=12; break; 897: case 'g': 898: c=15; break; 899: case 'i': 900: c=16; break; 901: case 'l': 902: c=18; break; 903: case 'r': 904: c=19; break; 905: case 's': 906: c=21; break; 907: case 't': 908: c=26; break; 909: case 'u': 910: c=27; break; 911: case 'v': 912: c=29; break; 913: case 'w': 914: c=30; break; 915: 916: default: 917: return( -1 ); 918: } 919: 920: for( p= lxrdope+c; p->lxrch[0] == ch; ++p ){ 921: if( !strcmp( yytext, p->lxrch ) ){ /* match */ 922: switch( p->lxract ){ 923: 924: case AR_TY: 925: /* type word */ 926: stwart = instruct; 927: yylval.nodep = mkty( (TWORD)p->lxrval, 0, p->lxrval ); 928: return( TYPE ); 929: 930: case AR_RW: 931: /* ordinary reserved word */ 932: return( yylval.intval = p->lxrval ); 933: 934: case AR_CL: 935: /* class word */ 936: yylval.intval = p->lxrval; 937: return( CLASS ); 938: 939: case AR_S: 940: /* struct */ 941: stwart = INSTRUCT|SEENAME|TAGNAME; 942: yylval.intval = INSTRUCT; 943: return( STRUCT ); 944: 945: case AR_U: 946: /* union */ 947: stwart = INUNION|SEENAME|TAGNAME; 948: yylval.intval = INUNION; 949: return( STRUCT ); 950: 951: case AR_E: 952: /* enums */ 953: stwart = SEENAME|TAGNAME; 954: return( yylval.intval = ENUM ); 955: 956: case AR_A: 957: /* asm */ 958: asm_esc = 1; /* warn the world! */ 959: lxget( ' ', LEXWS ); 960: if( getchar() != '(' ) goto badasm; 961: lxget( ' ', LEXWS ); 962: if( getchar() != '"' ) goto badasm; 963: # ifndef ONEPASS 964: # ifndef LINT 965: putchar(')'); 966: # endif 967: # endif 968: while( (c=getchar()) != '"' ){ 969: if( c=='\n' || c==EOF ) goto badasm; 970: # ifndef LINT 971: putchar(c); 972: # endif 973: } 974: lxget( ' ', LEXWS ); 975: if( getchar() != ')' ) goto badasm; 976: # ifndef LINT 977: putchar('\n'); 978: # endif 979: return( 0 ); 980: 981: badasm: 982: uerror("bad asm construction" ); 983: return( 0 ); 984: 985: default: 986: cerror("bad AR_?? action" ); 987: } 988: } 989: } 990: return( -1 ); 991: } 992: 993: extern int labelno; 994: 995: lxtitle(){ 996: /* called after a newline; set linenumber and file name */ 997: 998: register c, val; 999: register char *cp, *cq; 1000: 1001: for(;;){ /* might be several such lines in a row */ 1002: if( (c=getchar()) != '#' ){ 1003: if( c != EOF ) ungetc(c,stdin); 1004: #ifndef LINT 1005: if ( lastloc != PROG) return; 1006: cp = ftitle; 1007: cq = ititle; 1008: while ( *cp ) if (*cp++ != *cq++) return; 1009: if ( *cq ) return; 1010: psline(); 1011: #endif 1012: return; 1013: } 1014: 1015: lxget( ' ', LEXWS ); 1016: val = 0; 1017: for( c=getchar(); isdigit(c); c=getchar() ){ 1018: val = val*10+ c - '0'; 1019: } 1020: if( c == EOF ) 1021: continue; 1022: ungetc( c, stdin ); 1023: lineno = val; 1024: lxget( ' ', LEXWS ); 1025: if( (c=getchar()) != '\n' && c != EOF ){ 1026: for( cp=ftitle; c!=EOF && c!='\n'; c=getchar(),++cp ){ 1027: *cp = c; 1028: } 1029: *cp = '\0'; 1030: #ifndef LINT 1031: if (ititle[0] == '\0') { 1032: cp = ftitle; 1033: cq = ititle; 1034: while ( *cp ) 1035: *cq++ = *cp++; 1036: *cq = '\0'; 1037: *--cq = '\0'; 1038: #ifndef FLEXNAMES 1039: for ( cp = ititle+1; *(cp-1); cp += 8 ) { 1040: pstab(cp, N_SO); 1041: if (gdebug) printf("0,0,LL%d\n", labelno); 1042: } 1043: #else 1044: pstab(ititle+1, N_SO); 1045: if (gdebug) printf("0,0,LL%d\n", labelno); 1046: #endif 1047: 1048: *cq = '"'; 1049: printf("LL%d:\n", labelno++); 1050: } 1051: #endif 1052: } 1053: } 1054: } 1055: 1056: #define NSAVETAB 512 /* was 4096 */ 1057: char *savetab; 1058: int saveleft; 1059: 1060: char * 1061: savestr(cp) 1062: register char *cp; 1063: { 1064: register int len; 1065: 1066: len = strlen(cp) + 1; 1067: if (len > saveleft) { 1068: saveleft = NSAVETAB; 1069: if (len > saveleft) 1070: saveleft = len; 1071: savetab = (char *)malloc(saveleft); 1072: if (savetab == 0) 1073: cerror("Ran out of memory (savestr)"); 1074: } 1075: strncpy(savetab, cp, len); 1076: cp = savetab; 1077: savetab += len; 1078: saveleft -= len; 1079: return (cp); 1080: } 1081: 1082: /* 1083: * The definition for the segmented hash tables. 1084: */ 1085: #define MAXHASH 16 /* was 20 */ 1086: #define HASHINC 257 /* was 1013 */ 1087: struct ht { 1088: char **ht_low; 1089: char **ht_high; 1090: int ht_used; 1091: } htab[MAXHASH]; 1092: 1093: char * 1094: hash(s) 1095: char *s; 1096: { 1097: register char **h; 1098: register i; 1099: register char *cp; 1100: struct ht *htp; 1101: int sh; 1102: 1103: /* 1104: * The hash function is a modular hash of 1105: * the sum of the characters with the sum 1106: * doubled before each successive character 1107: * is added. 1108: */ 1109: cp = s; 1110: i = 0; 1111: while (*cp) 1112: i = i*2 + *cp++; 1113: sh = (i&077777) % HASHINC; 1114: cp = s; 1115: /* 1116: * There are as many as MAXHASH active 1117: * hash tables at any given point in time. 1118: * The search starts with the first table 1119: * and continues through the active tables 1120: * as necessary. 1121: */ 1122: for (htp = htab; htp < &htab[MAXHASH]; htp++) { 1123: if (htp->ht_low == 0) { 1124: register char **hp = 1125: (char **) calloc(sizeof (char **), HASHINC); 1126: if (hp == 0) 1127: cerror("ran out of memory (hash)"); 1128: htp->ht_low = hp; 1129: htp->ht_high = htp->ht_low + HASHINC; 1130: } 1131: h = htp->ht_low + sh; 1132: /* 1133: * quadratic rehash increment 1134: * starts at 1 and incremented 1135: * by two each rehash. 1136: */ 1137: i = 1; 1138: do { 1139: if (*h == 0) { 1140: if (htp->ht_used > (HASHINC * 3)/4) 1141: break; 1142: htp->ht_used++; 1143: *h = savestr(cp); 1144: return (*h); 1145: } 1146: if (**h == *cp && strcmp(*h, cp) == 0) 1147: return (*h); 1148: h += i; 1149: i += 2; 1150: if (h >= htp->ht_high) 1151: h -= HASHINC; 1152: } while (i < HASHINC); 1153: } 1154: cerror("ran out of hash tables"); 1155: /* NOTREACHED */ 1156: }