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

Defined functions

hash defined in line 1093; used 2 times
lxcom defined in line 434; used 1 times
lxenter defined in line 204; used 5 times
lxinit defined in line 272; used 1 times
lxmore defined in line 215; used 4 times
lxres defined in line 871; used 1 times
lxstr defined in line 316; used 3 times
lxtitle defined in line 995; used 2 times
mainp1 defined in line 75; never used
savestr defined in line 1060; used 3 times
yylex defined in line 498; never used

Defined variables

asm_esc defined in line 13; used 1 times
fpe_sigvec defined in line 67; used 2 times
htab defined in line 1091; used 2 times
lxcp defined in line 270; used 6 times
lxdope defined in line 233; used 5 times
lxgcp defined in line 62; used 4 times
lxmask defined in line 202; used 7 times
lxmatch defined in line 314; used 5 times
lxrdope defined in line 835; used 1 times
oldway defined in line 68; used 1 times
saveleft defined in line 1058; used 6 times
savetab defined in line 1057; used 5 times
sccsid defined in line 2; never used
yytext defined in line 61; used 46 times

Defined struct's

ht defined in line 1087; used 2 times
lxdope defined in line 228; used 6 times
lxrdope defined in line 829; used 2 times
  • in line 877(2)

Defined macros

AR_A defined in line 53; used 1 times
AR_CL defined in line 49; used 6 times
AR_E defined in line 52; used 1 times
AR_RW defined in line 48; used 13 times
AR_S defined in line 50; used 1 times
AR_TY defined in line 47; used 8 times
AR_U defined in line 51; used 1 times
A_1C defined in line 19; used 15 times
A_AND defined in line 31; used 1 times
A_BCD defined in line 22; used 1 times
A_CC defined in line 21; used 1 times
A_DIG defined in line 18; used 1 times
A_DOT defined in line 24; used 1 times
A_EQ defined in line 27; used 1 times
A_ERR defined in line 16; used 1 times
A_GT defined in line 30; used 1 times
A_LET defined in line 17; used 1 times
A_LT defined in line 29; used 1 times
A_MI defined in line 26; used 1 times
A_NL defined in line 34; used 1 times
A_NOT defined in line 28; used 1 times
A_OR defined in line 32; used 1 times
A_PL defined in line 25; used 1 times
A_SL defined in line 23; used 1 times
A_STR defined in line 20; used 1 times
A_WS defined in line 33; used 1 times
CSMASK defined in line 197; never used
CSSZ defined in line 198; used 3 times
HASHINC defined in line 1086; used 6 times
LEXDIG defined in line 39; used 9 times
LEXDOT defined in line 43; used 2 times
LEXHEX defined in line 41; used 2 times
LEXLET defined in line 38; used 7 times
LEXOCT defined in line 40; used 3 times
LEXWS defined in line 42; used 6 times
LXTSZ defined in line 59; used 3 times
MAXHASH defined in line 1085; used 2 times
NSAVETAB defined in line 1056; used 1 times
lxget defined in line 213; used 12 times
Last modified: 1995-01-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 6270
Valid CSS Valid XHTML 1.0 Strict