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