xref: /original-bsd/usr.bin/pascal/eyacc/ey4.c (revision cd79ddd6)
1704299f3Sbostic /*-
2*cd79ddd6Sbostic  * Copyright (c) 1979, 1993
3*cd79ddd6Sbostic  *	The Regents of the University of California.  All rights reserved.
4704299f3Sbostic  *
5704299f3Sbostic  * %sccs.include.proprietary.c%
6f600bb80Smckusick  */
7f600bb80Smckusick 
8f600bb80Smckusick #ifndef lint
9*cd79ddd6Sbostic static char sccsid[] = "@(#)ey4.c	8.1 (Berkeley) 06/06/93";
10704299f3Sbostic #endif /* not lint */
11f600bb80Smckusick 
12f600bb80Smckusick # include "ey.h"
13f600bb80Smckusick 
output()14f600bb80Smckusick output(){ /* print the output for the states */
15f600bb80Smckusick 
16f600bb80Smckusick   int i, j, k, c;
17f600bb80Smckusick 
18f600bb80Smckusick   settab();
19f600bb80Smckusick   arrset("yyact");
20f600bb80Smckusick 
21f600bb80Smckusick   for( i=0; i<nstate; ++i ){ /* output the stuff for state i */
22f600bb80Smckusick     nolook = (tystate[i]==0);
23f600bb80Smckusick     closure(i);
24f600bb80Smckusick     /* output actions */
25f600bb80Smckusick     aryfil( temp1, nterms+1, 0 );
26f600bb80Smckusick     for( j=0; j<cwset; ++j ){ /* look at the items */
27f600bb80Smckusick       c = *( wsets[j].pitem );
28f600bb80Smckusick       if( c>0 && c<NTBASE && temp1[c]==0 ) temp1[c] = go2(i,c);
29f600bb80Smckusick       }
30f600bb80Smckusick 
31f600bb80Smckusick     if( i == 1 ) temp1[1] = ACCEPTCODE;
32f600bb80Smckusick 
33f600bb80Smckusick     /* now, we have the shifts; look at the reductions */
34f600bb80Smckusick 
35f600bb80Smckusick     lastred = 0;
36f600bb80Smckusick     for( j=0; j<cwset; ++j ){
37f600bb80Smckusick       c = *( wsets[j].pitem );
38f600bb80Smckusick       if( c<=0 ){ /* reduction */
39f600bb80Smckusick         lastred = -c;
40f600bb80Smckusick         for( k=1; k<=nterms; ++k ){
41f600bb80Smckusick           if( ((wsets[j].ws[k>>4])&(1<<(k&017))) != 0 ) {
42f600bb80Smckusick             if( temp1[k] == 0 ) temp1[k] = c;
43f600bb80Smckusick             else if( temp1[k]<0 ){ /* reduce/reduce conflict */
44f600bb80Smckusick               settty();
45f600bb80Smckusick               fprintf( cout , "\n%d: reduce/reduce conflict (red'ns %d and %d ) on %s",
46f600bb80Smckusick                 i, -temp1[k], lastred, symnam(k) );
47f600bb80Smckusick               if( -temp1[k] > lastred ) temp1[k] = -lastred;
48f600bb80Smckusick               ++zzrrconf;
49f600bb80Smckusick               settab();
50f600bb80Smckusick               }
51f600bb80Smckusick             else { /* potential shift/reduce conflict */
52f600bb80Smckusick               switch( precftn( lastred, k ) ) {
53f600bb80Smckusick 
54f600bb80Smckusick             case 0: /* precedence does not apply */
55f600bb80Smckusick 
56f600bb80Smckusick                 settty();
57f600bb80Smckusick                 fprintf( cout , "\n%d: shift/reduce conflict (shift %d, red'n %d) on %s", i,
58f600bb80Smckusick 			temp1[k], lastred, symnam(k) );
59f600bb80Smckusick                 ++zzsrconf;
60f600bb80Smckusick                 settab();
61f600bb80Smckusick 		/* resolve in favor of shifting, so remove from reduce set */
62f600bb80Smckusick 		wsets[j].ws[k>>4] &=~ (1<<(k&017));
63f600bb80Smckusick                 break;
64f600bb80Smckusick 
65f600bb80Smckusick             case 1: /*  reduce */
66f600bb80Smckusick 
67f600bb80Smckusick                 temp1[k] = -lastred;
68f600bb80Smckusick                 break;
69f600bb80Smckusick 
70f600bb80Smckusick             case 2: /* error, binary operator */
71f600bb80Smckusick 
72f600bb80Smckusick                 temp1[k] = ERRCODE;
73f600bb80Smckusick                 break;
74f600bb80Smckusick 
75f600bb80Smckusick             case 3: /* shift ... leave the entry alone */
76f600bb80Smckusick 
77f600bb80Smckusick                 break;
78f600bb80Smckusick                 }
79f600bb80Smckusick               }
80f600bb80Smckusick             }
81f600bb80Smckusick           }
82f600bb80Smckusick         }
83f600bb80Smckusick       }
84f600bb80Smckusick     wract(i);
85f600bb80Smckusick     }
86f600bb80Smckusick 
87f600bb80Smckusick   settab();
88f600bb80Smckusick   arrdone();
89f600bb80Smckusick 
90f600bb80Smckusick   /* now, output the pointers to the action array */
91f600bb80Smckusick   /* also output the info about reductions */
92f600bb80Smckusick   prred();
93f600bb80Smckusick   }
94f600bb80Smckusick 
prred()95f600bb80Smckusick prred(){ /* print the information about the actions and the reductions */
96f600bb80Smckusick   int index, i;
97f600bb80Smckusick 
98f600bb80Smckusick   arrset("yypact");
99f600bb80Smckusick   index = 1;    /* position in the output table */
100f600bb80Smckusick 
101f600bb80Smckusick   for( i=0; i<nstate; ++i ){
102f600bb80Smckusick     if( tystate[i]>0 ){  /* the state is real */
103f600bb80Smckusick       temp1[i] = index;
104f600bb80Smckusick       arrval( index );
105f600bb80Smckusick       index += tystate[i];
106f600bb80Smckusick       }
107f600bb80Smckusick     else {
108f600bb80Smckusick       arrval( temp1[-tystate[i]] );
109f600bb80Smckusick       }
110f600bb80Smckusick     }
111f600bb80Smckusick 
112f600bb80Smckusick   arrdone();
113f600bb80Smckusick 
114f600bb80Smckusick   arrset("yyr1");
115f600bb80Smckusick   for( i=1; i<nprod; ++i ) arrval( *prdptr[i] - NTBASE );
116f600bb80Smckusick   arrdone();
117f600bb80Smckusick 
118f600bb80Smckusick   arrset("yyr2");
119f600bb80Smckusick   for( i=1; i<nprod; ++i ) arrval( ( prdptr[i+1]-prdptr[i]-2 ) );
120f600bb80Smckusick   arrdone();
121f600bb80Smckusick 
122f600bb80Smckusick   }
123f600bb80Smckusick 
go2(i,c)124f600bb80Smckusick go2(i,c){ /* do a goto on the closure state, not worrying about lookaheads */
125f600bb80Smckusick   if( c<NTBASE ) return( amem[ apstate[i]+c ] );
126f600bb80Smckusick   else return( amem[ apstate[i] + c - NTBASE + nterms ] );
127f600bb80Smckusick   }
128f600bb80Smckusick 
129f600bb80Smckusick int pkdebug = 0;
apack(p,n)130f600bb80Smckusick apack(p, n ) int *p;{ /* pack state i from temp1 into amem */
131f600bb80Smckusick   _REGISTER k, l, off;
132f600bb80Smckusick   int j;
133f600bb80Smckusick 
134f600bb80Smckusick   /* find the spot */
135f600bb80Smckusick 
136f600bb80Smckusick   j = n;
137f600bb80Smckusick   for( off = 0; off <= j && p[off] == 0; ++off ) ;
138f600bb80Smckusick   if( off > j ){ /* no actions */
139f600bb80Smckusick     return(0);
140f600bb80Smckusick     }
141f600bb80Smckusick   j -= off;
142f600bb80Smckusick   for( k=0; k<actsiz; ++k ){
143f600bb80Smckusick     for( l=0; l<=j; ++l ){
144f600bb80Smckusick       if( p[off+l] != 0 ){
145f600bb80Smckusick         if( p[off+l] != amem[k+l] && amem[k+l] != 0 ) goto nextk;
146f600bb80Smckusick         }
147f600bb80Smckusick       }
148f600bb80Smckusick     if( pkdebug ){ settty(); fprintf( cout , "off = %d, k = %d\n", off, k ); }
149f600bb80Smckusick     /* we have found an acceptable k */
150f600bb80Smckusick     for( l=0; l<=j; ++l ){
151f600bb80Smckusick       if( p[off+l] ){
152f600bb80Smckusick         if( k+l >= actsiz ) error("action table overflow");
153f600bb80Smckusick         if( k+l >= memact ) memact = k+l;
154f600bb80Smckusick         amem[k+l] = p[off+l];
155f600bb80Smckusick         }
156f600bb80Smckusick       }
157f600bb80Smckusick     if( pkdebug ){
158f600bb80Smckusick       for( k=0; k<memact; k+=10){
159f600bb80Smckusick         fprintf( cout , "\t");
160f600bb80Smckusick         for( l=0; l<=9; ++l ) fprintf( cout , "%d ", amem[k+l] );
161f600bb80Smckusick         fprintf( cout , "\n");
162f600bb80Smckusick         }
163f600bb80Smckusick       }
164f600bb80Smckusick     return(k-off);
165f600bb80Smckusick 
166f600bb80Smckusick     nextk: ;
167f600bb80Smckusick     }
168f600bb80Smckusick   error("no space in action table");
169f600bb80Smckusick   }
170f600bb80Smckusick 
go2out()171f600bb80Smckusick go2out(){ /* output the gotos for the nontermninals */
172f600bb80Smckusick   int i, j, k, best, offset, count, cbest, times;
173f600bb80Smckusick 
174f600bb80Smckusick   settab();
175f600bb80Smckusick   arrset("yygo");
176f600bb80Smckusick   offset = 1;
177f600bb80Smckusick 
178f600bb80Smckusick   for( i=1; i<=nnonter; ++i ) {
179f600bb80Smckusick     go2gen(i);
180f600bb80Smckusick 
181f600bb80Smckusick     /* find the best one to make default */
182f600bb80Smckusick 
183f600bb80Smckusick     temp2[i] = offset;
184f600bb80Smckusick 
185f600bb80Smckusick     best = -1;
186f600bb80Smckusick     times = 0;
187f600bb80Smckusick 
188f600bb80Smckusick     for( j=0; j<=nstate; ++j ){ /* is j the most frequent */
189f600bb80Smckusick       if( tystate[j] == 0 ) continue;
190f600bb80Smckusick       if( tystate[j] == best ) continue;
191f600bb80Smckusick 
192f600bb80Smckusick       /* is tystate[j] the most frequent */
193f600bb80Smckusick 
194f600bb80Smckusick       count = 0;
195f600bb80Smckusick       cbest = tystate[j];
196f600bb80Smckusick 
197f600bb80Smckusick       for( k=j; k<=nstate; ++k ) if( tystate[k]==cbest ) ++count;
198f600bb80Smckusick 
199f600bb80Smckusick       if( count > times ){
200f600bb80Smckusick         best = cbest;
201f600bb80Smckusick         times = count;
202f600bb80Smckusick         }
203f600bb80Smckusick       }
204f600bb80Smckusick 
205f600bb80Smckusick     /* best is now the default entry */
206f600bb80Smckusick 
207f600bb80Smckusick     zzgobest += (times-1)*2;
208f600bb80Smckusick     settab();
209f600bb80Smckusick     for( j=0; j<=nstate; ++j ){
210f600bb80Smckusick       if( tystate[j] != 0 && tystate[j]!=best ){
211f600bb80Smckusick         arrval( j );
212f600bb80Smckusick         arrval( tystate[j] );
213f600bb80Smckusick         offset += 2;
214f600bb80Smckusick         zzgoent += 2;
215f600bb80Smckusick         }
216f600bb80Smckusick       }
217f600bb80Smckusick 
218f600bb80Smckusick     /* now, the default */
219f600bb80Smckusick 
220f600bb80Smckusick     zzgoent += 2;
221f600bb80Smckusick     arrval( -1 );
222f600bb80Smckusick     arrval( best );
223f600bb80Smckusick     offset += 2;
224f600bb80Smckusick 
225f600bb80Smckusick     }
226f600bb80Smckusick 
227f600bb80Smckusick   arrdone();
228f600bb80Smckusick 
229f600bb80Smckusick   arrset("yypgo");
230f600bb80Smckusick   for( i=1; i<=nnonter; ++i ) arrval( temp2[i] );
231f600bb80Smckusick   arrdone();
232f600bb80Smckusick 
233f600bb80Smckusick   }
234f600bb80Smckusick 
235f600bb80Smckusick int g2debug = 0;
go2gen(c)236f600bb80Smckusick go2gen(c){ /* output the gotos for nonterminal c */
237f600bb80Smckusick 
238f600bb80Smckusick   int i, work, cc;
239f600bb80Smckusick   struct item *p, *q;
240f600bb80Smckusick 
241f600bb80Smckusick   /* first, find nonterminals with gotos on c */
242f600bb80Smckusick 
243f600bb80Smckusick   aryfil( temp1, nnonter+1, 0 );
244f600bb80Smckusick   temp1[c] = 1;
245f600bb80Smckusick 
246f600bb80Smckusick   work = 1;
247f600bb80Smckusick   while( work ){
248f600bb80Smckusick     work = 0;
249f600bb80Smckusick     for( i=0; i<nprod; ++i ){
250f600bb80Smckusick       if( (cc=prdptr[i][1]-NTBASE) >= 0 ){ /* cc is a nonterminal */
251f600bb80Smckusick         if( temp1[cc] != 0 ){ /* cc has a goto on c */
252f600bb80Smckusick           cc = *prdptr[i]-NTBASE; /* thus, the left side of production i does too */
253f600bb80Smckusick           if( temp1[cc] == 0 ){
254f600bb80Smckusick             work = 1;
255f600bb80Smckusick             temp1[cc] = 1;
256f600bb80Smckusick             }
257f600bb80Smckusick           }
258f600bb80Smckusick         }
259f600bb80Smckusick       }
260f600bb80Smckusick     }
261f600bb80Smckusick 
262f600bb80Smckusick   /* now, we have temp1[c] = 1 if a goto on c in closure of cc */
263f600bb80Smckusick 
264f600bb80Smckusick   if( g2debug ){
265f600bb80Smckusick     settty();
266f600bb80Smckusick     fprintf( cout , "%s: gotos on ", nontrst[c].name );
267f600bb80Smckusick     for( i=0; i<=nnonter; ++i ) if( temp1[i]) fprintf( cout , "%s ", nontrst[i].name);
268f600bb80Smckusick     fprintf( cout , "\n");
269f600bb80Smckusick     }
270f600bb80Smckusick 
271f600bb80Smckusick   /* now, go through and put gotos into tystate */
272f600bb80Smckusick 
273f600bb80Smckusick   aryfil( tystate, nstate, 0 );
274f600bb80Smckusick   settty();
275f600bb80Smckusick   fprintf( cout , "\nnonterminal %s\n", nontrst[c].name );
276f600bb80Smckusick   for( i=0; i<nstate; ++i ){
277f600bb80Smckusick     q = pstate[i+1];
278f600bb80Smckusick     for( p=pstate[i]; p<q; ++p ){
279f600bb80Smckusick       if( (cc= *p->pitem) >= NTBASE ){
280f600bb80Smckusick         if( temp1[cc -= NTBASE] ){ /* goto on c is possible */
281f600bb80Smckusick           tystate[i] = amem[indgo[i]+c];
282f600bb80Smckusick           break;
283f600bb80Smckusick           }
284f600bb80Smckusick         }
285f600bb80Smckusick       }
286f600bb80Smckusick     if( tystate[i] ) fprintf( cout , "\t%d\t%d\n", i, tystate[i]);
287f600bb80Smckusick     }
288f600bb80Smckusick   }
289f600bb80Smckusick 
precftn(r,t)290f600bb80Smckusick precftn(r,t){ /* decide a shift/reduce conflict by precedence.
291f600bb80Smckusick 			Returns 0 if action is 'do nothing',1 if action is reduce,
292f600bb80Smckusick 			2 if the action is 'error,binary operator'
293f600bb80Smckusick 			and 3 if the action is 'reduce'. */
294f600bb80Smckusick 
295f600bb80Smckusick 	int lp,lt;
296f600bb80Smckusick 	lp = levprd[r];
297f600bb80Smckusick 	lt = trmlev[t];
298f600bb80Smckusick 	if ((lt==0)||((lp&03)==0))return(0);
299f600bb80Smckusick 	if((lt>>3) == (lp>>3)){
300f600bb80Smckusick 		return(lt&03);
301f600bb80Smckusick 		}
302f600bb80Smckusick 	if((lt>>3) > (lp>>3)) return(3);
303f600bb80Smckusick 	return(1);
304f600bb80Smckusick 	}
305f600bb80Smckusick 
306f600bb80Smckusick int cdebug = 0; /* debug for common states */
wract(i)307f600bb80Smckusick wract(i){ /* output state i */
308f600bb80Smckusick   /* temp1 has the actions, lastred the default */
309f600bb80Smckusick   int p, p0, p1, size;
310f600bb80Smckusick   int ntimes, tred, count, j, k;
311f600bb80Smckusick   struct item *q0, *q1;
312f600bb80Smckusick 
313f600bb80Smckusick   /* find the best choice for lastred */
314f600bb80Smckusick 
315f600bb80Smckusick   lastred = 0;
316f600bb80Smckusick   ntimes = 0;
317f600bb80Smckusick   stateflags[i] = 0;
318f600bb80Smckusick   /***** UCB MOD - full state spec if shift on error *****/
319f600bb80Smckusick   if (temp1[2] > 0)
320f600bb80Smckusick     stateflags[i] |= NEEDSREDUCE;
321f600bb80Smckusick   else for( j=1; j<=nterms; ++j ){
322f600bb80Smckusick     /* find the entry on which the greatest number of reductions are done */
323f600bb80Smckusick     if( temp1[j] >= 0 ) continue;
324f600bb80Smckusick     if( temp1[j]+lastred == 0 ) continue;
325f600bb80Smckusick     /* count the number of appearances of temp1[j] */
326f600bb80Smckusick     count = 0;
327f600bb80Smckusick     tred = -temp1[j];
328f600bb80Smckusick     for( p=1; p<=nterms; ++p ){
329f600bb80Smckusick       if( temp1[p]+tred == 0 ) ++count;
330f600bb80Smckusick       }
331f600bb80Smckusick     if( count >ntimes ){
332f600bb80Smckusick       lastred = tred;
333f600bb80Smckusick       ntimes = count;
334f600bb80Smckusick       }
335f600bb80Smckusick     }
336f600bb80Smckusick 
337f600bb80Smckusick     /* clear out entries in temp1 which equal lastred */
338f600bb80Smckusick     /* ie, make the most frequent reduction into the default reduction */
339f600bb80Smckusick     for( p=1; p<= nterms; ++p ) if( temp1[p]+lastred == 0 )temp1[p]=0;
340f600bb80Smckusick 
341f600bb80Smckusick     /* write out the state */
342f600bb80Smckusick 
343f600bb80Smckusick     /* first, check for equality with another state */
344f600bb80Smckusick     /* see if there is a nonterminal with all dots before it, */
345f600bb80Smckusick     /* and no reductions in the state */
346f600bb80Smckusick     /* this is done by checking if all items are the same non-terminal */
347f600bb80Smckusick     p0 = 0;
348f600bb80Smckusick     q1 = pstate[i+1];
349f600bb80Smckusick     for( q0=pstate[i]; q0<q1; ++q0 ){
350f600bb80Smckusick       if( (p1= *(q0->pitem) ) < NTBASE ) goto standard;
351f600bb80Smckusick       if( p0 == 0 ) p0 = p1;
352f600bb80Smckusick       else if( p0 != p1 ) goto standard;
353f600bb80Smckusick       }
354f600bb80Smckusick     stateflags[i] |= SINGLE_NT | pempty[p0 - NTBASE];
355f600bb80Smckusick 
356f600bb80Smckusick     /* now, all items have dots before p0 */
357f600bb80Smckusick     if( cdebug ){
358f600bb80Smckusick       settty();
359f600bb80Smckusick       fprintf( cout , "state %d, pre-nonterminal %s\n",i,nontrst[p0-NTBASE].name);
360f600bb80Smckusick       }
361f600bb80Smckusick 
362f600bb80Smckusick     for( j=0; j<i; ++j ){
363f600bb80Smckusick       /*
364f600bb80Smckusick        * check that the states have the same shift lookaheads.
365f600bb80Smckusick        */
366f600bb80Smckusick       if( apstate[i] != apstate[j] )
367f600bb80Smckusick 	continue;
368f600bb80Smckusick       if (cdebug)
369f600bb80Smckusick 	fprintf(cout, "states %d and %d have same shift lookaheads\n",i,j);
370f600bb80Smckusick 
371f600bb80Smckusick       /*
372f600bb80Smckusick        * Check that state has one item, and that the item matches.
373f600bb80Smckusick        */
374f600bb80Smckusick       if ((stateflags[j] & SINGLE_NT) == 0 || *(pstate[j]->pitem) != p0)
375f600bb80Smckusick 	continue;
376f600bb80Smckusick 
377f600bb80Smckusick       /*
378f600bb80Smckusick        * Check that enumeration and reduce lookaheads are the same.
379f600bb80Smckusick        */
380f600bb80Smckusick       if ((stateflags[i]&(GENLAMBDA|NEEDSREDUCE)) == (GENLAMBDA|NEEDSREDUCE)) {
381f600bb80Smckusick 	/*
382f600bb80Smckusick 	 * p0 derives lambda.
383f600bb80Smckusick 	 * state[i] needs full reduce lookahead
384f600bb80Smckusick 	 * state[j] has full reduce lookahead
385f600bb80Smckusick 	 */
386f600bb80Smckusick 	if ((stateflags[j] & NEEDSREDUCE) == 0)
387f600bb80Smckusick 	  error("state %d does not need full reduce", j);
388f600bb80Smckusick 	if (lambdarule < 0)
389f600bb80Smckusick 	  error("missing lambda rule definition in state %d", i);
390f600bb80Smckusick 	if (lookstate[j] == 0)
391f600bb80Smckusick 	  error("state %d lookahead was not saved", j);
392f600bb80Smckusick 	/* must check lookaheads */
393f600bb80Smckusick 	for (k = 0; k < tbitset; ++k)
394f600bb80Smckusick 	  if (lastate[lookstate[j]].lset[k] != wsets[lambdarule].ws[k])
395f600bb80Smckusick 	    /* cannot merge states */ goto nextj;
396f600bb80Smckusick       }
397f600bb80Smckusick 
398f600bb80Smckusick       /* we have a match with state j ! */
399f600bb80Smckusick 
400f600bb80Smckusick       if( cdebug ){
401f600bb80Smckusick 	settty();
402f600bb80Smckusick 	fprintf( cout , "state %d matches state %d\n", i, j);
403f600bb80Smckusick       }
404f600bb80Smckusick       tystate[i] = -j;
405f600bb80Smckusick       zzacsave += tystate[j];
406f600bb80Smckusick       zznsave++;
407f600bb80Smckusick       wrstate(i);
408f600bb80Smckusick       /* merged, so no need for future consideration */
409f600bb80Smckusick       stateflags[i] = 0;
410f600bb80Smckusick       return;
411f600bb80Smckusick 
412f600bb80Smckusick     nextj:  ;
413f600bb80Smckusick       }
414f600bb80Smckusick 
415f600bb80Smckusick 
416f600bb80Smckusick   standard:
417f600bb80Smckusick     tystate[i] = 2;
418f600bb80Smckusick     wrstate(i);
419f600bb80Smckusick     if ((stateflags[i] & (SINGLE_NT|NEEDSREDUCE|GENLAMBDA)) ==
420f600bb80Smckusick 	(SINGLE_NT|NEEDSREDUCE|GENLAMBDA)) {
421f600bb80Smckusick       if (savedlook + 1 >= maxlastate) {
422f600bb80Smckusick 	settty();
423f600bb80Smckusick 	fprintf(cout,
424f600bb80Smckusick 	  "Warning: _maxlastate too small (%d), state packing impared\n",
425f600bb80Smckusick 	  maxlastate);
426f600bb80Smckusick 	/* cannot consider future merger with this state */
427f600bb80Smckusick 	stateflags[i] = 0;
428f600bb80Smckusick       } else {
429f600bb80Smckusick 	if( cdebug ){
430f600bb80Smckusick 	  settty();
431f600bb80Smckusick 	  fprintf( cout , "save lookahead for state %d\n", i);
432f600bb80Smckusick 	}
433f600bb80Smckusick 	lookstate[i] = savedlook;
434f600bb80Smckusick 	for (k = 0; k < tbitset; ++k)
435f600bb80Smckusick 	  lastate[savedlook].lset[k] = wsets[lambdarule].ws[k];
436f600bb80Smckusick 	savedlook++;
437f600bb80Smckusick       }
438f600bb80Smckusick     }
439f600bb80Smckusick 
440f600bb80Smckusick     size = 0;
441f600bb80Smckusick     for( p0=1; p0<=nterms; ++p0 )
442f600bb80Smckusick       if( (p1=temp1[p0])!=0 ) {
443f600bb80Smckusick 	/***** UCB MOD - test actions are negative of symbol to be tested
444f600bb80Smckusick 			 this speeds up the parser as it is easy to check for
445f600bb80Smckusick 	 *****/
446f600bb80Smckusick         arrval( -trmset[p0].value );
447f600bb80Smckusick         if( p1 < 0 ) arrval( REDUCACT - p1 );
448f600bb80Smckusick         else if( p1 == ACCEPTCODE ) arrval( ACCEPTACT );
449f600bb80Smckusick         else if( p1 == ERRCODE ) arrval( ERRACT );
450f600bb80Smckusick         else arrval( SHIFTACT + p1 );
451f600bb80Smckusick         size += 2;
452f600bb80Smckusick         }
453f600bb80Smckusick     if( lastred ) arrval( REDUCACT + lastred );
454f600bb80Smckusick     else arrval( ERRACT );
455f600bb80Smckusick     tystate[i] = size+1; /* store entry size in tystate */
456f600bb80Smckusick     zzacent += (size+1);
457f600bb80Smckusick     return;
458f600bb80Smckusick   }
459f600bb80Smckusick 
wrstate(i)460f600bb80Smckusick wrstate(i){ /* writes state i */
461f600bb80Smckusick 	int j0,j1,s;
462f600bb80Smckusick         struct item *pp, *qq;
463f600bb80Smckusick 	settty();
464f600bb80Smckusick 	fprintf( cout , "\nstate %d\n",i);
465f600bb80Smckusick 	qq = pstate[i+1];
466f600bb80Smckusick 	for( pp=pstate[i]; pp<qq; ++pp) fprintf( cout , "\t%s\n", writem(pp));
467f600bb80Smckusick 
468f600bb80Smckusick         /* check for state equal to another */
469f600bb80Smckusick 
470f600bb80Smckusick         if( tystate[i] <= 0 ){
471f600bb80Smckusick           fprintf( cout , "\n\tsame as %d\n\n", -tystate[i] );
472f600bb80Smckusick           return;
473f600bb80Smckusick           }
474f600bb80Smckusick 
475f600bb80Smckusick 	for( j0=1; j0<=nterms; ++j0 ) if( (j1=temp1[j0]) != 0 ){
476f600bb80Smckusick 	fprintf( cout , "\n\t%s  ", symnam(j0) );
477f600bb80Smckusick              if( j1>0 ){ /* shift, error, or accept */
478f600bb80Smckusick                if( j1 == ACCEPTCODE ) fprintf( cout ,  "accept" );
479f600bb80Smckusick                else if( j1 == ERRCODE ) fprintf( cout ,  "error" );
480f600bb80Smckusick                else fprintf( cout ,  "shift %d", j1 );
481f600bb80Smckusick                }
482f600bb80Smckusick 		   else fprintf( cout , "reduce %d",-j1 );
483f600bb80Smckusick 	   }
484f600bb80Smckusick 
485f600bb80Smckusick 	/* output the final production */
486f600bb80Smckusick 
487f600bb80Smckusick 	if( lastred ) fprintf( cout , "\n\t.  reduce %d\n\n", lastred );
488f600bb80Smckusick 	else fprintf( cout , "\n\t.  error\n\n" );
489f600bb80Smckusick 
490f600bb80Smckusick ret:
491f600bb80Smckusick 	settab();
492f600bb80Smckusick 	}
493