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