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