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