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