|
|
1.1 root 1: /*
2: * LALR-1 parser generator
3: * read in rules
4: * - read in definitions
5: * - gobble rules
6: * - copy anything complicated to the output
7: */
8: #include "yacc.h"
9: #include <action.h>
10:
11: struct sym *defsym(), *elook();
12: YYSTYPE yylval;
13: struct
14: {
15: int lex;
16: YYSTYPE val;
17: } last = {-1};
18:
19: readrules()
20: {
21: struct sym *saccept, *seof, *serror;
22: int t, t1, t2, nt, asc, pred, tokno, toktyp, c;
23: struct sym *sp;
24:
25:
26: #if DGC
27: printf("Read rules\n");
28: #endif
29: saccept = defsym("$accept", TNTERM);
30: seof = defsym("$end", TTERM);
31: serror = defsym("error", TTERM);
32: seof->s_val = YYEOFVAL;
33: serror->s_val = YYERRVAL;
34:
35: /* part 1 - read in rules */
36: while( (t = yylex()) != MARK ) {
37: #if DGC
38: printf("t = %d\n", t);
39: #endif
40: switch( t ) {
41:
42: case EOF:
43: yyerror(FATAL, "end of file in definition section\n");
44: break; /* stupid C switch statement */
45:
46: case START:
47: if( yylex() != IDENT )
48: yyerror(!FATAL, "bad %start syntax");
49: else {
50: defsym(yylval.sptr->s_name,TNTERM);
51: startsym = yylval.sptr->s_no;
52: }
53: break;
54:
55: case UNION:
56: copyunion();
57: break;
58:
59: case TOKEN:
60: case LEFT:
61: case RIGHT:
62: case NONASSOC:
63: asc = t-TOKEN;
64: if( t!=TOKEN )
65: pred = predlev++;
66: else
67: pred = UNKNOWN;
68:
69: case TYPE:
70: toktyp = UINT;
71: while( (t1 = yylex()) == IDENT || t1 == T_IDENT ) {
72: if( t1==T_IDENT ) {
73: toktyp = yylval.sptr->s_no;
74: continue;
75: }
76: sp = yylval.sptr;
77: if( (t2 = yylex()) == INTEGER )
78: if( t==TYPE ) /*MWC DSC*/
79: yyerror(!FATAL, "token value assignment not allowed for %type");
80: else
81: tokno = yylval.ival;
82: else {
83: backup(t2);
84: if( sp->s_name[0]!='\'' )
85: tokno = tno++;
86: else
87: tokno = UNKNOWN;
88: }
89: if( t==TYPE && toktyp==UINT )
90: yyerror(!FATAL,"Type id needed for %%type");
91: switch( t ) {
92: case TOKEN:
93: case LEFT:
94: case RIGHT:
95: case NONASSOC: /* C needs ranges on case */
96:
97: deftok(sp, toktyp, asc, pred, tokno);
98: break;
99:
100: case TYPE:
101: defnttyp(sp, toktyp);
102: break;
103: }
104: if( (t2 = yylex()) != COMMA ) backup(t2);
105: }
106: backup(t1);
107: break;
108: default:
109: yyerror(FATAL, "unexpected symbol in definition section",
110: t);
111: }
112: }
113:
114: wrtdefs();
115: wrthdr();
116: /* part 2 - read in rules */
117: prdptr[0] = (struct prod *)yalloc(1, sizeof *prdptr[0] + 3 * sizeof *prdptr[0]->p_right);
118: prdptr[0]->p_prodno = 0;
119: prdptr[0]->p_prc = prdptr[0]->p_ass = UNKNOWN;
120: prdptr[0]->p_left = -saccept->s_no;
121: prdptr[0]->p_right[0] = startsym;
122: prdptr[0]->p_right[1] = seof->s_no;
123: prdptr[0]->p_right[2] = -1;
124: nprod = 1;
125: while( (t = yylex()) == C_IDENT ) {
126: defsym(yylval.sptr->s_name, TNTERM);
127: nt = yylval.sptr->s_no;
128: while( getrule(nt) );
129: }
130: if( t==MARK ) { /* gobble up rest of file */
131: linepos(tabout);
132: while( (c = llgetc()) != EOF )
133: putc(c, tabout);
134: } else if( t!=EOF )
135: yyerror(FATAL, "bad rule syntax");
136: wrtnames();
137: fclose(defin);
138: fclose(actout);
139: }
140:
141: /*
142: * lexical input reader
143: * - copy comments and percent curlies to the output w/o change
144: * - lookup the list of reserved keywords
145: * - enter identifiers and character constants in the symbol table
146: * character constants are special because they start with a apostrophe
147: * as do internally generated non terminals
148: * - the "value" of the token read is left in the global variable yylval
149: * this is either a symbol table pointer or an integer (for NUMBER)
150: */
151:
152: yylex()
153: {
154: int c, i, lesk;
155: char s[SYMSIZE];
156:
157: if( last.lex != -1 ) {
158: yylval = last.val;
159: lesk = last.lex;
160: last.lex = -1;
161: return( lesk );
162: }
163: last.lex = -1;
164:
165: read:
166: while( whitespace( c = llgetc() ) ) ;
167: switch( c ) {
168: case '|':
169: return( VBAR );
170:
171: case ';':
172: return( SEMICOLON );
173:
174:
175: case '/':
176: if( (c = llgetc()) != '*' )
177: goto error;
178: copycomment("*/", NULL, 0); /* write to the rathole */
179: goto read;
180:
181: case '<':
182: gettype(s);
183: yylval.sptr = defsym(s, TTYPE);
184: return( T_IDENT );
185:
186: case '{':
187: return( LBRAC );
188:
189: case ',':
190: return( COMMA );
191:
192: case '%':
193: if( (c = llgetc()) == '{' ) {
194: linepos(tabout);
195: copycomment("%}", tabout, 0);
196: goto read;
197: } else if( c=='%' )
198: return( MARK );
199: llungetc(c);
200: getword(s);
201: for( i=0; restab[i].r_name ; i++ )
202: if( strcmp(s, restab[i].r_name)==0 )
203: return( restab[i].r_val );
204: yyerror(!FATAL|SKIP, "illegal \"%%keyword\"");
205: goto read;
206:
207: case '\'':
208: c = readchar();
209: if( llgetc() != '\'' ) {
210: yyerror(!FATAL|SKIP, "bad character constant\n");
211: goto read;
212: }
213: sprintf(s, "%s", prsym(c));
214: yylval.sptr = defsym(s, TTERM);
215: yylval.sptr->s_val = c;
216: return( IDENT );
217:
218: case EOF:
219: return(EOF);
220: default:
221: if( digit(c) ) {
222: yylval.ival = readnum(c);
223: return( INTEGER );
224: } else if( alpha(c) ) {
225: llungetc(c);
226: getword(s);
227: yylval.sptr = defsym(s, UNKNOWN);
228: while( whit2space(c = llgetc()) );
229: if( c==':' )
230: return( C_IDENT );
231: llungetc(c);
232: return(IDENT);
233: } else {
234: error:
235: yyerror(!FATAL|SKIP, "illegal character %c", c);
236: goto read;
237: }
238: }
239: }
240:
241: /* read a production (the bi's for a <- b0 .. bn ) until a ';' or '|' */
242:
243: getrule(nt)
244: int nt;
245: {
246: int precused, t, n, size, actpres;
247: char s[SYMSIZE];
248: register struct prod *pp;
249: register struct sym *sp;
250: #ifdef IAPX86 /* workaround cc1 'too many stores' bug */
251: char *tmp;
252: #endif
253:
254: nitprod->p_left = -nt;
255: nitprod->p_prc = nitprod->p_ass = UNKNOWN;
256: actpres = n = precused = 0;
257: t = yylex();
258: while( t==PREC || t==IDENT || t==LBRAC ) {
259: switch( t ) {
260: case PREC:
261: t = yylex();
262: sp = yylval.sptr;
263: if( sp->s_genre!=TTERM || sp->s_prc<0 )
264: yyerror(!FATAL,"bad %prec construct");
265: else {
266: nitprod->p_prc = sp->s_prc;
267: nitprod->p_ass = sp->s_ass;
268: precused++;
269: }
270: break;
271:
272: case IDENT:
273: sp = yylval.sptr;
274: if( sp->s_genre == UNKNOWN )
275: defsym(sp->s_name, TNTERM);
276: if( sp->s_genre==TTERM && sp->s_ass>UNASSOC &&
277: !precused ) {
278: nitprod->p_ass = sp->s_ass;
279: nitprod->p_prc = sp->s_prc;
280: }
281: if( n >= MAXPRODL-1 )
282: yyerror(FATAL, "production too long");
283: nitprod->p_right[n++] = sp->s_no;
284: break;
285:
286: case LBRAC:
287: cpyact(n, ntrmptr[nt-NTBASE]);
288: if( (t = yylex()) == IDENT ) { /* action inside rule */
289: pp = (struct prod *)yalloc(1, sizeof *pp + sizeof(int));
290: sprintf(s, "$$%d", nprod);
291: sp = defsym(s, TNTERM);
292: pp->p_prodno = nprod;
293: pp->p_prc = pp->p_ass = UNKNOWN;
294: pp->p_left = -sp->s_no;
295: pp->p_right[0] = -1;
296: bounded(nprod, maxprod, "productions");
297: prdptr[nprod++] = pp;
298: nitprod->p_right[n++] = sp->s_no;
299: } else
300: actpres++;
301: continue;
302: }
303: t = yylex();
304: }
305: if( !actpres && ntrmptr[nt-NTBASE]->s_type>=0 ) {
306: if( n==0 )
307: yyerror(!FATAL, "must return value since lhs has type\n");
308: #ifndef IAPX86 /* work around 'too many stores bug'. */
309: else
310: if (elook(*nitprod->p_right)->s_type !=
311: ntrmptr[nt-NTBASE]->s_type )
312: yyerror(WARNING, "default action may cause type clash");
313: #else
314: else {
315: tmp = elook(*nitprod->p_right);
316: if (tmp->s_type != ntrmptr[nt-NTBASE]->s_type )
317: yyerror(WARNING, "default action may cause type clash");
318: }
319: #endif /* cc bug workaround */
320: }
321: if( t!=VBAR && t!=SEMICOLON )
322: yyerror(FATAL, "rule terminator not ';' or '|'");
323: bounded(nprod, maxprod, "productions");
324: nitprod->p_prodno = nprod;
325: nitprod->p_right[n++] = -1;
326: size = sizeof *nitprod + n * sizeof(int);
327: copyb(nitprod, prdptr[nprod++] = (struct prod *)yalloc(1, size), size);
328: return( t==VBAR );
329: }
330:
331: struct sym *
332: defsym(s, typ)
333: char *s;
334: {
335: register struct sym *sp;
336: register struct genre *gp; /* MWC DSC */
337: register i;
338: int start;
339:
340: i = start = hash(s);
341: while( (sp = symtab[i])!=NULL && strcmp(s, sp->s_name) )
342: if( (i = (i+1) % maxsym ) == start ) /* MWC DSC */
343: yyerror(FATAL, "symbol table overflow");
344:
345: if( sp==NULL ) {
346: #if DEBUG
347: printf("defsym: %s new\n", s);
348: #endif
349: sp = symtab[i] = (struct sym *)yalloc(1, sizeof *sp);
350: #ifdef DAVELIB
351: sprintf(sp->s_name, "%.?s", SYMSIZE-1, s);
352: #else
353: sprintf(sp->s_name, "%.*s", SYMSIZE-1, s);
354: #endif
355: sp->s_no = -1;
356: sp->s_prc = sp->s_ass = UNKNOWN;
357: sp->s_type = UINT;
358: sp->s_genre = UNKNOWN;
359: }
360: if( typ!=UNKNOWN && sp->s_genre!=typ ) {
361: if( sp->s_genre!=UNKNOWN )
362: yyerror(FATAL, "internal error - type redefinition");
363: sp->s_genre = typ;
364: if( (sp->s_no = gtab[typ].g_ordno++) >= gtab[typ].g_maxord )
365: yyerror(FATAL, "too many %s, actual limit %d",
366: gtab[typ].g_name, gtab[typ].g_maxord);
367: gp = >ab[typ];
368: (*gp->g_sptr) [ sp->s_no ] = sp;
369: sp->s_no += gp->g_base;
370: #if DEBUG
371: printf("defsym: %s %d %d\n", s, typ, sp->s_no);
372: #endif
373: }
374: return(sp);
375: }
376:
377: int hash(s) /* Could have more scatter on 32-bit int machine */
378: register char *s;
379: {
380: register unsigned sum;
381: if( (sum = *s) == '\0' )
382: return(0);
383: do {
384: sum += s[0] | s[1]<<8;
385: s += 2;
386: } while( s[-1]!='\0' && s[0]!='\0' );
387: return( sum % maxsym ); /* MWC DSC */
388: }
389:
390: gettype(s)
391: char *s;
392: {
393: register c;
394:
395: while( whit2space( c = llgetc() ) )
396: ; /* just for howard */
397: llungetc(c);
398: getword(s);
399: if( llgetc()!='>' ) yyerror(!FATAL|SKIP, "missing '>' in type ref");
400: }
401:
402: deftok(sp, typ, asc, pred, tokno)
403: struct sym *sp;
404: int typ, asc, pred, tokno;
405: {
406: if( yydebug )
407: fprintf(listout, "deftok(%s) = type %d, ass %d, pred %d, # %d\n",
408: sp->s_name, typ, asc, pred, tokno);
409: if( typ!=UNKNOWN ) sp->s_type = typ;
410: if( asc!=UNKNOWN ) sp->s_ass = asc;
411: if( pred!=UNKNOWN ) sp->s_prc = pred;
412: if( tokno!=UNKNOWN ) sp->s_val = tokno;
413: defsym(sp->s_name, TTERM);
414: }
415:
416: wrtdefs()
417: {
418: register i;
419: register struct sym *sp;
420:
421: for(i=0; i<nterm; i++) {
422: sp = trmptr[i];
423: if( alpha(sp->s_name[0]) && strcmp(sp->s_name, "error") )
424: fprintf(fhdr, "#define %s %d\n", sp->s_name,
425: sp->s_val);
426: }
427: if (ntype==0)
428: fprintf(fhdr, "typedef int YYSTYPE;\n");
429: fprintf(fhdr, "#ifdef YYTNAMES\n");
430: fprintf(fhdr, "extern readonly struct yytname\n{\n");
431: fprintf(fhdr, "\tchar\t*tn_name;\n\tint\ttn_val;\n} yytnames[%d];\n",
432: nterm+1);
433: fprintf(fhdr, "#endif\n");
434: fprintf(fhdr, "extern YYSTYPE yylval;\n");
435: fclose(fhdr);
436: }
437:
438: wrthdr()
439: {
440: fprintf(tabout, "\n#include \"%s\"\n", ytabh);
441: fprintf(tabout, "#define YYCLEARIN yychar = -1000\n");
442: fprintf(tabout, "#define YYERROK yyerrflag = 0\n");
443: fprintf(tabout, "extern int yychar;\n");
444: fprintf(tabout, "extern short yyerrflag;\n");
445: fprintf(tabout,"#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n");
446: fprintf(tabout,"#endif\n");
447: fprintf(tabout, "YYSTYPE yyval, yylval;\n");
448: }
449:
450: wrtnames()
451: {
452: register i;
453: register char *sp;
454:
455: fprintf(tabout, "#ifdef YYTNAMES\n");
456: fprintf(tabout, "readonly struct yytname yytnames[%d] =\n{\n", nterm+1);
457: for(i=0; i<nterm; i++) {
458: fprintf(tabout, "\t\"");
459: sp = trmptr[i]->s_name;
460: while( *sp ) {
461: if( *sp=='\\' || *sp=='"' )
462: putc('\\', tabout);
463: putc(*sp, tabout);
464: sp++;
465: }
466: fprintf(tabout, "\", %d, \n", trmptr[i]->s_val);
467: }
468: fprintf(tabout, "\tNULL\n} ;\n");
469: fprintf(tabout, "#endif\n");
470: }
471:
472: defnttyp(sp, typ)
473: struct sym *sp;
474: {
475: sp->s_type = typ;
476: }
477:
478: cpyact(nel, ntp)
479: struct sym *ntp;
480: {
481: register c, istyp, n;
482: int accolade, sign, c1;
483: char s[SYMSIZE];
484: struct sym *sp;
485:
486: accolade = 1;
487: fprintf(actout, "\ncase %d: {\n", nprod);
488: linepos(actout);
489:
490: do {
491: c = llgetc();
492: switch( c ) {
493: case EOF:
494: yyerror(FATAL, "end of file in action");
495: break;
496:
497: case '{':
498: accolade++;
499: break;
500:
501: case '}':
502: accolade--;
503: break;
504:
505: case '/':
506: if( (c1 = llgetc()) == '*' ) {
507: fprintf(actout, "/*");
508: copycomment("*/", actout, 0);
509: fprintf(actout, "*/");
510: continue;
511: }
512: llungetc(c1);
513: break;
514:
515: case '"':
516: putc('"', actout);
517: copycomment("\"", actout, 1);
518: putc('"', actout);
519: continue;
520:
521: case '\'':
522: putc('\'', actout);
523: copycomment("'", actout, 1);
524: putc('\'', actout);
525: continue;
526:
527: case '$':
528: if( istyp = (c = llgetc())=='<' )
529: gettype(s);
530: else
531: llungetc(c);
532: switch( c = llgetc() ) {
533:
534: case '$':
535: if( !istyp && (istyp = ntp->s_type!=UINT) )
536: strcpy(s, typeptr[ntp->s_type]->s_name);
537: fprintf(actout, "yyval");
538: if( istyp )
539: fprintf(actout,".%s",s);
540: break;
541: case '0':
542: case '1':
543: case '2':
544: case '3':
545: case '4':
546: case '5':
547: case '6':
548: case '7':
549: case '8':
550: case '9':
551: case '-':
552: if( sign = c=='-' )
553: c = llgetc();
554: n = readnum(c);
555: n += -2*sign*n; /* jazzy linear eq. sign switch */
556: if( n>nel ) {
557: yyerror(!FATAL, "illegal $%d construct", n);
558: break;
559: }
560: #ifndef IAPX86 /* 'too many stores' workaround */
561: if( n>0 && !istyp &&
562: (sp = elook(nitprod->p_right[n-1]))->
563: s_type!=UINT ) {
564: #else
565: sp = elook(nitprod->p_right[n-1]);
566: if (n > 0 && !istyp && sp->s_type != UINT) {
567: #endif
568: sp = typeptr[sp->s_type];
569: istyp++;
570: strcpy(s, sp->s_name);
571: }
572: fprintf(actout,"yypvt[%d]", n-nel);
573: if( istyp )
574: fprintf(actout,".%s",s);
575: break;
576: default:
577: yyerror(!FATAL|SKIP, "illegal construct $%c", c);
578: break;
579: }
580: continue;
581: }
582: putc(c, actout);
583: } while( accolade );
584: fprintf(actout, "break;\n");
585: }
586:
587: backup(t)
588: {
589: last.lex = t;
590: last.val = yylval;
591: }
592:
593: linepos(f)
594: FILE *f;
595: {
596: fprintf(f, "\n#line %d \"%s\"\n", yyline, gramy);
597: }
598:
599: copycomment(s, f, flag)
600: register char *s;
601: FILE *f;
602: {
603: register c, c1;
604:
605: do {
606: c = llgetc();
607: while( c=='\\' && flag ) {
608: if( f!=NULL )
609: fprintf(f, "\\%c", llgetc());
610: c = llgetc();
611: }
612: if( c==EOF )
613: yyerror(FATAL, "end of file god knows where");
614: if (c=='\n' && flag)
615: yyerror(FATAL, "newline in string");
616: if(c!=s[0]){
617: if(f!=NULL)
618: putc(c, f);
619: }
620: else if( s[1]!='\0' && (c1 = llgetc()) != s[1] ){
621: if(f!=NULL)
622: putc(c, f);
623: llungetc(c1);
624: }
625: } while( c!=s[0] || (s[1]!='\0' && (c1!=s[1])) );
626: }
627:
628: getword(s)
629: char *s;
630: {
631: register char *sp;
632: register c;
633:
634: sp = s;
635: c = llgetc();
636: do {
637: if( sp>=&s[SYMSIZE-1] )
638: yyerror(FATAL, "symbol too long");
639: *sp++ = c;
640: } while( alphanum(c = llgetc()) );
641: *sp++ = '\0';
642: llungetc(c);
643: }
644:
645: llgetc()
646: {
647: register c;
648:
649: if( (c = getc(defin)) == '\n' )
650: yyline++;
651: return(c);
652: }
653:
654: llungetc(c)
655: register c;
656: {
657: if( c=='\n' )
658: yyline--;
659: ungetc(c, defin);
660: }
661:
662: readchar()
663: {
664: register c;
665:
666: if( (c = llgetc()) == '\\' ) {
667: switch( c = llgetc() ) {
668: case 'n':
669: return( '\n' );
670:
671: case 'r':
672: return( '\r' );
673:
674: case 't':
675: return( '\t' );
676:
677: case '\'':
678: return( '\'' );
679:
680: case 'b':
681: return( '\b' );
682:
683: case 'f':
684: return( '\f' );
685:
686: default:
687: if( c>='0' && c<='7' )
688: return( readnum(c) );
689: else
690: return(c);
691: }
692: }
693: return(c);
694: }
695:
696: copyunion()
697: {
698: register c, accolade;
699:
700: while( whitespace( c = llgetc() ) );
701: if( c!='{' )
702: yyerror(!FATAL,"Bad %union syntax");
703: linepos(fhdr);
704: fprintf(fhdr, "typedef union {");
705: accolade = 1;
706:
707: do {
708: if( (c = llgetc()) == EOF )
709: yyerror(FATAL, "eof in union declaration");
710: putc(c, fhdr);
711: if( c=='{' ) accolade++;
712: else if( c=='}' ) accolade--;
713: else if( c=='/' ) {
714: if( (c = llgetc()) == '*' ) {
715: putc('*', fhdr);
716: copycomment("*/", fhdr, 0);
717: fprintf(fhdr, "*/");
718: } else
719: llungetc(c);
720: }
721: } while( accolade );
722: fprintf(fhdr, " YYSTYPE;\n");
723: }
724:
725: readnum(c)
726: register c;
727: {
728: register n;
729:
730: n = c - '0';
731: while( digit( c=llgetc() ) )
732: n = n*10 + c - '0';
733: llungetc(c);
734: return(n);
735: }
736: alpha(c)
737: {
738: return( (c>='A' && c<='Z') || (c>='a' && c<='z') || c=='_' );
739: }
740:
741: digit(c)
742: {
743: return( c>='0' && c<='9' );
744: }
745:
746: alphanum(c)
747: {
748: return( (c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9')
749: || c=='_' );
750: }
751:
752: whitespace(c)
753: {
754: return( c==' ' || c=='\t' || c=='\f' || c=='\n' );
755: }
756:
757: whit2space(c)
758: {
759: return( c==' ' || c=='\t' || c=='\f' );
760: }
761:
762: struct sym *
763: elook(n)
764: register n;
765: {
766: if( n>=NTBASE )
767: return( ntrmptr[n-NTBASE] );
768: else
769: return( trmptr[n] );
770: }
771:
772: min(a,b)
773: {
774: return( a<b ? a : b);
775: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.