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

Defined functions

hash defined in line 1090; used 2 times
lxcom defined in line 430; used 1 times
lxenter defined in line 200; used 5 times
lxinit defined in line 268; used 1 times
lxmore defined in line 211; used 4 times
lxres defined in line 867; used 1 times
lxstr defined in line 312; used 3 times
lxtitle defined in line 991; used 2 times
mainp1 defined in line 75; never used
savestr defined in line 1057; used 3 times
yylex defined in line 494; 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 1088; used 2 times
lxcp defined in line 266; used 6 times
lxdope defined in line 229; used 5 times
lxgcp defined in line 62; used 4 times
lxmask defined in line 198; used 7 times
lxmatch defined in line 310; used 5 times
lxrdope defined in line 831; used 1 times
oldway defined in line 68; used 1 times
saveleft defined in line 1055; used 6 times
savetab defined in line 1054; 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 1084; used 2 times
lxdope defined in line 224; used 6 times
lxrdope defined in line 825; used 2 times
  • in line 873(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 193; never used
CSSZ defined in line 194; used 3 times
HASHINC defined in line 1083; 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 1082; used 2 times
NSAVETAB defined in line 1053; used 1 times
lxget defined in line 209; used 12 times
Last modified: 1986-04-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3200
Valid CSS Valid XHTML 1.0 Strict