1: #ifndef lint
   2: static char sccsid[] = "@(#)y2.c	4.1	(Berkeley)	2/11/83";
   3: #endif not lint
   4: 
   5: # include "dextern"
   6: # define IDENTIFIER 257
   7: # define MARK 258
   8: # define TERM 259
   9: # define LEFT 260
  10: # define RIGHT 261
  11: # define BINARY 262
  12: # define PREC 263
  13: # define LCURLY 264
  14: # define C_IDENTIFIER 265  /* name followed by colon */
  15: # define NUMBER 266
  16: # define START 267
  17: # define TYPEDEF 268
  18: # define TYPENAME 269
  19: # define UNION 270
  20: # define ENDFILE 0
  21: 
  22:     /* communication variables between various I/O routines */
  23: 
  24: char *infile;   /* input file name */
  25: int numbval;    /* value of an input number */
  26: char tokname[NAMESIZE]; /* input token name */
  27: 
  28:     /* storage of names */
  29: 
  30: char cnames[CNAMSZ];    /* place where token and nonterminal names are stored */
  31: int cnamsz = CNAMSZ;    /* size of cnames */
  32: char * cnamp = cnames;  /* place where next name is to be put in */
  33: int ndefout = 3;  /* number of defined symbols output */
  34: 
  35:     /* storage of types */
  36: int ntypes; /* number of types defined */
  37: char * typeset[NTYPES]; /* pointers to type tags */
  38: 
  39:     /* symbol tables for tokens and nonterminals */
  40: 
  41: int ntokens = 0;
  42: struct toksymb tokset[NTERMS];
  43: int toklev[NTERMS];
  44: int nnonter = -1;
  45: struct ntsymb nontrst[NNONTERM];
  46: int start;  /* start symbol */
  47: 
  48:     /* assigned token type values */
  49: int extval = 0;
  50: 
  51:     /* input and output file descriptors */
  52: 
  53: FILE * finput;      /* yacc input file */
  54: FILE * faction;     /* file for saving actions */
  55: FILE * fdefine;     /* file for # defines */
  56: FILE * ftable;      /* y.tab.c file */
  57: FILE * ftemp;       /* tempfile to pass 2 */
  58: FILE * foutput;     /* y.output file */
  59: 
  60:     /* storage for grammar rules */
  61: 
  62: int mem0[MEMSIZE] ; /* production storage */
  63: int *mem = mem0;
  64: int nprod= 1;   /* number of productions */
  65: int *prdptr[NPROD]; /* pointers to descriptions of productions */
  66: int levprd[NPROD] ; /* precedence levels for the productions */
  67: 
  68: 
  69: setup(argc,argv) int argc; char *argv[];
  70: {   int i,j,lev,t, ty;
  71:     int c;
  72:     int *p;
  73:     char actname[8];
  74: 
  75:     foutput = NULL;
  76:     fdefine = NULL;
  77:     i = 1;
  78:     while( argc >= 2  && argv[1][0] == '-' ) {
  79:         while( *++(argv[1]) ){
  80:             switch( *argv[1] ){
  81:             case 'v':
  82:             case 'V':
  83:                 foutput = fopen(FILEU, "w" );
  84:                 if( foutput == NULL ) error( "cannot open y.output" );
  85:                 continue;
  86:             case 'D':
  87:             case 'd':
  88:                 fdefine = fopen( FILED, "w" );
  89:                 continue;
  90:             case 'o':
  91:             case 'O':
  92:                 fprintf( stderr, "`o' flag now default in yacc\n" );
  93:                 continue;
  94: 
  95:             case 'r':
  96:             case 'R':
  97:                 error( "Ratfor Yacc is dead: sorry...\n" );
  98: 
  99:             default:
 100:                 error( "illegal option: %c", *argv[1]);
 101:                 }
 102:             }
 103:         argv++;
 104:         argc--;
 105:         }
 106: 
 107:     ftable = fopen( OFILE, "w" );
 108:     if( ftable == NULL ) error( "cannot open table file" );
 109: 
 110:     ftemp = fopen( TEMPNAME, "w" );
 111:     faction = fopen( ACTNAME, "w" );
 112:     if( ftemp==NULL || faction==NULL ) error( "cannot open temp file" );
 113: 
 114:     if( argc < 2 || ((finput=fopen( infile=argv[1], "r" )) == NULL ) ){
 115:         error( "cannot open input file" );
 116:         }
 117: 
 118:     cnamp = cnames;
 119:     defin(0,"$end");
 120:     extval = 0400;
 121:     defin(0,"error");
 122:     defin(1,"$accept");
 123:     mem=mem0;
 124:     lev = 0;
 125:     ty = 0;
 126:     i=0;
 127: 
 128:     /* sorry -- no yacc parser here.....
 129: 		we must bootstrap somehow... */
 130: 
 131:     for( t=gettok();  t!=MARK && t!= ENDFILE; ){
 132:         switch( t ){
 133: 
 134:         case ';':
 135:             t = gettok();
 136:             break;
 137: 
 138:         case START:
 139:             if( (t=gettok()) != IDENTIFIER ){
 140:                 error( "bad %%start construction" );
 141:                 }
 142:             start = chfind(1,tokname);
 143:             t = gettok();
 144:             continue;
 145: 
 146:         case TYPEDEF:
 147:             if( (t=gettok()) != TYPENAME ) error( "bad syntax in %%type" );
 148:             ty = numbval;
 149:             for(;;){
 150:                 t = gettok();
 151:                 switch( t ){
 152: 
 153:                 case IDENTIFIER:
 154:                     if( (t=chfind( 1, tokname ) ) < NTBASE ) {
 155:                         j = TYPE( toklev[t] );
 156:                         if( j!= 0 && j != ty ){
 157:                             error( "type redeclaration of token %s",
 158:                                 tokset[t].name );
 159:                             }
 160:                         else SETTYPE( toklev[t],ty);
 161:                         }
 162:                     else {
 163:                         j = nontrst[t-NTBASE].tvalue;
 164:                         if( j != 0 && j != ty ){
 165:                             error( "type redeclaration of nonterminal %s",
 166:                                 nontrst[t-NTBASE].name );
 167:                             }
 168:                         else nontrst[t-NTBASE].tvalue = ty;
 169:                         }
 170:                 case ',':
 171:                     continue;
 172: 
 173:                 case ';':
 174:                     t = gettok();
 175:                     break;
 176:                 default:
 177:                     break;
 178:                     }
 179:                 break;
 180:                 }
 181:             continue;
 182: 
 183:         case UNION:
 184:             /* copy the union declaration to the output */
 185:             cpyunion();
 186:             t = gettok();
 187:             continue;
 188: 
 189:         case LEFT:
 190:         case BINARY:
 191:         case RIGHT:
 192:             ++i;
 193:         case TERM:
 194:             lev = t-TERM;  /* nonzero means new prec. and assoc. */
 195:             ty = 0;
 196: 
 197:             /* get identifiers so defined */
 198: 
 199:             t = gettok();
 200:             if( t == TYPENAME ){ /* there is a type defined */
 201:                 ty = numbval;
 202:                 t = gettok();
 203:                 }
 204: 
 205:             for(;;) {
 206:                 switch( t ){
 207: 
 208:                 case ',':
 209:                     t = gettok();
 210:                     continue;
 211: 
 212:                 case ';':
 213:                     break;
 214: 
 215:                 case IDENTIFIER:
 216:                     j = chfind(0,tokname);
 217:                     if( lev ){
 218:                         if( ASSOC(toklev[j]) ) error( "redeclaration of precedence of %s", tokname );
 219:                         SETASC(toklev[j],lev);
 220:                         SETPLEV(toklev[j],i);
 221:                         }
 222:                     if( ty ){
 223:                         if( TYPE(toklev[j]) ) error( "redeclaration of type of %s", tokname );
 224:                         SETTYPE(toklev[j],ty);
 225:                         }
 226:                     if( (t=gettok()) == NUMBER ){
 227:                         tokset[j].value = numbval;
 228:                         if( j < ndefout && j>2 ){
 229:                             error( "please define type number of %s earlier",
 230:                                 tokset[j].name );
 231:                             }
 232:                         t=gettok();
 233:                         }
 234:                     continue;
 235: 
 236:                     }
 237: 
 238:                 break;
 239:                 }
 240: 
 241:             continue;
 242: 
 243:         case LCURLY:
 244:             defout();
 245:             cpycode();
 246:             t = gettok();
 247:             continue;
 248: 
 249:         default:
 250:             error( "syntax error" );
 251: 
 252:             }
 253: 
 254:         }
 255: 
 256:     if( t == ENDFILE ){
 257:         error( "unexpected EOF before %%" );
 258:         }
 259: 
 260:     /* t is MARK */
 261: 
 262:     defout();
 263: 
 264:         fprintf( ftable,  "#define yyclearin yychar = -1\n" );
 265:         fprintf( ftable,  "#define yyerrok yyerrflag = 0\n" );
 266:         fprintf( ftable,  "extern int yychar;\nextern short yyerrflag;\n" );
 267:         fprintf( ftable,  "#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n" );
 268:         if( !ntypes ) fprintf( ftable,  "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n" );
 269:         fprintf( ftable,  "YYSTYPE yylval, yyval;\n" );
 270: 
 271:     prdptr[0]=mem;
 272:     /* added production */
 273:     *mem++ = NTBASE;
 274:     *mem++ = start;  /* if start is 0, we will overwrite with the lhs of the first rule */
 275:     *mem++ = 1;
 276:     *mem++ = 0;
 277:     prdptr[1]=mem;
 278: 
 279:     while( (t=gettok()) == LCURLY ) cpycode();
 280: 
 281:     if( t != C_IDENTIFIER ) error( "bad syntax on first rule" );
 282: 
 283:     if( !start ) prdptr[0][1] = chfind(1,tokname);
 284: 
 285:     /* read rules */
 286: 
 287:     while( t!=MARK && t!=ENDFILE ){
 288: 
 289:         /* process a rule */
 290: 
 291:         if( t == '|' ){
 292:             *mem++ = *prdptr[nprod-1];
 293:             }
 294:         else if( t == C_IDENTIFIER ){
 295:             *mem = chfind(1,tokname);
 296:             if( *mem < NTBASE ) error( "token illegal on LHS of grammar rule" );
 297:             ++mem;
 298:             }
 299:         else error( "illegal rule: missing semicolon or | ?" );
 300: 
 301:         /* read rule body */
 302: 
 303: 
 304:         t = gettok();
 305:     more_rule:
 306:         while( t == IDENTIFIER ) {
 307:             *mem = chfind(1,tokname);
 308:             if( *mem<NTBASE ) levprd[nprod] = toklev[*mem];
 309:             ++mem;
 310:             t = gettok();
 311:             }
 312: 
 313: 
 314:         if( t == PREC ){
 315:             if( gettok()!=IDENTIFIER) error( "illegal %%prec syntax" );
 316:             j = chfind(2,tokname);
 317:             if( j>=NTBASE)error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name);
 318:             levprd[nprod]=toklev[j];
 319:             t = gettok();
 320:             }
 321: 
 322:         if( t == '=' ){
 323:             levprd[nprod] |= ACTFLAG;
 324:             fprintf( faction, "\ncase %d:", nprod );
 325:             cpyact( mem-prdptr[nprod]-1 );
 326:             fprintf( faction, " break;" );
 327:             if( (t=gettok()) == IDENTIFIER ){
 328:                 /* action within rule... */
 329: 
 330:                 sprintf( actname, "$$%d", nprod );
 331:                 j = chfind(1,actname);  /* make it a nonterminal */
 332: 
 333:                 /* the current rule will become rule number nprod+1 */
 334:                 /* move the contents down, and make room for the null */
 335: 
 336:                 for( p=mem; p>=prdptr[nprod]; --p ) p[2] = *p;
 337:                 mem += 2;
 338: 
 339:                 /* enter null production for action */
 340: 
 341:                 p = prdptr[nprod];
 342: 
 343:                 *p++ = j;
 344:                 *p++ = -nprod;
 345: 
 346:                 /* update the production information */
 347: 
 348:                 levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
 349:                 levprd[nprod] = ACTFLAG;
 350: 
 351:                 if( ++nprod >= NPROD ) error( "more than %d rules", NPROD );
 352:                 prdptr[nprod] = p;
 353: 
 354:                 /* make the action appear in the original rule */
 355:                 *mem++ = j;
 356: 
 357:                 /* get some more of the rule */
 358: 
 359:                 goto more_rule;
 360:                 }
 361: 
 362:             }
 363: 
 364:         while( t == ';' ) t = gettok();
 365: 
 366:         *mem++ = -nprod;
 367: 
 368:         /* check that default action is reasonable */
 369: 
 370:         if( ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].tvalue ){
 371:             /* no explicit action, LHS has value */
 372:             register tempty;
 373:             tempty = prdptr[nprod][1];
 374:             if( tempty < 0 ) error( "must return a value, since LHS has a type" );
 375:             else if( tempty >= NTBASE ) tempty = nontrst[tempty-NTBASE].tvalue;
 376:             else tempty = TYPE( toklev[tempty] );
 377:             if( tempty != nontrst[*prdptr[nprod]-NTBASE].tvalue ){
 378:                 error( "default action causes potential type clash" );
 379:                 }
 380:             }
 381: 
 382:         if( ++nprod >= NPROD ) error( "more than %d rules", NPROD );
 383:         prdptr[nprod] = mem;
 384:         levprd[nprod]=0;
 385: 
 386:         }
 387: 
 388:     /* end of all rules */
 389: 
 390:     finact();
 391:     if( t == MARK ){
 392:         fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile );
 393:         while( (c=getc(finput)) != EOF ) putc( c, ftable );
 394:         }
 395:     fclose( finput );
 396:     }
 397: 
 398: finact(){
 399:     /* finish action routine */
 400: 
 401:     fclose(faction);
 402: 
 403:     fprintf( ftable, "# define YYERRCODE %d\n", tokset[2].value );
 404: 
 405:     }
 406: 
 407: defin( t, s ) register char  *s; {
 408: /*	define s to be a terminal if t=0
 409: 	or a nonterminal if t=1		*/
 410: 
 411:     register val;
 412: 
 413:     if (t) {
 414:         if( ++nnonter >= NNONTERM ) error("too many nonterminals, limit %d",NNONTERM);
 415:         nontrst[nnonter].name = cstash(s);
 416:         return( NTBASE + nnonter );
 417:         }
 418:     /* must be a token */
 419:     if( ++ntokens >= NTERMS ) error("too many terminals, limit %d",NTERMS );
 420:     tokset[ntokens].name = cstash(s);
 421: 
 422:     /* establish value for token */
 423: 
 424:     if( s[0]==' ' && s[2]=='\0' ) /* single character literal */
 425:         val = s[1];
 426:     else if ( s[0]==' ' && s[1]=='\\' ) { /* escape sequence */
 427:         if( s[3] == '\0' ){ /* single character escape sequence */
 428:             switch ( s[2] ){
 429:                      /* character which is escaped */
 430:             case 'n': val = '\n'; break;
 431:             case 'r': val = '\r'; break;
 432:             case 'b': val = '\b'; break;
 433:             case 't': val = '\t'; break;
 434:             case 'f': val = '\f'; break;
 435:             case '\'': val = '\''; break;
 436:             case '"': val = '"'; break;
 437:             case '\\': val = '\\'; break;
 438:             default: error( "invalid escape" );
 439:                 }
 440:             }
 441:         else if( s[2] <= '7' && s[2]>='0' ){ /* \nnn sequence */
 442:             if( s[3]<'0' || s[3] > '7' || s[4]<'0' ||
 443:                 s[4]>'7' || s[5] != '\0' ) error("illegal \\nnn construction" );
 444:             val = 64*s[2] + 8*s[3] + s[4] - 73*'0';
 445:             if( val == 0 ) error( "'\\000' is illegal" );
 446:             }
 447:         }
 448:     else {
 449:         val = extval++;
 450:         }
 451:     tokset[ntokens].value = val;
 452:     toklev[ntokens] = 0;
 453:     return( ntokens );
 454:     }
 455: 
 456: defout(){ /* write out the defines (at the end of the declaration section) */
 457: 
 458:     register int i, c;
 459:     register char *cp;
 460: 
 461:     for( i=ndefout; i<=ntokens; ++i ){
 462: 
 463:         cp = tokset[i].name;
 464:         if( *cp == ' ' ) ++cp;  /* literals */
 465: 
 466:         for( ; (c= *cp)!='\0'; ++cp ){
 467: 
 468:             if( islower(c) || isupper(c) || isdigit(c) || c=='_' );  /* VOID */
 469:             else goto nodef;
 470:             }
 471: 
 472:         fprintf( ftable, "# define %s %d\n", tokset[i].name, tokset[i].value );
 473:         if( fdefine != NULL ) fprintf( fdefine, "# define %s %d\n", tokset[i].name, tokset[i].value );
 474: 
 475:     nodef:  ;
 476:         }
 477: 
 478:     ndefout = ntokens+1;
 479: 
 480:     }
 481: 
 482: char *
 483: cstash( s ) register char *s; {
 484:     char *temp;
 485: 
 486:     temp = cnamp;
 487:     do {
 488:         if( cnamp >= &cnames[cnamsz] ) error("too many characters in id's and literals" );
 489:         else *cnamp++ = *s;
 490:         }  while ( *s++ );
 491:     return( temp );
 492:     }
 493: 
 494: gettok() {
 495:     register i, base;
 496:     static int peekline; /* number of '\n' seen in lookahead */
 497:     register c, match, reserve;
 498: 
 499: begin:
 500:     reserve = 0;
 501:     lineno += peekline;
 502:     peekline = 0;
 503:     c = getc(finput);
 504:     while( c==' ' || c=='\n' || c=='\t' || c=='\f' ){
 505:         if( c == '\n' ) ++lineno;
 506:         c=getc(finput);
 507:         }
 508:     if( c == '/' ){ /* skip comment */
 509:         lineno += skipcom();
 510:         goto begin;
 511:         }
 512: 
 513:     switch(c){
 514: 
 515:     case EOF:
 516:         return(ENDFILE);
 517:     case '{':
 518:         ungetc( c, finput );
 519:         return( '=' );  /* action ... */
 520:     case '<':  /* get, and look up, a type name (union member name) */
 521:         i = 0;
 522:         while( (c=getc(finput)) != '>' && c>=0 && c!= '\n' ){
 523:             tokname[i] = c;
 524:             if( ++i >= NAMESIZE ) --i;
 525:             }
 526:         if( c != '>' ) error( "unterminated < ... > clause" );
 527:         tokname[i] = '\0';
 528:         for( i=1; i<=ntypes; ++i ){
 529:             if( !strcmp( typeset[i], tokname ) ){
 530:                 numbval = i;
 531:                 return( TYPENAME );
 532:                 }
 533:             }
 534:         typeset[numbval = ++ntypes] = cstash( tokname );
 535:         return( TYPENAME );
 536: 
 537:     case '"':
 538:     case '\'':
 539:         match = c;
 540:         tokname[0] = ' ';
 541:         i = 1;
 542:         for(;;){
 543:             c = getc(finput);
 544:             if( c == '\n' || c == EOF )
 545:                 error("illegal or missing ' or \"" );
 546:             if( c == '\\' ){
 547:                 c = getc(finput);
 548:                 tokname[i] = '\\';
 549:                 if( ++i >= NAMESIZE ) --i;
 550:                 }
 551:             else if( c == match ) break;
 552:             tokname[i] = c;
 553:             if( ++i >= NAMESIZE ) --i;
 554:             }
 555:         break;
 556: 
 557:     case '%':
 558:     case '\\':
 559: 
 560:         switch(c=getc(finput)) {
 561: 
 562:         case '0':   return(TERM);
 563:         case '<':   return(LEFT);
 564:         case '2':   return(BINARY);
 565:         case '>':   return(RIGHT);
 566:         case '%':
 567:         case '\\':  return(MARK);
 568:         case '=':   return(PREC);
 569:         case '{':   return(LCURLY);
 570:         default:    reserve = 1;
 571:             }
 572: 
 573:     default:
 574: 
 575:         if( isdigit(c) ){ /* number */
 576:             numbval = c-'0' ;
 577:             base = (c=='0') ? 8 : 10 ;
 578:             for( c=getc(finput); isdigit(c) ; c=getc(finput) ){
 579:                 numbval = numbval*base + c - '0';
 580:                 }
 581:             ungetc( c, finput );
 582:             return(NUMBER);
 583:             }
 584:         else if( islower(c) || isupper(c) || c=='_' || c=='.' || c=='$' ){
 585:             i = 0;
 586:             while( islower(c) || isupper(c) || isdigit(c) || c=='_' || c=='.' || c=='$' ){
 587:                 tokname[i] = c;
 588:                 if( reserve && isupper(c) ) tokname[i] += 'a'-'A';
 589:                 if( ++i >= NAMESIZE ) --i;
 590:                 c = getc(finput);
 591:                 }
 592:             }
 593:         else return(c);
 594: 
 595:         ungetc( c, finput );
 596:         }
 597: 
 598:     tokname[i] = '\0';
 599: 
 600:     if( reserve ){ /* find a reserved word */
 601:         if( !strcmp(tokname,"term")) return( TERM );
 602:         if( !strcmp(tokname,"token")) return( TERM );
 603:         if( !strcmp(tokname,"left")) return( LEFT );
 604:         if( !strcmp(tokname,"nonassoc")) return( BINARY );
 605:         if( !strcmp(tokname,"binary")) return( BINARY );
 606:         if( !strcmp(tokname,"right")) return( RIGHT );
 607:         if( !strcmp(tokname,"prec")) return( PREC );
 608:         if( !strcmp(tokname,"start")) return( START );
 609:         if( !strcmp(tokname,"type")) return( TYPEDEF );
 610:         if( !strcmp(tokname,"union")) return( UNION );
 611:         error("invalid escape, or illegal reserved word: %s", tokname );
 612:         }
 613: 
 614:     /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
 615: 
 616:     c = getc(finput);
 617:     while( c==' ' || c=='\t'|| c=='\n' || c=='\f' || c== '/' ) {
 618:         if( c == '\n' ) ++peekline;
 619:         else if( c == '/' ){ /* look for comments */
 620:             peekline += skipcom();
 621:             }
 622:         c = getc(finput);
 623:         }
 624:     if( c == ':' ) return( C_IDENTIFIER );
 625:     ungetc( c, finput );
 626:     return( IDENTIFIER );
 627: }
 628: 
 629: fdtype( t ){ /* determine the type of a symbol */
 630:     register v;
 631:     if( t >= NTBASE ) v = nontrst[t-NTBASE].tvalue;
 632:     else v = TYPE( toklev[t] );
 633:     if( v <= 0 ) error( "must specify type for %s", (t>=NTBASE)?nontrst[t-NTBASE].name:
 634:             tokset[t].name );
 635:     return( v );
 636:     }
 637: 
 638: chfind( t, s ) register char *s; {
 639:     int i;
 640: 
 641:     if (s[0]==' ')t=0;
 642:     TLOOP(i){
 643:         if(!strcmp(s,tokset[i].name)){
 644:             return( i );
 645:             }
 646:         }
 647:     NTLOOP(i){
 648:         if(!strcmp(s,nontrst[i].name)) {
 649:             return( i+NTBASE );
 650:             }
 651:         }
 652:     /* cannot find name */
 653:     if( t>1 )
 654:         error( "%s should have been defined earlier", s );
 655:     return( defin( t, s ) );
 656:     }
 657: 
 658: cpyunion(){
 659:     /* copy the union declaration to the output, and the define file if present */
 660: 
 661:     int level, c;
 662:     fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile );
 663:     fprintf( ftable, "typedef union " );
 664:     if( fdefine ) fprintf( fdefine, "\ntypedef union " );
 665: 
 666:     level = 0;
 667:     for(;;){
 668:         if( (c=getc(finput)) < 0 ) error( "EOF encountered while processing %%union" );
 669:         putc( c, ftable );
 670:         if( fdefine ) putc( c, fdefine );
 671: 
 672:         switch( c ){
 673: 
 674:         case '\n':
 675:             ++lineno;
 676:             break;
 677: 
 678:         case '{':
 679:             ++level;
 680:             break;
 681: 
 682:         case '}':
 683:             --level;
 684:             if( level == 0 ) { /* we are finished copying */
 685:                 fprintf( ftable, " YYSTYPE;\n" );
 686:                 if( fdefine ) fprintf( fdefine, " YYSTYPE;\nextern YYSTYPE yylval;\n" );
 687:                 return;
 688:                 }
 689:             }
 690:         }
 691:     }
 692: 
 693: cpycode(){ /* copies code between \{ and \} */
 694: 
 695:     int c;
 696:     c = getc(finput);
 697:     if( c == '\n' ) {
 698:         c = getc(finput);
 699:         lineno++;
 700:         }
 701:     fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile );
 702:     while( c>=0 ){
 703:         if( c=='\\' )
 704:             if( (c=getc(finput)) == '}' ) return;
 705:             else putc('\\', ftable );
 706:         if( c=='%' )
 707:             if( (c=getc(finput)) == '}' ) return;
 708:             else putc('%', ftable );
 709:         putc( c , ftable );
 710:         if( c == '\n' ) ++lineno;
 711:         c = getc(finput);
 712:         }
 713:     error("eof before %%}" );
 714:     }
 715: 
 716: skipcom(){ /* skip over comments */
 717:     register c, i=0;  /* i is the number of lines skipped */
 718: 
 719:     /* skipcom is called after reading a / */
 720: 
 721:     if( getc(finput) != '*' ) error( "illegal comment" );
 722:     c = getc(finput);
 723:     while( c != EOF ){
 724:         while( c == '*' ){
 725:             if( (c=getc(finput)) == '/' ) return( i );
 726:             }
 727:         if( c == '\n' ) ++i;
 728:         c = getc(finput);
 729:         }
 730:     error( "EOF inside comment" );
 731:     /* NOTREACHED */
 732:     }
 733: 
 734: cpyact(offset){ /* copy C action to the next ; or closing } */
 735:     int brac, c, match, j, s, tok;
 736: 
 737:     fprintf( faction, "\n# line %d \"%s\"\n", lineno, infile );
 738: 
 739:     brac = 0;
 740: 
 741: loop:
 742:     c = getc(finput);
 743: swt:
 744:     switch( c ){
 745: 
 746: case ';':
 747:         if( brac == 0 ){
 748:             putc( c , faction );
 749:             return;
 750:             }
 751:         goto lcopy;
 752: 
 753: case '{':
 754:         brac++;
 755:         goto lcopy;
 756: 
 757: case '$':
 758:         s = 1;
 759:         tok = -1;
 760:         c = getc(finput);
 761:         if( c == '<' ){ /* type description */
 762:             ungetc( c, finput );
 763:             if( gettok() != TYPENAME ) error( "bad syntax on $<ident> clause" );
 764:             tok = numbval;
 765:             c = getc(finput);
 766:             }
 767:         if( c == '$' ){
 768:             fprintf( faction, "yyval");
 769:             if( ntypes ){ /* put out the proper tag... */
 770:                 if( tok < 0 ) tok = fdtype( *prdptr[nprod] );
 771:                 fprintf( faction, ".%s", typeset[tok] );
 772:                 }
 773:             goto loop;
 774:             }
 775:         if( c == '-' ){
 776:             s = -s;
 777:             c = getc(finput);
 778:             }
 779:         if( isdigit(c) ){
 780:             j=0;
 781:             while( isdigit(c) ){
 782:                 j= j*10+c-'0';
 783:                 c = getc(finput);
 784:                 }
 785: 
 786:             j = j*s - offset;
 787:             if( j > 0 ){
 788:                 error( "Illegal use of $%d", j+offset );
 789:                 }
 790: 
 791:             fprintf( faction, "yypvt[-%d]", -j );
 792:             if( ntypes ){ /* put out the proper tag */
 793:                 if( j+offset <= 0 && tok < 0 ) error( "must specify type of $%d", j+offset );
 794:                 if( tok < 0 ) tok = fdtype( prdptr[nprod][j+offset] );
 795:                 fprintf( faction, ".%s", typeset[tok] );
 796:                 }
 797:             goto swt;
 798:             }
 799:         putc( '$' , faction );
 800:         if( s<0 ) putc('-', faction );
 801:         goto swt;
 802: 
 803: case '}':
 804:         if( --brac ) goto lcopy;
 805:         putc( c, faction );
 806:         return;
 807: 
 808: 
 809: case '/':   /* look for comments */
 810:         putc( c , faction );
 811:         c = getc(finput);
 812:         if( c != '*' ) goto swt;
 813: 
 814:         /* it really is a comment */
 815: 
 816:         putc( c , faction );
 817:         c = getc(finput);
 818:         while( c != EOF ){
 819:             while( c=='*' ){
 820:                 putc( c , faction );
 821:                 if( (c=getc(finput)) == '/' ) goto lcopy;
 822:                 }
 823:             putc( c , faction );
 824:             if( c == '\n' )++lineno;
 825:             c = getc(finput);
 826:             }
 827:         error( "EOF inside comment" );
 828: 
 829: case '\'':  /* character constant */
 830:         match = '\'';
 831:         goto string;
 832: 
 833: case '"':   /* character string */
 834:         match = '"';
 835: 
 836:     string:
 837: 
 838:         putc( c , faction );
 839:         while( c=getc(finput) ){
 840: 
 841:             if( c=='\\' ){
 842:                 putc( c , faction );
 843:                 c=getc(finput);
 844:                 if( c == '\n' ) ++lineno;
 845:                 }
 846:             else if( c==match ) goto lcopy;
 847:             else if( c=='\n' ) error( "newline in string or char. const." );
 848:             putc( c , faction );
 849:             }
 850:         error( "EOF in string or character constant" );
 851: 
 852: case EOF:
 853:         error("action does not terminate" );
 854: 
 855: case '\n':  ++lineno;
 856:         goto lcopy;
 857: 
 858:         }
 859: 
 860: lcopy:
 861:     putc( c , faction );
 862:     goto loop;
 863:     }

