|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid ="@(#)scan.c 2.4 (Berkeley) 4/22/87"; ! 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: extern char *release; ! 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: if (hflag) ! 341: uerror("superfluous backslash in string/character constant"); ! 342: /*FALLTHROUGH*/ ! 343: case '\\': ! 344: case '\"': ! 345: case '\'': ! 346: val = c; ! 347: goto mkcc; ! 348: ! 349: case 'n': ! 350: val = '\n'; ! 351: goto mkcc; ! 352: ! 353: case 'r': ! 354: val = '\r'; ! 355: goto mkcc; ! 356: ! 357: case 'b': ! 358: val = '\b'; ! 359: goto mkcc; ! 360: ! 361: case 't': ! 362: val = '\t'; ! 363: goto mkcc; ! 364: ! 365: case 'f': ! 366: val = '\f'; ! 367: goto mkcc; ! 368: ! 369: case 'v': ! 370: val = '\013'; ! 371: goto mkcc; ! 372: ! 373: case '0': ! 374: case '1': ! 375: case '2': ! 376: case '3': ! 377: case '4': ! 378: case '5': ! 379: case '6': ! 380: case '7': ! 381: val = c-'0'; ! 382: c=getchar(); /* try for 2 */ ! 383: if( lxmask[c+1] & LEXOCT ){ ! 384: val = (val<<3) | (c-'0'); ! 385: c = getchar(); /* try for 3 */ ! 386: if( lxmask[c+1] & LEXOCT ){ ! 387: val = (val<<3) | (c-'0'); ! 388: } ! 389: else ungetc( c ,stdin); ! 390: } ! 391: else ungetc( c ,stdin); ! 392: ! 393: goto mkcc1; ! 394: ! 395: } ! 396: default: ! 397: val =c; ! 398: mkcc: ! 399: val = CCTRANS(val); ! 400: mkcc1: ! 401: if( lxmatch == '\'' ){ ! 402: val = CHARCAST(val); /* it is, after all, a "character" constant */ ! 403: makecc( val, i ); ! 404: } ! 405: else { /* stash the byte into the string */ ! 406: if( strflg ) { ! 407: if( ct==0 || i<ct ) putbyte( val ); ! 408: else if( i == ct ) werror( "non-null byte ignored in string initializer" ); ! 409: } ! 410: else bycode( val, i ); ! 411: } ! 412: ++i; ! 413: continue; ! 414: } ! 415: break; ! 416: } ! 417: /* end of string or char constant */ ! 418: ! 419: if( lxmatch == '"' ){ ! 420: if( strflg ){ /* end the string */ ! 421: if( ct==0 || i<ct ) putbyte( 0 ); /* the null at the end */ ! 422: } ! 423: else { /* the initializer gets a null byte */ ! 424: bycode( 0, i++ ); ! 425: bycode( -1, i ); ! 426: dimtab[curdim] = i; /* in case of later sizeof ... */ ! 427: } ! 428: } ! 429: else { /* end the character constant */ ! 430: if( i == 0 ) uerror( "empty character constant" ); ! 431: if( i>(SZINT/SZCHAR) || ( (pflag||hflag)&&i>1) ) ! 432: uerror( "too many characters in character constant" ); ! 433: } ! 434: } ! 435: ! 436: lxcom(){ ! 437: register c; ! 438: /* saw a /*: process a comment */ ! 439: ! 440: for(;;){ ! 441: ! 442: switch( c = getchar() ){ ! 443: ! 444: case EOF: ! 445: uerror( "unexpected EOF" ); ! 446: return; ! 447: ! 448: case '\n': ! 449: ++lineno; ! 450: ! 451: default: ! 452: continue; ! 453: ! 454: case '*': ! 455: if( (c = getchar()) == '/' ) return; ! 456: else ungetc( c ,stdin); ! 457: continue; ! 458: ! 459: # ifdef LINT ! 460: case 'V': ! 461: lxget( c, LEXLET|LEXDIG ); ! 462: { ! 463: extern int vaflag; ! 464: int i; ! 465: i = yytext[7]?yytext[7]-'0':0; ! 466: yytext[7] = '\0'; ! 467: if( strcmp( yytext, "VARARGS" ) ) continue; ! 468: vaflag = i; ! 469: continue; ! 470: } ! 471: case 'L': ! 472: lxget( c, LEXLET ); ! 473: if( strcmp( yytext, "LINTLIBRARY" ) ) continue; ! 474: { ! 475: extern int libflag; ! 476: libflag = 1; ! 477: } ! 478: continue; ! 479: ! 480: case 'A': ! 481: lxget( c, LEXLET ); ! 482: if( strcmp( yytext, "ARGSUSED" ) ) continue; ! 483: { ! 484: extern int argflag, vflag; ! 485: argflag = 1; ! 486: vflag = 0; ! 487: } ! 488: continue; ! 489: ! 490: case 'N': ! 491: lxget( c, LEXLET ); ! 492: if( strcmp( yytext, "NOTREACHED" ) ) continue; ! 493: reached = 0; ! 494: continue; ! 495: # endif ! 496: } ! 497: } ! 498: } ! 499: ! 500: yylex(){ ! 501: for(;;){ ! 502: ! 503: register lxchar; ! 504: register struct lxdope *p; ! 505: register struct symtab *sp; ! 506: int id; ! 507: ! 508: switch( (p=lxcp[(lxchar=getchar())+1])->lxact ){ ! 509: ! 510: onechar: ! 511: ungetc( lxchar ,stdin); ! 512: ! 513: case A_1C: ! 514: /* eat up a single character, and return an opcode */ ! 515: ! 516: yylval.intval = p->lxval; ! 517: return( p->lxtok ); ! 518: ! 519: case A_ERR: ! 520: uerror( "illegal character: %03o (octal)", lxchar ); ! 521: break; ! 522: ! 523: case A_LET: ! 524: /* collect an identifier, check for reserved word, and return */ ! 525: lxget( lxchar, LEXLET|LEXDIG ); ! 526: if( (lxchar=lxres()) > 0 ) return( lxchar ); /* reserved word */ ! 527: if( lxchar== 0 ) continue; ! 528: #ifdef FLEXNAMES ! 529: id = lookup( hash(yytext), ! 530: #else ! 531: id = lookup( yytext, ! 532: #endif ! 533: /* tag name for struct/union/enum */ ! 534: (stwart&TAGNAME)? STAG: ! 535: /* member name for struct/union */ ! 536: (stwart&(INSTRUCT|INUNION|FUNNYNAME))?SMOS:0 ); ! 537: sp = &stab[id]; ! 538: if( sp->sclass == TYPEDEF && !stwart ){ ! 539: stwart = instruct; ! 540: yylval.nodep = mkty( sp->stype, sp->dimoff, sp->sizoff ); ! 541: return( TYPE ); ! 542: } ! 543: stwart = (stwart&SEENAME) ? instruct : 0; ! 544: yylval.intval = id; ! 545: return( NAME ); ! 546: ! 547: case A_DIG: ! 548: /* collect a digit string, then look at last one... */ ! 549: lastcon = 0; ! 550: lxget( lxchar, LEXDIG ); ! 551: switch( lxchar=getchar() ){ ! 552: ! 553: case 'x': ! 554: case 'X': ! 555: if( yytext[0] != '0' && !yytext[1] ) uerror( "illegal hex constant" ); ! 556: lxmore( lxchar, LEXHEX ); ! 557: /* convert the value */ ! 558: { ! 559: register char *cp; ! 560: for( cp = yytext+2; *cp; ++cp ){ ! 561: /* this code won't work for all wild character sets, ! 562: but seems ok for ascii and ebcdic */ ! 563: lastcon <<= 4; ! 564: if( isdigit( *cp ) ) lastcon += *cp-'0'; ! 565: else if( isupper( *cp ) ) lastcon += *cp - 'A'+ 10; ! 566: else lastcon += *cp - 'a'+ 10; ! 567: } ! 568: } ! 569: ! 570: hexlong: ! 571: /* criterion for longness for hex and octal constants is that it ! 572: fit within 0177777 */ ! 573: if( lastcon & ~0177777L ) yylval.intval = 1; ! 574: else yylval.intval = 0; ! 575: ! 576: goto islong; ! 577: ! 578: case '.': ! 579: lxmore( lxchar, LEXDIG ); ! 580: ! 581: getfp: ! 582: if( (lxchar=getchar()) == 'e' || lxchar == 'E' ){ /* exponent */ ! 583: ! 584: case 'e': ! 585: case 'E': ! 586: if( (lxchar=getchar()) == '+' || lxchar == '-' ){ ! 587: *lxgcp++ = 'e'; ! 588: } ! 589: else { ! 590: ungetc(lxchar,stdin); ! 591: lxchar = 'e'; ! 592: } ! 593: lxmore( lxchar, LEXDIG ); ! 594: /* now have the whole thing... */ ! 595: } ! 596: else { /* no exponent */ ! 597: ungetc( lxchar ,stdin); ! 598: } ! 599: return( isitfloat( yytext ) ); ! 600: ! 601: default: ! 602: ungetc( lxchar ,stdin); ! 603: if( yytext[0] == '0' ){ ! 604: /* convert in octal */ ! 605: register char *cp; ! 606: for( cp = yytext+1; *cp; ++cp ){ ! 607: lastcon <<= 3; ! 608: lastcon += *cp - '0'; ! 609: } ! 610: goto hexlong; ! 611: } ! 612: else { ! 613: /* convert in decimal */ ! 614: register char *cp; ! 615: for( cp = yytext; *cp; ++cp ){ ! 616: lastcon = lastcon * 10 + *cp - '0'; ! 617: } ! 618: } ! 619: ! 620: /* decide if it is long or not (decimal case) */ ! 621: ! 622: /* if it is positive and fits in 15 bits, or negative and ! 623: and fits in 15 bits plus an extended sign, it is int; otherwise long */ ! 624: /* if there is an l or L following, all bets are off... */ ! 625: ! 626: { CONSZ v; ! 627: v = lastcon & ~077777L; ! 628: if( v == 0 || v == ~077777L ) yylval.intval = 0; ! 629: else yylval.intval = 1; ! 630: } ! 631: ! 632: islong: ! 633: /* finally, look for trailing L or l */ ! 634: if( (lxchar = getchar()) == 'L' || lxchar == 'l' ) yylval.intval = 1; ! 635: else ungetc( lxchar ,stdin); ! 636: return( ICON ); ! 637: } ! 638: ! 639: case A_DOT: ! 640: /* look for a dot: if followed by a digit, floating point */ ! 641: lxchar = getchar(); ! 642: if( lxmask[lxchar+1] & LEXDIG ){ ! 643: ungetc(lxchar,stdin); ! 644: lxget( '.', LEXDIG ); ! 645: goto getfp; ! 646: } ! 647: stwart = FUNNYNAME; ! 648: goto onechar; ! 649: ! 650: case A_STR: ! 651: /* string constant */ ! 652: lxmatch = '"'; ! 653: return( STRING ); ! 654: ! 655: case A_CC: ! 656: /* character constant */ ! 657: lxmatch = '\''; ! 658: lastcon = 0; ! 659: lxstr(0); ! 660: yylval.intval = 0; ! 661: return( ICON ); ! 662: ! 663: case A_BCD: ! 664: { ! 665: register i; ! 666: int j; ! 667: for( i=0; i<LXTSZ; ++i ){ ! 668: if( ( j = getchar() ) == '`' ) break; ! 669: if( j == '\n' ){ ! 670: uerror( "newline in BCD constant" ); ! 671: break; ! 672: } ! 673: yytext[i] = j; ! 674: } ! 675: yytext[i] = '\0'; ! 676: if( i>6 ) uerror( "BCD constant exceeds 6 characters" ); ! 677: # ifdef gcos ! 678: else strtob( yytext, &lastcon, i ); ! 679: lastcon >>= 6*(6-i); ! 680: # else ! 681: uerror( "gcos BCD constant illegal" ); ! 682: # endif ! 683: yylval.intval = 0; /* not long */ ! 684: return( ICON ); ! 685: } ! 686: ! 687: case A_SL: ! 688: /* / */ ! 689: if( (lxchar=getchar()) != '*' ) goto onechar; ! 690: lxcom(); ! 691: case A_WS: ! 692: continue; ! 693: ! 694: case A_NL: ! 695: ++lineno; ! 696: lxtitle(); ! 697: continue; ! 698: ! 699: case A_NOT: ! 700: /* ! */ ! 701: if( (lxchar=getchar()) != '=' ) goto onechar; ! 702: yylval.intval = NE; ! 703: return( EQUOP ); ! 704: ! 705: case A_MI: ! 706: /* - */ ! 707: if( (lxchar=getchar()) == '-' ){ ! 708: yylval.intval = DECR; ! 709: return( INCOP ); ! 710: } ! 711: if( lxchar != '>' ) goto onechar; ! 712: stwart = FUNNYNAME; ! 713: yylval.intval=STREF; ! 714: return( STROP ); ! 715: ! 716: case A_PL: ! 717: /* + */ ! 718: if( (lxchar=getchar()) != '+' ) goto onechar; ! 719: yylval.intval = INCR; ! 720: return( INCOP ); ! 721: ! 722: case A_AND: ! 723: /* & */ ! 724: if( (lxchar=getchar()) != '&' ) goto onechar; ! 725: return( yylval.intval = ANDAND ); ! 726: ! 727: case A_OR: ! 728: /* | */ ! 729: if( (lxchar=getchar()) != '|' ) goto onechar; ! 730: return( yylval.intval = OROR ); ! 731: ! 732: case A_LT: ! 733: /* < */ ! 734: if( (lxchar=getchar()) == '<' ){ ! 735: yylval.intval = LS; ! 736: return( SHIFTOP ); ! 737: } ! 738: if( lxchar != '=' ) goto onechar; ! 739: yylval.intval = LE; ! 740: return( RELOP ); ! 741: ! 742: case A_GT: ! 743: /* > */ ! 744: if( (lxchar=getchar()) == '>' ){ ! 745: yylval.intval = RS; ! 746: return(SHIFTOP ); ! 747: } ! 748: if( lxchar != '=' ) goto onechar; ! 749: yylval.intval = GE; ! 750: return( RELOP ); ! 751: ! 752: case A_EQ: ! 753: /* = */ ! 754: switch( lxchar = getchar() ){ ! 755: ! 756: case '=': ! 757: yylval.intval = EQ; ! 758: return( EQUOP ); ! 759: ! 760: case '+': ! 761: yylval.intval = ASG PLUS; ! 762: break; ! 763: ! 764: case '-': ! 765: yylval.intval = ASG MINUS; ! 766: ! 767: warn: ! 768: if( lxmask[ (lxchar=getchar())+1] & (LEXLET|LEXDIG|LEXDOT) ){ ! 769: werror( "ambiguous assignment: assignment op taken" ); ! 770: } ! 771: ungetc( lxchar ,stdin); ! 772: break; ! 773: ! 774: case '*': ! 775: yylval.intval = ASG MUL; ! 776: goto warn; ! 777: ! 778: case '/': ! 779: yylval.intval = ASG DIV; ! 780: break; ! 781: ! 782: case '%': ! 783: yylval.intval = ASG MOD; ! 784: break; ! 785: ! 786: case '&': ! 787: yylval.intval = ASG AND; ! 788: break; ! 789: ! 790: case '|': ! 791: yylval.intval = ASG OR; ! 792: break; ! 793: ! 794: case '^': ! 795: yylval.intval = ASG ER; ! 796: break; ! 797: ! 798: case '<': ! 799: if( (lxchar=getchar()) != '<' ){ ! 800: uerror( "=<%c illegal", lxchar ); ! 801: } ! 802: yylval.intval = ASG LS; ! 803: break; ! 804: ! 805: case '>': ! 806: if( (lxchar=getchar()) != '>' ){ ! 807: uerror( "=>%c illegal", lxchar ); ! 808: } ! 809: yylval.intval = ASG RS; ! 810: break; ! 811: ! 812: default: ! 813: goto onechar; ! 814: ! 815: } ! 816: ! 817: return( ASOP ); ! 818: ! 819: default: ! 820: cerror( "yylex error, character %03o (octal)", lxchar ); ! 821: ! 822: } ! 823: ! 824: /* ordinarily, repeat here... */ ! 825: cerror( "out of switch in yylex" ); ! 826: ! 827: } ! 828: ! 829: } ! 830: ! 831: struct lxrdope { ! 832: /* dope for reserved, in alphabetical order */ ! 833: ! 834: char *lxrch; /* name of reserved word */ ! 835: short lxract; /* reserved word action */ ! 836: short lxrval; /* value to be returned */ ! 837: } lxrdope[] = { ! 838: ! 839: "asm", AR_A, 0, ! 840: "auto", AR_CL, AUTO, ! 841: "break", AR_RW, BREAK, ! 842: "char", AR_TY, CHAR, ! 843: "case", AR_RW, CASE, ! 844: "continue", AR_RW, CONTINUE, ! 845: "double", AR_TY, DOUBLE, ! 846: "default", AR_RW, DEFAULT, ! 847: "do", AR_RW, DO, ! 848: "extern", AR_CL, EXTERN, ! 849: "else", AR_RW, ELSE, ! 850: "enum", AR_E, ENUM, ! 851: "for", AR_RW, FOR, ! 852: "float", AR_TY, FLOAT, ! 853: "fortran", AR_CL, FORTRAN, ! 854: "goto", AR_RW, GOTO, ! 855: "if", AR_RW, IF, ! 856: "int", AR_TY, INT, ! 857: "long", AR_TY, LONG, ! 858: "return", AR_RW, RETURN, ! 859: "register", AR_CL, REGISTER, ! 860: "switch", AR_RW, SWITCH, ! 861: "struct", AR_S, 0, ! 862: "sizeof", AR_RW, SIZEOF, ! 863: "short", AR_TY, SHORT, ! 864: "static", AR_CL, STATIC, ! 865: "typedef", AR_CL, TYPEDEF, ! 866: "unsigned", AR_TY, UNSIGNED, ! 867: "union", AR_U, 0, ! 868: "void", AR_TY, UNDEF, /* tymerge adds FTN */ ! 869: "while", AR_RW, WHILE, ! 870: "", 0, 0, /* to stop the search */ ! 871: }; ! 872: ! 873: lxres() { ! 874: /* check to see of yytext is reserved; if so, ! 875: /* do the appropriate action and return */ ! 876: /* otherwise, return -1 */ ! 877: ! 878: register c, ch; ! 879: register struct lxrdope *p; ! 880: ! 881: ch = yytext[0]; ! 882: ! 883: if( !islower(ch) ) return( -1 ); ! 884: ! 885: switch( ch ){ ! 886: ! 887: case 'a': ! 888: c=0; break; ! 889: case 'b': ! 890: c=2; break; ! 891: case 'c': ! 892: c=3; break; ! 893: case 'd': ! 894: c=6; break; ! 895: case 'e': ! 896: c=9; break; ! 897: case 'f': ! 898: c=12; break; ! 899: case 'g': ! 900: c=15; break; ! 901: case 'i': ! 902: c=16; break; ! 903: case 'l': ! 904: c=18; break; ! 905: case 'r': ! 906: c=19; break; ! 907: case 's': ! 908: c=21; break; ! 909: case 't': ! 910: c=26; break; ! 911: case 'u': ! 912: c=27; break; ! 913: case 'v': ! 914: c=29; break; ! 915: case 'w': ! 916: c=30; break; ! 917: ! 918: default: ! 919: return( -1 ); ! 920: } ! 921: ! 922: for( p= lxrdope+c; p->lxrch[0] == ch; ++p ){ ! 923: if( !strcmp( yytext, p->lxrch ) ){ /* match */ ! 924: switch( p->lxract ){ ! 925: ! 926: case AR_TY: ! 927: /* type word */ ! 928: stwart = instruct; ! 929: yylval.nodep = mkty( (TWORD)p->lxrval, 0, p->lxrval ); ! 930: return( TYPE ); ! 931: ! 932: case AR_RW: ! 933: { ! 934: extern int nsizeof; ! 935: ! 936: if (p->lxrval == SIZEOF) ! 937: ++nsizeof; ! 938: } ! 939: /* ordinary reserved word */ ! 940: return( yylval.intval = p->lxrval ); ! 941: ! 942: case AR_CL: ! 943: /* class word */ ! 944: yylval.intval = p->lxrval; ! 945: return( CLASS ); ! 946: ! 947: case AR_S: ! 948: /* struct */ ! 949: stwart = INSTRUCT|SEENAME|TAGNAME; ! 950: yylval.intval = INSTRUCT; ! 951: return( STRUCT ); ! 952: ! 953: case AR_U: ! 954: /* union */ ! 955: stwart = INUNION|SEENAME|TAGNAME; ! 956: yylval.intval = INUNION; ! 957: return( STRUCT ); ! 958: ! 959: case AR_E: ! 960: /* enums */ ! 961: stwart = SEENAME|TAGNAME; ! 962: return( yylval.intval = ENUM ); ! 963: ! 964: case AR_A: ! 965: /* asm */ ! 966: asm_esc = 1; /* warn the world! */ ! 967: lxget( ' ', LEXWS ); ! 968: if( getchar() != '(' ) goto badasm; ! 969: lxget( ' ', LEXWS ); ! 970: if( getchar() != '"' ) goto badasm; ! 971: # ifndef ONEPASS ! 972: # ifndef LINT ! 973: putchar(')'); ! 974: # endif ! 975: # endif ! 976: while( (c=getchar()) != '"' ){ ! 977: if( c=='\n' || c==EOF ) goto badasm; ! 978: # ifndef LINT ! 979: putchar(c); ! 980: # endif ! 981: } ! 982: lxget( ' ', LEXWS ); ! 983: if( getchar() != ')' ) goto badasm; ! 984: # ifndef LINT ! 985: putchar('\n'); ! 986: # endif ! 987: return( 0 ); ! 988: ! 989: badasm: ! 990: uerror( "bad asm construction" ); ! 991: return( 0 ); ! 992: ! 993: default: ! 994: cerror( "bad AR_?? action" ); ! 995: } ! 996: } ! 997: } ! 998: return( -1 ); ! 999: } ! 1000: ! 1001: extern int labelno; ! 1002: ! 1003: lxtitle(){ ! 1004: /* called after a newline; set linenumber and file name */ ! 1005: ! 1006: register c, val; ! 1007: register char *cp, *cq; ! 1008: ! 1009: for(;;){ /* might be several such lines in a row */ ! 1010: if( (c=getchar()) != '#' ){ ! 1011: if( c != EOF ) ungetc(c,stdin); ! 1012: #ifndef LINT ! 1013: if ( lastloc != PROG) return; ! 1014: cp = ftitle; ! 1015: cq = ititle; ! 1016: while ( *cp ) if (*cp++ != *cq++) return; ! 1017: if ( *cq ) return; ! 1018: psline(); ! 1019: #endif ! 1020: return; ! 1021: } ! 1022: ! 1023: lxget( ' ', LEXWS ); ! 1024: val = 0; ! 1025: for( c=getchar(); isdigit(c); c=getchar() ){ ! 1026: val = val*10+ c - '0'; ! 1027: } ! 1028: if( c == EOF ) ! 1029: continue; ! 1030: ungetc( c, stdin ); ! 1031: lineno = val; ! 1032: lxget( ' ', LEXWS ); ! 1033: if( (c=getchar()) != '\n' && c != EOF ){ ! 1034: for( cp=ftitle; c!=EOF && c!='\n'; c=getchar(),++cp ){ ! 1035: *cp = c; ! 1036: } ! 1037: *cp = '\0'; ! 1038: #ifndef LINT ! 1039: if (ititle[0] == '\0') { ! 1040: cp = ftitle; ! 1041: cq = ititle; ! 1042: while ( *cp ) ! 1043: *cq++ = *cp++; ! 1044: *cq = '\0'; ! 1045: *--cq = '\0'; ! 1046: #ifndef FLEXNAMES ! 1047: for ( cp = ititle+1; *(cp-1); cp += 8 ) { ! 1048: pstab(cp, N_SO); ! 1049: if (gdebug) printf("0,0,LL%d\n", labelno); ! 1050: } ! 1051: #else ! 1052: pstab(ititle+1, N_SO); ! 1053: if (gdebug) printf("0,0,LL%d\n", labelno); ! 1054: #endif ! 1055: ! 1056: *cq = '"'; ! 1057: printf("LL%d:\n", labelno++); ! 1058: } ! 1059: #endif ! 1060: } ! 1061: } ! 1062: } ! 1063: ! 1064: #ifdef FLEXNAMES ! 1065: #define NSAVETAB 4096 ! 1066: char *savetab; ! 1067: int saveleft; ! 1068: ! 1069: char * ! 1070: savestr(cp) ! 1071: register char *cp; ! 1072: { ! 1073: register int len; ! 1074: ! 1075: len = strlen(cp) + 1; ! 1076: if (len > saveleft) { ! 1077: saveleft = NSAVETAB; ! 1078: if (len > saveleft) ! 1079: saveleft = len; ! 1080: savetab = (char *)malloc(saveleft); ! 1081: if (savetab == 0) ! 1082: cerror("Ran out of memory (savestr)"); ! 1083: } ! 1084: strncpy(savetab, cp, len); ! 1085: cp = savetab; ! 1086: savetab += len; ! 1087: saveleft -= len; ! 1088: return (cp); ! 1089: } ! 1090: ! 1091: /* ! 1092: * The definition for the segmented hash tables. ! 1093: */ ! 1094: #define MAXHASH 20 ! 1095: #define HASHINC 1013 ! 1096: struct ht { ! 1097: char **ht_low; ! 1098: char **ht_high; ! 1099: int ht_used; ! 1100: } htab[MAXHASH]; ! 1101: ! 1102: char * ! 1103: hash(s) ! 1104: char *s; ! 1105: { ! 1106: register char **h; ! 1107: register i; ! 1108: register char *cp; ! 1109: struct ht *htp; ! 1110: int sh; ! 1111: ! 1112: /* ! 1113: * The hash function is a modular hash of ! 1114: * the sum of the characters with the sum ! 1115: * doubled before each successive character ! 1116: * is added. ! 1117: */ ! 1118: cp = s; ! 1119: i = 0; ! 1120: while (*cp) ! 1121: i = i*2 + *cp++; ! 1122: sh = (i&077777) % HASHINC; ! 1123: cp = s; ! 1124: /* ! 1125: * There are as many as MAXHASH active ! 1126: * hash tables at any given point in time. ! 1127: * The search starts with the first table ! 1128: * and continues through the active tables ! 1129: * as necessary. ! 1130: */ ! 1131: for (htp = htab; htp < &htab[MAXHASH]; htp++) { ! 1132: if (htp->ht_low == 0) { ! 1133: register char **hp = ! 1134: (char **) calloc(sizeof (char **), HASHINC); ! 1135: if (hp == 0) ! 1136: cerror("ran out of memory (hash)"); ! 1137: htp->ht_low = hp; ! 1138: htp->ht_high = htp->ht_low + HASHINC; ! 1139: } ! 1140: h = htp->ht_low + sh; ! 1141: /* ! 1142: * quadratic rehash increment ! 1143: * starts at 1 and incremented ! 1144: * by two each rehash. ! 1145: */ ! 1146: i = 1; ! 1147: do { ! 1148: if (*h == 0) { ! 1149: if (htp->ht_used > (HASHINC * 3)/4) ! 1150: break; ! 1151: htp->ht_used++; ! 1152: *h = savestr(cp); ! 1153: return (*h); ! 1154: } ! 1155: if (**h == *cp && strcmp(*h, cp) == 0) ! 1156: return (*h); ! 1157: h += i; ! 1158: i += 2; ! 1159: if (h >= htp->ht_high) ! 1160: h -= HASHINC; ! 1161: } while (i < HASHINC); ! 1162: } ! 1163: cerror("ran out of hash tables"); ! 1164: } ! 1165: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.