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