|
|
1.1 root 1: /*
2: * LALR-1 parser generator
3: * generation of lookahead sets
4: * the algorithm is thanks to Frank D. Remer & Thomas J Pennello,
5: * "Efficient computation of LALR(1) lookahead sets",
6: * SIGPLAN conference 1979.
7: */
8: #include "yacc.h"
9: #include <assert.h>
10:
11: /* the size of SMAX must be related to the amount of space available
12: on the runtime stack for recursive calls to traverse.
13: (on systems which do not dynamically allocate the stack like RSX)
14: on RSX traverse takes up about 18 bytes per call which means that
15: with a 1024 byte stack we can probably make 50-55 levels of recursion
16: */
17: #define SMAX 300
18:
19: #define INFINITY 10000 /* infinity is small for a mathematician */
20: #define INITCODE 1
21: #define COPYCODE 2
22: #define UNIONCODE 3
23: #define EOFCODE 4
24: static struct
25: {
26: int s_last;
27: int s_vals[SMAX];
28: } stk; /* stack for digraph */
29:
30: static struct trans *transp; /* temporary vector for traverse */
31: static struct lset *lsetp, *fsetp;
32: static int nttrans;
33: int rread(), rincl();
34: struct lset *getset();
35:
36: genlook()
37: {
38: int code = EOFCODE;
39: rewopt();
40: cttrans();
41: transp = (struct trans *)yalloc(nttrans, sizeof *transp);
42: cdread();
43: rread(0);
44: rread(1);
45: digraph();
46: free(transp->t_trans->ng_rel);
47: rincl(0);
48: rincl(1);
49: digraph();
50: free(transp->t_trans->ng_rel);
51: free(transp);
52: fwrite(&code, sizeof code, 1, optout);
53: execute();
54: lookback();
55: }
56:
57: cdread()
58: {
59: register i, j, k;
60: struct state *stp, *stp1;
61: struct ntgo *ntp;
62: struct lset lset;
63: int code = INITCODE;
64:
65: for(i=0; i<nstates; i++) {
66: stp = &states[i];
67: for(j=0; j<stp->s_ntgo; j++) {
68: zerolset(&lset);
69: ntp = &stp->s_ntgos[j];
70: stp1 = &states[ntp->ng_st];
71: for(k=0; k<stp1->s_tgo; k++)
72: setbit(&lset, stp1->s_tgos[k].tg_trm);
73: fwrite(&code, sizeof code, 1, optout);
74: fwrite(&ntp, sizeof ntp, 1, optout);
75: fwrite(lset.l_bits, sizeof lset.l_bits, 1, optout);
76: }
77: }
78: }
79:
80:
81:
82: cttrans()
83: {
84: /* count number of nonterminal transations in automaton */
85: register i;
86:
87: nttrans = 0;
88: for(i=0; i<nstates; i++)
89: nttrans += states[i].s_ntgo;
90: }
91:
92: digraph()
93: {
94: register i;
95: stk.s_last = 0;
96: zerolev();
97: for(i=0; i<nttrans; i++)
98: if( transp[i].t_level==0 )
99: traverse(i);
100: }
101:
102: traverse(x)
103: register int x;
104: {
105: register i, y;
106: int k;
107: struct ntgo *ntp;
108: int code = UNIONCODE;
109:
110: if( stk.s_last>= (SMAX-1) )
111: yyerror(FATAL|NLNO, "internal stack overflow - SMAX");
112: stk.s_vals[++stk.s_last] = x;
113: k = stk.s_last;
114: transp[x].t_level = k;
115: ntp = transp[x].t_trans;
116:
117: for(i=0; i<ntp->ng_rel->r_count; i++) {
118: y = ntp->ng_rel->r_list[i];
119: if( transp[y].t_level==0 )
120: traverse(y);
121: if( transp[y].t_level < transp[x].t_level )
122: transp[x].t_level = transp[y].t_level;
123: fwrite(&code, sizeof code, 1, optout);
124: fwrite(&ntp, sizeof ntp, 1, optout);
125: fwrite(&transp[y].t_trans, sizeof ntp, 1, optout);
126: }
127:
128: code = COPYCODE;
129: if( transp[x].t_level == k ) {
130: transp[x].t_level = INFINITY;
131: while( (y = stk.s_vals[stk.s_last--]) != x ) {
132: transp[y].t_level = INFINITY;
133: fwrite(&code, sizeof code, 1, optout);
134: fwrite(&transp[y].t_trans, sizeof ntp, 1, optout);
135: fwrite(&ntp, sizeof ntp, 1, optout);
136: }
137: }
138: }
139:
140: /*
141: * form the set unions of the read sets and the follow sets, following
142: * the codes left in temp file by digraph
143: */
144: execute()
145: {
146: int code;
147: struct ntgo *ntp1, *ntp2;
148: register struct lset *csetp;
149:
150: rewopt();
151: csetp = lsetp = (struct lset *)yalloc(nttrans, sizeof *lsetp);
152: fsetp = NULL;
153: for(;;) {
154: if( fread(&code, sizeof code, 1, optout) != 1 )
155: yyerror(NLNO|FATAL, "eof on tempfile in execute");
156: switch( code ) {
157: case INITCODE:
158: fread(&ntp1, sizeof ntp1, 1, optout);
159: assert( csetp < &lsetp[nttrans] );
160: fread(csetp->l_bits, sizeof csetp->l_bits, 1, optout);
161: /*
162: fprintf(listout, "init: "); ptrans(ntp1);
163: prlset(csetp); fprintf(listout,"\n");
164: */
165: ntp1->ng_lset = csetp++;
166: break;
167:
168: case UNIONCODE:
169: fread(&ntp1, sizeof ntp1, 1, optout);
170: fread(&ntp2, sizeof ntp2, 1, optout);
171: /*
172: fprintf(listout, "union "); ptrans(ntp1); fprintf(listout," |=");
173: ptrans(ntp2);
174: */
175: setunion(ntp1->ng_lset, ntp2->ng_lset);
176: /*
177: prlset(ntp1->ng_lset); fprintf(listout, "\n");
178: */
179: break;
180:
181: case COPYCODE:
182: fread(&ntp1, sizeof ntp1, 1, optout);
183: fread(&ntp2, sizeof ntp2, 1, optout);
184: xxx("copy", ntp1, ntp2);
185: freeset(ntp1->ng_lset);
186: ntp1->ng_lset = getset();
187: copylset(ntp1->ng_lset, ntp2->ng_lset);
188: break;
189:
190: case EOFCODE:
191: return;
192: default:
193: yyerror(NLNO|FATAL, "bad temp file; code %o\n", code);
194: }
195: }
196: }
197:
198: lookback()
199: {
200: register i;
201:
202: for(i=0; i<nprod; i++)
203: reduce(prdptr[i]);
204:
205: }
206:
207: reduce(pp)
208: register struct prod *pp;
209: {
210: register nt, i;
211: struct sym *sp;
212: struct redn *rdp;
213: struct state *stp, *stp1;
214: int j, sno, sno1;
215: struct ntgo *ntp;
216:
217: nt = -pp->p_left;
218: sp = ntrmptr[nt-NTBASE];
219: for(j=0; j<sp->s_nstates; j++) {
220: stp = &states[sno = sp->s_states[j]];
221: for(i=0; i<stp->s_ntgo; i++) {
222: ntp = &stp->s_ntgos[i];
223: if( ntp->ng_nt == nt )
224: break;
225: }
226: assert(pp->p_prodno==0 || i<stp->s_ntgo);
227: sno1 = go2star(sno, PROD_RIGHT (pp),
228: PROD_RIGHT (pp) + prodl(pp));
229: stp1 = &states[sno1];
230: if( stp1->s_reds == (struct redn *)NULL ) { /* MWC DSC */
231: stp1->s_reds = (struct redn *)yalloc(stp1->s_nred, sizeof *stp1->s_reds);
232: stp1->s_nred = 0;
233: }
234: rdp = stp1->s_reds;
235: for(i=0; i<stp1->s_nred; i++,rdp++)
236: if( rdp->rd_prod==pp )
237: break;
238: if( yydebug ) {
239: fprintf(listout, "(%d, pdn %d) ", sno1, pp->p_prodno);
240: prlset(ntp->ng_lset);
241: fprintf(listout, "\n");
242: }
243: if( i==stp1->s_nred ) {
244: rdp->rd_prod = pp;
245: rdp->rd_lset = getset();
246: if( pp->p_prodno!=0 ) {
247: copylset(rdp->rd_lset, ntp->ng_lset);
248: } else {
249: zerolset(rdp->rd_lset);
250: setbit(rdp->rd_lset, EOFNO);
251: }
252: stp1->s_nred++;
253: } else {
254: setunion(rdp->rd_lset, ntp->ng_lset);
255: }
256: }
257: }
258:
259: go2star(sno, ip, fin)
260: register *ip;
261: int *fin;
262: {
263: register i;
264: register struct state *stp;
265:
266: while( ip!=fin ) {
267: stp = &states[sno];
268: if( *ip>=NTBASE ) {
269: for(i=0; i<stp->s_ntgo; i++)
270: if( stp->s_ntgos[i].ng_nt == *ip )
271: break;
272: assert(i<stp->s_ntgo);
273: sno = stp->s_ntgos[i].ng_st;
274: } else {
275: for(i=0; i<stp->s_tgo; i++)
276: if( stp->s_tgos[i].tg_trm == *ip )
277: break;
278: assert(i<stp->s_tgo);
279: sno = stp->s_tgos[i].tg_st;
280: }
281: ip++;
282: }
283: return(sno);
284: }
285:
286: rread(todo)
287: {
288: struct state *stp;
289: register struct sym *sp;
290: register i, j;
291: int p;
292: struct ntgo *ntp;
293:
294: if( todo )
295: zerolev();
296: else
297: startcount();
298:
299: for(i=0; i<nttrans; i++) {
300: stp = &states[transp[i].t_trans->ng_st];
301: for(j=0; j<stp->s_ntgo; j++) {
302: ntp = &stp->s_ntgos[j];
303: sp = ntrmptr[ntp->ng_nt-NTBASE];
304: if( sp->s_flags&DERIV ) {
305: p = transp[i].t_level++;
306: if( todo ) {
307: transp[i].t_trans->ng_rel->r_list[p] =
308: rsearch(ntp);
309: xxx("reads",transp[i].t_trans,ntp);
310: }
311: break;
312: }
313: }
314: }
315: if( !todo )
316: endcount();
317: }
318:
319: rincl(todo)
320: {
321: register i, j;
322: int *pb, *pe, k, p, sno, sno1, ind, nt;
323: struct state *stp;
324: struct prod *pp;
325: struct ntgo *ntp;
326: struct sym *sp;
327:
328: if( todo )
329: zerolev();
330: else
331: startcount();
332: for(i=0; i<nttrans; i++) {
333: sno = ssearch(transp[i].t_trans);
334: sp = ntrmptr[transp[i].t_trans->ng_nt-NTBASE];
335: for(j=0; j<sp->s_nprods; j++) {
336: pp = sp->s_prods[j];
337: pb = PROD_RIGHT (pp);
338: pe = pb + prodl(pp);
339: while( pb <= --pe && (nt = *pe) >= NTBASE ) {
340: sno1 = go2star(sno, pb, pe);
341: stp = &states[sno1];
342: for(k=0; k<stp->s_ntgo; k++)
343: if( stp->s_ntgos[k].ng_nt==nt )
344: break;
345: assert(k<stp->s_ntgo);
346: ind = rsearch(&stp->s_ntgos[k]);
347: p = transp[ind].t_level++;
348: if( todo ) {
349: ntp = transp[ind].t_trans;
350: xxx("includes", ntp, transp[i].t_trans);
351: ntp->ng_rel->r_list[p] = i;
352: }
353: if( (ntrmptr[nt-NTBASE]->s_flags&DERIV)==0 )
354: break;
355: }
356: }
357: }
358: if( !todo )
359: endcount();
360: }
361:
362: endcount()
363: {
364: register i, k;
365: struct ntgo *ntp;
366: char * alloc;
367:
368: k = 0;
369: for(i = 0 ; i < nttrans ; i ++)
370: k += REL_TOTAL_SIZE (transp [i].t_level);
371:
372: alloc = yalloc (1, k);
373:
374: for(i=0; i<nttrans; i++) {
375: ntp = transp[i].t_trans;
376: ntp->ng_rel = (struct rel *) alloc;
377: REL_EXTRA_INIT (ntp->ng_rel);
378: ntp->ng_rel->r_count = transp[i].t_level;
379:
380: alloc += REL_TOTAL_SIZE (transp[i].t_level);
381: }
382: }
383:
384: startcount()
385: {
386: register i, j, k;
387: struct state *stp;
388:
389: k = 0;
390: for(i=0; i<nstates; i++) {
391: stp = &states[i];
392: for(j=0; j<stp->s_ntgo; j++) {
393: transp[k].t_trans = &stp->s_ntgos[j];
394: transp[k].t_level = 0;
395: k++;
396: }
397: }
398: }
399:
400: zerolev()
401: {
402: register i;
403: for(i=0; i<nttrans; i++)
404: transp[i].t_level = 0;
405: }
406:
407: rsearch(ntp)
408: struct ntgo *ntp;
409: {
410: register lb, nb;
411: register struct ntgo *el;
412: int ub;
413:
414: lb = 0;
415: ub = nttrans-1;
416: do {
417: nb = (ub+lb)/2;
418: if( (el = transp[nb].t_trans) < ntp )
419: lb = nb+1;
420: else if( el > ntp )
421: ub = nb-1;
422: else
423: return(nb);
424: } while( lb<=ub );
425: yyerror(NLNO|FATAL, "oops in rsearch");
426: }
427:
428: ssearch(ntp)
429: struct ntgo *ntp;
430: {
431: register lb, nb;
432: register struct ntgo *el;
433: int ub;
434:
435: lb = 0;
436: ub = nstates-1;
437:
438: do {
439: nb = (ub+lb) / 2;
440: el = states[nb].s_ntgos;
441: if( ntp < el )
442: ub = nb-1;
443: else if( ntp >= &el[states[nb].s_ntgo] )
444: lb = nb+1;
445: else
446: return(nb);
447: } while( lb<=ub );
448: yyerror(NLNO|FATAL, "oops in ssearch");
449: }
450:
451: prodl(pp)
452: register struct prod *pp;
453: {
454: register *ip;
455:
456: ip = PROD_RIGHT (pp);
457: while (* ip ++ != -1)
458: /* DO NOTHING */;
459: return ip - PROD_RIGHT (pp) - 1; /* BONZO OR NO??? */
460: }
461:
462: struct lset *
463: getset()
464: {
465: register struct lset *lp;
466: if( fsetp ) {
467: lp = fsetp;
468: fsetp = fsetp->l_next;
469: return(lp);
470: }
471: lp = (struct lset *)yalloc(1, sizeof *lp);
472: return(lp);
473: }
474:
475: freeset(lp)
476: struct lset *lp;
477: {
478: lp->l_next = fsetp;
479: fsetp = lp;
480: }
481:
482: frlset()
483: {
484: register struct state *stp;
485: register i, j;
486: struct lset *lp, *lp1;
487:
488: free(states[0].s_tgos);
489: free(states[0].s_ntgos);
490: for(i=0; i<nstates; i++) {
491: stp = &states[i];
492: for(j=0; j<stp->s_nred; j++)
493: freeset(stp->s_reds[j].rd_lset);
494: if( stp->s_reds != (struct redn *)NULL ) /* MWC DSC */
495: free(stp->s_reds);
496: for(j=0; j<stp->s_ntgo; j++)
497: freeset(stp->s_ntgos[j].ng_lset);
498: }
499: lp = fsetp;
500: while( lp ) {
501: lp1 = lp->l_next;
502: if( lp<&lsetp[0] || lp>=&lsetp[nttrans] )
503: free(lp);
504: lp = lp1;
505: }
506: free(lsetp);
507: }
508:
509: xxx(s, ntp1, ntp2)
510: char *s;
511: struct ntgo *ntp1, *ntp2;
512: {
513: if( !yydebug )
514: return;
515: ptrans(ntp1); fprintf(listout, " %s ", s); ptrans(ntp2);
516: fprintf(listout, "\n");
517: }
518: ptrans(ntp)
519: struct ntgo *ntp;
520: {
521: int sno;
522: sno = ssearch(ntp);
523: fprintf(listout, "(%d, %s)", sno, ptosym(ntp->ng_nt));
524: }
525:
526: prlset(ls)
527: struct lset *ls;
528: {
529: register i, once;
530: fprintf(listout, "[");
531: once = 0;
532: for(i=first(ls); i>=0; i=next(ls,i)) {
533: if( once++ ) fprintf(listout, ",");
534: fprintf(listout, "%s", trmptr[i]->s_name);
535: }
536: fprintf(listout, "]");
537: }
538:
539:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.