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: }