1 #ifndef lint 2 static char sccsid[] = "@(#)y2.c 4.1 (Berkeley) 02/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 } 864