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