|
|
1.1 ! root 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.