Defined functions

chfind defined in line 638; used 8 times
cpyact defined in line 734; used 1 times
cpycode defined in line 693; used 2 times
cpyunion defined in line 658; used 1 times
cstash defined in line 482; used 4 times
defin defined in line 407; used 4 times
defout defined in line 456; used 2 times
fdtype defined in line 629; used 2 times
finact defined in line 398; used 1 times
gettok defined in line 494; used 22 times
setup defined in line 69; used 1 times
skipcom defined in line 716; used 2 times

Defined variables

cnames defined in line 30; used 3 times
cnamp defined in line 32; used 4 times
cnamsz defined in line 31; used 1 times
extval defined in line 49; used 2 times
infile defined in line 24; used 5 times
levprd defined in line 66; used 22 times
mem defined in line 63; used 43 times
mem0 defined in line 62; used 8 times
ndefout defined in line 33; used 3 times
nontrst defined in line 45; used 31 times
nprod defined in line 64; used 58 times
ntokens defined in line 41; used 21 times
ntypes defined in line 36; used 6 times
numbval defined in line 25; used 9 times
prdptr defined in line 65; used 44 times
sccsid defined in line 2; never used
start defined in line 46; used 3 times
toklev defined in line 43; used 25 times
tokname defined in line 26; used 30 times
tokset defined in line 42; used 30 times
typeset defined in line 37; used 4 times

Defined macros

BINARY defined in line 11; used 3 times
C_IDENTIFIER defined in line 14; used 3 times
ENDFILE defined in line 20; used 4 times
IDENTIFIER defined in line 6; used 5 times
LCURLY defined in line 13; used 2 times
LEFT defined in line 9; used 2 times
MARK defined in line 7; used 4 times
NUMBER defined in line 15; used 2 times
PREC defined in line 12; used 3 times
RIGHT defined in line 10; used 2 times
START defined in line 16; used 1 times
TERM defined in line 8; used 4 times
TYPEDEF defined in line 17; used 1 times
TYPENAME defined in line 18; used 5 times
UNION defined in line 19; used 1 times
Last modified: 1983-02-12
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2800
Valid CSS Valid XHTML 1.0 Strict