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