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