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