|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.