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