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

Defined functions

chfind defined in line 640; used 8 times
cpyact defined in line 736; used 1 times
cpycode defined in line 695; used 2 times
cpyunion defined in line 660; used 1 times
cstash defined in line 483; used 4 times
defin defined in line 408; used 4 times
defout defined in line 457; used 2 times
fdtype defined in line 630; used 2 times
finact defined in line 399; used 1 times
gettok defined in line 495; used 22 times
setup defined in line 69; used 1 times
skipcom defined in line 718; 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: 1995-05-12
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2534
Valid CSS Valid XHTML 1.0 Strict