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