|
|
1.1 root 1: /*
2: * Copyright (c) 1979 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)ey3.c 5.1 (Berkeley) 4/29/85";
9: #endif not lint
10:
11: # include "ey.h"
12:
13: cpres(){ /* conpute an array with the beginnings of productions yielding given nonterminals
14: The array pres points to these lists */
15: int i,j,c;
16: pres = (int ***)yalloc(nnonter+1);
17: for(i=0;i<=nnonter;i++){
18: c = i+NTBASE;
19: pres[i] = (int **)mem;
20: fatfl = 0; /* make undefined symbols nonfatal */
21: for(j=0;j<nprod;j++)
22: if (*prdptr[j] == c) *mem++ = (int)(prdptr[j]+1);
23: if(pres[i] == (int **)mem){
24: error("nonterminal %s not defined!", nontrst[i].name);
25: }
26: }
27: pres[i] = (int **)mem;
28: fatfl = 1;
29: if( nerrors ){
30: summary();
31: cexit(1);
32: }
33: }
34:
35: int indebug = 0;
36: cpfir() {
37: /* compute an array with the first of nonterminals */
38: int i, ch, **s, **t, changes, *p;
39:
40: pfirst = (struct looksets **)yalloc(nnonter+1);
41: for (i=0;i<=nnonter;i++) {
42: aryfil( wsets[i].ws, tbitset, 0 );
43: t = pres[i+1];
44: for( s=pres[i]; s<t; ++s ){ /* initially fill the sets */
45: for( p = *s; (ch = *p) > 0 ; ++p ) {
46: if( ch < NTBASE ) {
47: wsets[i].ws[ch>>4] |= (1 << (ch&017) );
48: break;
49: }
50: else if( !pempty[ch-NTBASE] ) break;
51: }
52: }
53: }
54:
55: /* now, reflect transitivity */
56:
57: changes = 1;
58: while( changes ){
59: changes = 0;
60: for( i=0; i<=nnonter; ++i ){
61: t = pres[i+1];
62: for( s=pres[i]; s<t; ++s ){
63: for( p = *s; ( ch = (*p-NTBASE) ) >= 0; ++p ) {
64: changes |= UNION( wsets[i].ws, wsets[i].ws, wsets[ch].ws );
65: if( !pempty[ch] ) break;
66: }
67: }
68: }
69: }
70:
71: for( i=0; i<=nnonter; i++ ) pfirst[i] = flset( wsets[i].ws );
72: if( !indebug ) return;
73: settty();
74: for( i=0; i<=nnonter; i++ ){
75: fprintf( cout , "\n%s: ", nontrst[i].name );
76: prlook( pfirst[i] );
77: fprintf( cout , " %d\n", pempty[i] );
78: }
79: }
80:
81: state(c){ /* sorts last state,and sees if it equals earlier ones. returns state number */
82: int *s,size1,size2;
83: struct looksets *lp;
84: _REGISTER i;
85: struct item *p1, *p2, *k, *l, *q1, *q2;
86: p1 = pstate[nstate];
87: p2 = pstate[nstate+1];
88: if(p1==p2) return(0); /* null state */
89: /* sort the items */
90: for(k=p2-1;k>p1;k--) { /* make k the biggest */
91: for(l=k-1;l>=p1;--l)if( l->pitem > k->pitem ){
92: s = k->pitem;
93: k->pitem = l->pitem;
94: l->pitem = s;
95: lp = k->look;
96: k->look = l->look;
97: l->look = lp;
98: }
99: }
100: size1 = p2 - p1; /* size of state */
101:
102: for( i= (c>=NTBASE)?ntstates[c-NTBASE]:tstates[c]; i != 0; i = mstates[i] ) {
103: /* get ith state */
104: q1 = pstate[i];
105: q2 = pstate[i+1];
106: size2 = q2 - q1;
107: if (size1 != size2) continue;
108: k=p1;
109: for(l=q1;l<q2;l++) {
110: if( l->pitem != k->pitem ) break;
111: ++k;
112: }
113: if (l != q2) continue;
114: /* found it */
115: pstate[nstate+1] = pstate[nstate]; /* delete last state */
116: /* fix up lookaheads */
117: k=p1;
118: for( l=q1; l<q2; ++l ){
119: if( UNION( clset.lset, l->look->lset, k->look->lset ) ) {
120: tystate[i] = 1;
121: /* register the new set */
122: l->look = flset( &clset );
123: }
124: ++k;
125: }
126: return (i);
127: }
128: /* state is new */
129: pstate[nstate+2] = p2;
130: if(nstate+1 >= stsize) error("too many states");
131: if( c >= NTBASE ){
132: mstates[ nstate ] = ntstates[ c-NTBASE ];
133: ntstates[ c-NTBASE ] = nstate;
134: }
135: else {
136: mstates[ nstate ] = tstates[ c ];
137: tstates[ c ] = nstate;
138: }
139: tystate[nstate]=1;
140: return(nstate++);
141: }
142:
143: int pidebug = 0; /* debugging flag for putitem */
144: putitem ( ptr, lptr ) int *ptr; struct looksets *lptr;{
145: int *jip, k;
146: struct item *i, *j;
147:
148: if( pidebug ) {
149: settty();
150: fprintf( cout , "putitem(%s), state %d\n", writem(&ptr), nstate );
151: }
152: /* see if it's there */
153: j = pstate[nstate+1];
154: for( i=pstate[nstate]; i<j; ++i )
155: if(i->pitem == ptr) {
156: error("yacc error--duplicate item");
157: }
158: /* not there */
159: j->pitem = ptr;
160: j->look = flset( lptr );
161: pstate[nstate+1] = ++j;
162: jip = (int *)j;
163: if(jip-mem0 >= memsiz) error("out of state space");
164: }
165:
166: cempty(){ /* mark nonterminals which derive the empty string */
167:
168: int i, *p;
169:
170: /* set pempty to 0 */
171: pempty = (char *)yalloc( nnonter / sizeof(int) + 1 );
172: aryfil( pempty, nnonter+1, 0 );
173: for( i=1; i<nprod; ++i ) /* loop over productions */
174: if( prdptr[i][1] <= 0 ) /* i is empty production */
175: pempty[ *prdptr[i]-NTBASE ] = 1;
176:
177: /* now, all explicitly empty nonterminals marked with pempty = 1 */
178:
179: /* loop as long as we keep finding nontrivial empty nonterminals */
180:
181: again:
182: for( i=1; i<nprod; ++i ){
183: if( pempty[ *prdptr[i]-NTBASE ]==0 ){ /* not known to be empty */
184: for( p=prdptr[i]+1; *p>=NTBASE && pempty[*p-NTBASE]!=0 ; ++p ) ;
185: if( *p < 0 ){ /* we have a nontrivially empty nonterminal */
186: pempty[*prdptr[i]-NTBASE] = 1;
187: goto again; /* got one ... try for another */
188: }
189: }
190: }
191: }
192:
193: int gsdebug = 0;
194: stagen(){ /* generate the states */
195:
196: int i, j, k, c;
197:
198: /* initialize */
199:
200: nstate = 0;
201: pstate[0] = pstate[1] = (struct item *)mem;
202: aryfil( clset.lset, tbitset, 0 );
203: putitem( prdptr[0]+1, &clset );
204: tystate[0] = 1;
205: nstate = 1;
206: pstate[2] = pstate[1];
207:
208: memact = 0;
209: aryfil( amem, actsiz, 0 );
210:
211: /* now, the main state generation loop */
212:
213: more:
214: for( i=0; i<nstate; ++i ){
215: /* if tystate == 2, set to zero */
216: if( tystate[i] != 1 ) continue;
217: tystate[i] = 0;
218: aryfil( temp1, nterms+nnonter+1, 0 );
219: /* take state i, close it, and do gotos */
220: closure(i);
221: for( j=0; j<cwset; ++j ){ /* generate gotos */
222: if( wsets[j].flag ) continue;
223: wsets[j].flag = 1;
224: c = *(wsets[j].pitem);
225: /* if no symbols after the dot (ie empty rule) */
226: if( c <= 1 ) {
227: /* if not in kernel then tystate = 2 unless not done with it */
228: if( pstate[i+1]-pstate[i] <= j ) tystate[i] = (tystate[i]==1)?1:2;
229: continue;
230: }
231: /* do a goto on c */
232: for( k=j; k<cwset; ++k ){
233: if( c == *(wsets[k].pitem) ){ /* this item contributes to the goto */
234: putitem( wsets[k].pitem + 1, wsets[k].ws );
235: wsets[k].flag = 1;
236: }
237: }
238: if( c < NTBASE ) temp1[c] = state(c);
239: else temp1[c-NTBASE+nterms] = state(c);
240: }
241: if( gsdebug ){
242: settty();
243: fprintf( cout , "%d: ", i );
244: for( j=1; j<=nterms; ++j ){
245: if( temp1[j] != 0 ) fprintf( cout , "%s %d, ", symnam(j), temp1[j]);
246: }
247: for( j=1; j<=nnonter; ++j ){
248: if( temp1[j+nterms] ) fprintf( cout , "%s %d, ", nontrst[j].name, temp1[j+nterms] );
249: }
250: fprintf( cout , "\n");
251: }
252: apstate[i] = apack( &temp1[0], nterms );
253: indgo[i] = apack( &temp1[nterms+1], nnonter-1 ) - 1;
254: goto more; /* we have done one goto; do some more */
255: }
256: /* no more to do... stop */
257: }
258:
259: int cldebug = 0; /* debugging flag for closure */
260: closure(i){ /* generate the closure of state i */
261:
262: int c, ch, work;
263: _REGISTER j, k;
264: int *pi;
265: int **s, **t;
266: struct item *q;
267: _REGISTER struct item *p;
268:
269: ++zzclose;
270:
271: /* first, copy kernel of state i to wsets */
272:
273: lambdarule = -1;
274: cwset = 0;
275: q = pstate[i+1];
276: /* for every item in the kernel */
277: for( p=pstate[i]; p<q; ++p ){
278: wsets[cwset].pitem = p->pitem;
279: wsets[cwset].flag = 1; /* this item must get closed */
280: for( k=0; k<tbitset; ++k ) wsets[cwset].ws[k] = p->look->lset[k];
281: ++cwset;
282: }
283:
284: /* now, go through the loop, closing each item */
285:
286: work = 1;
287: while( work ){
288: work = 0;
289: for( j=0; j<cwset; ++j ){
290:
291: /* for every item in state, if terminal after dot, flag = 0 */
292: if( wsets[j].flag == 0 ) continue;
293: /* dot is before c, since pitem of X -> A.B is B */
294: c = *(wsets[j].pitem);
295:
296: if( c < NTBASE ){
297: wsets[j].flag = 0;
298: continue; /* only interesting case is where . is before nonterminal */
299: }
300:
301: /* compute the lookahead */
302: aryfil( clset.lset, tbitset, 0 );
303:
304: /* find items involving c */
305:
306: /* for all the rest of the items in the state */
307: for( k=j; k<cwset; ++k ){
308: if( wsets[k].flag == 1 && *(pi=wsets[k].pitem) == c ){
309: wsets[k].flag = 0;
310: if( nolook ) continue;
311: while( (ch= *++pi)>0 ){
312: if( ch < NTBASE ){ /* terminal symbol */
313: /* put ch in clset */
314: clset.lset[ch>>4] |= (1<<(ch&017));
315: break;
316: }
317: /* nonterminal symbol */
318: /* clset <- clset U first(ch) */
319: UNION( clset.lset, clset.lset, pfirst[ch-NTBASE] );
320: /* if ch cannot derive lambda we are done */
321: if( !pempty[ch-NTBASE] ) break;
322: }
323: /* if end of rule the clset <- clset U (lookahead for LHS) */
324: if( ch<=0 ) UNION( clset.lset, clset.lset, wsets[k].ws );
325: }
326: }
327:
328: /* now loop over productions derived from c */
329:
330: c -= NTBASE; /* c is now nonterminal number */
331:
332: t = pres[c+1];
333: /* for each rule that c derives */
334: for( s=pres[c]; s<t; ++s ){
335: /* put these items into the closure */
336: for( k=0; k<cwset; ++k ){ /* is the item there */
337: if( wsets[k].pitem == *s ){ /* yes, it is there */
338: if( nolook ) goto nexts;
339: /* if something new in ws, set flag = 1 */
340: if( UNION( wsets[k].ws, wsets[k].ws, clset.lset ) )
341: wsets[k].flag = work = 1;
342: goto nexts;
343: }
344: }
345:
346: /* not there; make a new entry */
347: if( cwset+1 >= wssize ) error( "working set overflow" );
348: wsets[cwset].pitem = *s;
349: wsets[cwset].flag = 1;
350: if (**s < 0)
351: lambdarule = cwset;
352: if( nolook ){
353: cwset++;
354: goto nexts;
355: }
356: work = 1;
357: for( k=0; k<tbitset; ++k ) wsets[cwset].ws[k] = clset.lset[k];
358: cwset++;
359:
360: nexts: ;
361: }
362:
363: }
364: }
365:
366: /* have computed closure; flags are reset; return */
367:
368: if( cwset > zzcwset ) zzcwset = cwset;
369: if( !cldebug ) return;
370: settty();
371: fprintf( cout , "\nState %d, nolook = %d\n", i, nolook );
372: for( j=0; j<cwset; ++j ){
373: if( wsets[j].flag ) fprintf( cout , "flag set!\n");
374: wsets[j].flag = 0;
375: fprintf( cout , "\t%s", writem(&wsets[j].pitem));
376: prlook( wsets[j].ws );
377: fprintf( cout , "\n" );
378: }
379:
380: }
381:
382: struct looksets *flset( p )
383: struct looksets *p;
384: {
385: /* decide if the lookahead set pointed to by p is known */
386: /* return pointer to a perminent location for the set */
387:
388: int j, *w;
389: _REGISTER *u, *v, i;
390:
391: for( i=0; i<nlset; ++i ){
392: u = p->lset;
393: v = lkst[i].lset;
394: w = & v[tbitset];
395: while( v<w) if( *u++ != *v++ ) goto more;
396: /* we have matched */
397: return( & lkst[i] );
398: more: ;
399: }
400: /* add a new one */
401: if( nlset+1 >= lsetsz )error("too many lookahead sets");
402: for( j=0; j<tbitset; ++j ){
403: lkst[nlset].lset[j] = p->lset[j];
404: }
405: return( & lkst[nlset++]);
406: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.