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

Defined functions

chfind defined in line 634; used 8 times
cpyact defined in line 730; used 1 times
cpycode defined in line 689; used 2 times
cpyunion defined in line 654; used 1 times
cstash defined in line 478; used 3 times
defin defined in line 403; used 4 times
defout defined in line 452; used 2 times
fdtype defined in line 625; used 2 times
finact defined in line 394; used 1 times
gettok defined in line 490; used 22 times
setup defined in line 65; used 1 times
skipcom defined in line 712; used 2 times

Defined variables

cnames defined in line 26; used 3 times
cnamp defined in line 28; used 4 times
cnamsz defined in line 27; used 1 times
extval defined in line 45; used 2 times
infile defined in line 20; used 5 times
levprd defined in line 62; used 8 times
mem defined in line 59; used 21 times
mem0 defined in line 58; used 2 times
ndefout defined in line 29; used 3 times
nnonter defined in line 40; used 3 times
nontrst defined in line 41; used 11 times
nprod defined in line 60; used 25 times
ntokens defined in line 37; used 7 times
ntypes defined in line 32; used 6 times
numbval defined in line 21; used 9 times
prdptr defined in line 61; used 14 times
start defined in line 42; used 3 times
toklev defined in line 39; used 12 times
tokname defined in line 22; used 30 times
tokset defined in line 38; used 13 times
typeset defined in line 33; used 4 times

Defined macros

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