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