xref: /csrg-svn/usr.bin/pascal/eyacc/ey4.c (revision 62087)
147968Sbostic /*-
2*62087Sbostic  * Copyright (c) 1979, 1993
3*62087Sbostic  *	The Regents of the University of California.  All rights reserved.
447968Sbostic  *
547968Sbostic  * %sccs.include.proprietary.c%
619573Smckusick  */
719573Smckusick 
819573Smckusick #ifndef lint
9*62087Sbostic static char sccsid[] = "@(#)ey4.c	8.1 (Berkeley) 06/06/93";
1047968Sbostic #endif /* not lint */
1119573Smckusick 
1219573Smckusick # include "ey.h"
1319573Smckusick 
output()1419573Smckusick output(){ /* print the output for the states */
1519573Smckusick 
1619573Smckusick   int i, j, k, c;
1719573Smckusick 
1819573Smckusick   settab();
1919573Smckusick   arrset("yyact");
2019573Smckusick 
2119573Smckusick   for( i=0; i<nstate; ++i ){ /* output the stuff for state i */
2219573Smckusick     nolook = (tystate[i]==0);
2319573Smckusick     closure(i);
2419573Smckusick     /* output actions */
2519573Smckusick     aryfil( temp1, nterms+1, 0 );
2619573Smckusick     for( j=0; j<cwset; ++j ){ /* look at the items */
2719573Smckusick       c = *( wsets[j].pitem );
2819573Smckusick       if( c>0 && c<NTBASE && temp1[c]==0 ) temp1[c] = go2(i,c);
2919573Smckusick       }
3019573Smckusick 
3119573Smckusick     if( i == 1 ) temp1[1] = ACCEPTCODE;
3219573Smckusick 
3319573Smckusick     /* now, we have the shifts; look at the reductions */
3419573Smckusick 
3519573Smckusick     lastred = 0;
3619573Smckusick     for( j=0; j<cwset; ++j ){
3719573Smckusick       c = *( wsets[j].pitem );
3819573Smckusick       if( c<=0 ){ /* reduction */
3919573Smckusick         lastred = -c;
4019573Smckusick         for( k=1; k<=nterms; ++k ){
4119573Smckusick           if( ((wsets[j].ws[k>>4])&(1<<(k&017))) != 0 ) {
4219573Smckusick             if( temp1[k] == 0 ) temp1[k] = c;
4319573Smckusick             else if( temp1[k]<0 ){ /* reduce/reduce conflict */
4419573Smckusick               settty();
4519573Smckusick               fprintf( cout , "\n%d: reduce/reduce conflict (red'ns %d and %d ) on %s",
4619573Smckusick                 i, -temp1[k], lastred, symnam(k) );
4719573Smckusick               if( -temp1[k] > lastred ) temp1[k] = -lastred;
4819573Smckusick               ++zzrrconf;
4919573Smckusick               settab();
5019573Smckusick               }
5119573Smckusick             else { /* potential shift/reduce conflict */
5219573Smckusick               switch( precftn( lastred, k ) ) {
5319573Smckusick 
5419573Smckusick             case 0: /* precedence does not apply */
5519573Smckusick 
5619573Smckusick                 settty();
5719573Smckusick                 fprintf( cout , "\n%d: shift/reduce conflict (shift %d, red'n %d) on %s", i,
5819573Smckusick 			temp1[k], lastred, symnam(k) );
5919573Smckusick                 ++zzsrconf;
6019573Smckusick                 settab();
6119573Smckusick 		/* resolve in favor of shifting, so remove from reduce set */
6219573Smckusick 		wsets[j].ws[k>>4] &=~ (1<<(k&017));
6319573Smckusick                 break;
6419573Smckusick 
6519573Smckusick             case 1: /*  reduce */
6619573Smckusick 
6719573Smckusick                 temp1[k] = -lastred;
6819573Smckusick                 break;
6919573Smckusick 
7019573Smckusick             case 2: /* error, binary operator */
7119573Smckusick 
7219573Smckusick                 temp1[k] = ERRCODE;
7319573Smckusick                 break;
7419573Smckusick 
7519573Smckusick             case 3: /* shift ... leave the entry alone */
7619573Smckusick 
7719573Smckusick                 break;
7819573Smckusick                 }
7919573Smckusick               }
8019573Smckusick             }
8119573Smckusick           }
8219573Smckusick         }
8319573Smckusick       }
8419573Smckusick     wract(i);
8519573Smckusick     }
8619573Smckusick 
8719573Smckusick   settab();
8819573Smckusick   arrdone();
8919573Smckusick 
9019573Smckusick   /* now, output the pointers to the action array */
9119573Smckusick   /* also output the info about reductions */
9219573Smckusick   prred();
9319573Smckusick   }
9419573Smckusick 
prred()9519573Smckusick prred(){ /* print the information about the actions and the reductions */
9619573Smckusick   int index, i;
9719573Smckusick 
9819573Smckusick   arrset("yypact");
9919573Smckusick   index = 1;    /* position in the output table */
10019573Smckusick 
10119573Smckusick   for( i=0; i<nstate; ++i ){
10219573Smckusick     if( tystate[i]>0 ){  /* the state is real */
10319573Smckusick       temp1[i] = index;
10419573Smckusick       arrval( index );
10519573Smckusick       index += tystate[i];
10619573Smckusick       }
10719573Smckusick     else {
10819573Smckusick       arrval( temp1[-tystate[i]] );
10919573Smckusick       }
11019573Smckusick     }
11119573Smckusick 
11219573Smckusick   arrdone();
11319573Smckusick 
11419573Smckusick   arrset("yyr1");
11519573Smckusick   for( i=1; i<nprod; ++i ) arrval( *prdptr[i] - NTBASE );
11619573Smckusick   arrdone();
11719573Smckusick 
11819573Smckusick   arrset("yyr2");
11919573Smckusick   for( i=1; i<nprod; ++i ) arrval( ( prdptr[i+1]-prdptr[i]-2 ) );
12019573Smckusick   arrdone();
12119573Smckusick 
12219573Smckusick   }
12319573Smckusick 
go2(i,c)12419573Smckusick go2(i,c){ /* do a goto on the closure state, not worrying about lookaheads */
12519573Smckusick   if( c<NTBASE ) return( amem[ apstate[i]+c ] );
12619573Smckusick   else return( amem[ apstate[i] + c - NTBASE + nterms ] );
12719573Smckusick   }
12819573Smckusick 
12919573Smckusick int pkdebug = 0;
apack(p,n)13019573Smckusick apack(p, n ) int *p;{ /* pack state i from temp1 into amem */
13119573Smckusick   _REGISTER k, l, off;
13219573Smckusick   int j;
13319573Smckusick 
13419573Smckusick   /* find the spot */
13519573Smckusick 
13619573Smckusick   j = n;
13719573Smckusick   for( off = 0; off <= j && p[off] == 0; ++off ) ;
13819573Smckusick   if( off > j ){ /* no actions */
13919573Smckusick     return(0);
14019573Smckusick     }
14119573Smckusick   j -= off;
14219573Smckusick   for( k=0; k<actsiz; ++k ){
14319573Smckusick     for( l=0; l<=j; ++l ){
14419573Smckusick       if( p[off+l] != 0 ){
14519573Smckusick         if( p[off+l] != amem[k+l] && amem[k+l] != 0 ) goto nextk;
14619573Smckusick         }
14719573Smckusick       }
14819573Smckusick     if( pkdebug ){ settty(); fprintf( cout , "off = %d, k = %d\n", off, k ); }
14919573Smckusick     /* we have found an acceptable k */
15019573Smckusick     for( l=0; l<=j; ++l ){
15119573Smckusick       if( p[off+l] ){
15219573Smckusick         if( k+l >= actsiz ) error("action table overflow");
15319573Smckusick         if( k+l >= memact ) memact = k+l;
15419573Smckusick         amem[k+l] = p[off+l];
15519573Smckusick         }
15619573Smckusick       }
15719573Smckusick     if( pkdebug ){
15819573Smckusick       for( k=0; k<memact; k+=10){
15919573Smckusick         fprintf( cout , "\t");
16019573Smckusick         for( l=0; l<=9; ++l ) fprintf( cout , "%d ", amem[k+l] );
16119573Smckusick         fprintf( cout , "\n");
16219573Smckusick         }
16319573Smckusick       }
16419573Smckusick     return(k-off);
16519573Smckusick 
16619573Smckusick     nextk: ;
16719573Smckusick     }
16819573Smckusick   error("no space in action table");
16919573Smckusick   }
17019573Smckusick 
go2out()17119573Smckusick go2out(){ /* output the gotos for the nontermninals */
17219573Smckusick   int i, j, k, best, offset, count, cbest, times;
17319573Smckusick 
17419573Smckusick   settab();
17519573Smckusick   arrset("yygo");
17619573Smckusick   offset = 1;
17719573Smckusick 
17819573Smckusick   for( i=1; i<=nnonter; ++i ) {
17919573Smckusick     go2gen(i);
18019573Smckusick 
18119573Smckusick     /* find the best one to make default */
18219573Smckusick 
18319573Smckusick     temp2[i] = offset;
18419573Smckusick 
18519573Smckusick     best = -1;
18619573Smckusick     times = 0;
18719573Smckusick 
18819573Smckusick     for( j=0; j<=nstate; ++j ){ /* is j the most frequent */
18919573Smckusick       if( tystate[j] == 0 ) continue;
19019573Smckusick       if( tystate[j] == best ) continue;
19119573Smckusick 
19219573Smckusick       /* is tystate[j] the most frequent */
19319573Smckusick 
19419573Smckusick       count = 0;
19519573Smckusick       cbest = tystate[j];
19619573Smckusick 
19719573Smckusick       for( k=j; k<=nstate; ++k ) if( tystate[k]==cbest ) ++count;
19819573Smckusick 
19919573Smckusick       if( count > times ){
20019573Smckusick         best = cbest;
20119573Smckusick         times = count;
20219573Smckusick         }
20319573Smckusick       }
20419573Smckusick 
20519573Smckusick     /* best is now the default entry */
20619573Smckusick 
20719573Smckusick     zzgobest += (times-1)*2;
20819573Smckusick     settab();
20919573Smckusick     for( j=0; j<=nstate; ++j ){
21019573Smckusick       if( tystate[j] != 0 && tystate[j]!=best ){
21119573Smckusick         arrval( j );
21219573Smckusick         arrval( tystate[j] );
21319573Smckusick         offset += 2;
21419573Smckusick         zzgoent += 2;
21519573Smckusick         }
21619573Smckusick       }
21719573Smckusick 
21819573Smckusick     /* now, the default */
21919573Smckusick 
22019573Smckusick     zzgoent += 2;
22119573Smckusick     arrval( -1 );
22219573Smckusick     arrval( best );
22319573Smckusick     offset += 2;
22419573Smckusick 
22519573Smckusick     }
22619573Smckusick 
22719573Smckusick   arrdone();
22819573Smckusick 
22919573Smckusick   arrset("yypgo");
23019573Smckusick   for( i=1; i<=nnonter; ++i ) arrval( temp2[i] );
23119573Smckusick   arrdone();
23219573Smckusick 
23319573Smckusick   }
23419573Smckusick 
23519573Smckusick int g2debug = 0;
go2gen(c)23619573Smckusick go2gen(c){ /* output the gotos for nonterminal c */
23719573Smckusick 
23819573Smckusick   int i, work, cc;
23919573Smckusick   struct item *p, *q;
24019573Smckusick 
24119573Smckusick   /* first, find nonterminals with gotos on c */
24219573Smckusick 
24319573Smckusick   aryfil( temp1, nnonter+1, 0 );
24419573Smckusick   temp1[c] = 1;
24519573Smckusick 
24619573Smckusick   work = 1;
24719573Smckusick   while( work ){
24819573Smckusick     work = 0;
24919573Smckusick     for( i=0; i<nprod; ++i ){
25019573Smckusick       if( (cc=prdptr[i][1]-NTBASE) >= 0 ){ /* cc is a nonterminal */
25119573Smckusick         if( temp1[cc] != 0 ){ /* cc has a goto on c */
25219573Smckusick           cc = *prdptr[i]-NTBASE; /* thus, the left side of production i does too */
25319573Smckusick           if( temp1[cc] == 0 ){
25419573Smckusick             work = 1;
25519573Smckusick             temp1[cc] = 1;
25619573Smckusick             }
25719573Smckusick           }
25819573Smckusick         }
25919573Smckusick       }
26019573Smckusick     }
26119573Smckusick 
26219573Smckusick   /* now, we have temp1[c] = 1 if a goto on c in closure of cc */
26319573Smckusick 
26419573Smckusick   if( g2debug ){
26519573Smckusick     settty();
26619573Smckusick     fprintf( cout , "%s: gotos on ", nontrst[c].name );
26719573Smckusick     for( i=0; i<=nnonter; ++i ) if( temp1[i]) fprintf( cout , "%s ", nontrst[i].name);
26819573Smckusick     fprintf( cout , "\n");
26919573Smckusick     }
27019573Smckusick 
27119573Smckusick   /* now, go through and put gotos into tystate */
27219573Smckusick 
27319573Smckusick   aryfil( tystate, nstate, 0 );
27419573Smckusick   settty();
27519573Smckusick   fprintf( cout , "\nnonterminal %s\n", nontrst[c].name );
27619573Smckusick   for( i=0; i<nstate; ++i ){
27719573Smckusick     q = pstate[i+1];
27819573Smckusick     for( p=pstate[i]; p<q; ++p ){
27919573Smckusick       if( (cc= *p->pitem) >= NTBASE ){
28019573Smckusick         if( temp1[cc -= NTBASE] ){ /* goto on c is possible */
28119573Smckusick           tystate[i] = amem[indgo[i]+c];
28219573Smckusick           break;
28319573Smckusick           }
28419573Smckusick         }
28519573Smckusick       }
28619573Smckusick     if( tystate[i] ) fprintf( cout , "\t%d\t%d\n", i, tystate[i]);
28719573Smckusick     }
28819573Smckusick   }
28919573Smckusick 
precftn(r,t)29019573Smckusick precftn(r,t){ /* decide a shift/reduce conflict by precedence.
29119573Smckusick 			Returns 0 if action is 'do nothing',1 if action is reduce,
29219573Smckusick 			2 if the action is 'error,binary operator'
29319573Smckusick 			and 3 if the action is 'reduce'. */
29419573Smckusick 
29519573Smckusick 	int lp,lt;
29619573Smckusick 	lp = levprd[r];
29719573Smckusick 	lt = trmlev[t];
29819573Smckusick 	if ((lt==0)||((lp&03)==0))return(0);
29919573Smckusick 	if((lt>>3) == (lp>>3)){
30019573Smckusick 		return(lt&03);
30119573Smckusick 		}
30219573Smckusick 	if((lt>>3) > (lp>>3)) return(3);
30319573Smckusick 	return(1);
30419573Smckusick 	}
30519573Smckusick 
30619573Smckusick int cdebug = 0; /* debug for common states */
wract(i)30719573Smckusick wract(i){ /* output state i */
30819573Smckusick   /* temp1 has the actions, lastred the default */
30919573Smckusick   int p, p0, p1, size;
31019573Smckusick   int ntimes, tred, count, j, k;
31119573Smckusick   struct item *q0, *q1;
31219573Smckusick 
31319573Smckusick   /* find the best choice for lastred */
31419573Smckusick 
31519573Smckusick   lastred = 0;
31619573Smckusick   ntimes = 0;
31719573Smckusick   stateflags[i] = 0;
31819573Smckusick   /***** UCB MOD - full state spec if shift on error *****/
31919573Smckusick   if (temp1[2] > 0)
32019573Smckusick     stateflags[i] |= NEEDSREDUCE;
32119573Smckusick   else for( j=1; j<=nterms; ++j ){
32219573Smckusick     /* find the entry on which the greatest number of reductions are done */
32319573Smckusick     if( temp1[j] >= 0 ) continue;
32419573Smckusick     if( temp1[j]+lastred == 0 ) continue;
32519573Smckusick     /* count the number of appearances of temp1[j] */
32619573Smckusick     count = 0;
32719573Smckusick     tred = -temp1[j];
32819573Smckusick     for( p=1; p<=nterms; ++p ){
32919573Smckusick       if( temp1[p]+tred == 0 ) ++count;
33019573Smckusick       }
33119573Smckusick     if( count >ntimes ){
33219573Smckusick       lastred = tred;
33319573Smckusick       ntimes = count;
33419573Smckusick       }
33519573Smckusick     }
33619573Smckusick 
33719573Smckusick     /* clear out entries in temp1 which equal lastred */
33819573Smckusick     /* ie, make the most frequent reduction into the default reduction */
33919573Smckusick     for( p=1; p<= nterms; ++p ) if( temp1[p]+lastred == 0 )temp1[p]=0;
34019573Smckusick 
34119573Smckusick     /* write out the state */
34219573Smckusick 
34319573Smckusick     /* first, check for equality with another state */
34419573Smckusick     /* see if there is a nonterminal with all dots before it, */
34519573Smckusick     /* and no reductions in the state */
34619573Smckusick     /* this is done by checking if all items are the same non-terminal */
34719573Smckusick     p0 = 0;
34819573Smckusick     q1 = pstate[i+1];
34919573Smckusick     for( q0=pstate[i]; q0<q1; ++q0 ){
35019573Smckusick       if( (p1= *(q0->pitem) ) < NTBASE ) goto standard;
35119573Smckusick       if( p0 == 0 ) p0 = p1;
35219573Smckusick       else if( p0 != p1 ) goto standard;
35319573Smckusick       }
35419573Smckusick     stateflags[i] |= SINGLE_NT | pempty[p0 - NTBASE];
35519573Smckusick 
35619573Smckusick     /* now, all items have dots before p0 */
35719573Smckusick     if( cdebug ){
35819573Smckusick       settty();
35919573Smckusick       fprintf( cout , "state %d, pre-nonterminal %s\n",i,nontrst[p0-NTBASE].name);
36019573Smckusick       }
36119573Smckusick 
36219573Smckusick     for( j=0; j<i; ++j ){
36319573Smckusick       /*
36419573Smckusick        * check that the states have the same shift lookaheads.
36519573Smckusick        */
36619573Smckusick       if( apstate[i] != apstate[j] )
36719573Smckusick 	continue;
36819573Smckusick       if (cdebug)
36919573Smckusick 	fprintf(cout, "states %d and %d have same shift lookaheads\n",i,j);
37019573Smckusick 
37119573Smckusick       /*
37219573Smckusick        * Check that state has one item, and that the item matches.
37319573Smckusick        */
37419573Smckusick       if ((stateflags[j] & SINGLE_NT) == 0 || *(pstate[j]->pitem) != p0)
37519573Smckusick 	continue;
37619573Smckusick 
37719573Smckusick       /*
37819573Smckusick        * Check that enumeration and reduce lookaheads are the same.
37919573Smckusick        */
38019573Smckusick       if ((stateflags[i]&(GENLAMBDA|NEEDSREDUCE)) == (GENLAMBDA|NEEDSREDUCE)) {
38119573Smckusick 	/*
38219573Smckusick 	 * p0 derives lambda.
38319573Smckusick 	 * state[i] needs full reduce lookahead
38419573Smckusick 	 * state[j] has full reduce lookahead
38519573Smckusick 	 */
38619573Smckusick 	if ((stateflags[j] & NEEDSREDUCE) == 0)
38719573Smckusick 	  error("state %d does not need full reduce", j);
38819573Smckusick 	if (lambdarule < 0)
38919573Smckusick 	  error("missing lambda rule definition in state %d", i);
39019573Smckusick 	if (lookstate[j] == 0)
39119573Smckusick 	  error("state %d lookahead was not saved", j);
39219573Smckusick 	/* must check lookaheads */
39319573Smckusick 	for (k = 0; k < tbitset; ++k)
39419573Smckusick 	  if (lastate[lookstate[j]].lset[k] != wsets[lambdarule].ws[k])
39519573Smckusick 	    /* cannot merge states */ goto nextj;
39619573Smckusick       }
39719573Smckusick 
39819573Smckusick       /* we have a match with state j ! */
39919573Smckusick 
40019573Smckusick       if( cdebug ){
40119573Smckusick 	settty();
40219573Smckusick 	fprintf( cout , "state %d matches state %d\n", i, j);
40319573Smckusick       }
40419573Smckusick       tystate[i] = -j;
40519573Smckusick       zzacsave += tystate[j];
40619573Smckusick       zznsave++;
40719573Smckusick       wrstate(i);
40819573Smckusick       /* merged, so no need for future consideration */
40919573Smckusick       stateflags[i] = 0;
41019573Smckusick       return;
41119573Smckusick 
41219573Smckusick     nextj:  ;
41319573Smckusick       }
41419573Smckusick 
41519573Smckusick 
41619573Smckusick   standard:
41719573Smckusick     tystate[i] = 2;
41819573Smckusick     wrstate(i);
41919573Smckusick     if ((stateflags[i] & (SINGLE_NT|NEEDSREDUCE|GENLAMBDA)) ==
42019573Smckusick 	(SINGLE_NT|NEEDSREDUCE|GENLAMBDA)) {
42119573Smckusick       if (savedlook + 1 >= maxlastate) {
42219573Smckusick 	settty();
42319573Smckusick 	fprintf(cout,
42419573Smckusick 	  "Warning: _maxlastate too small (%d), state packing impared\n",
42519573Smckusick 	  maxlastate);
42619573Smckusick 	/* cannot consider future merger with this state */
42719573Smckusick 	stateflags[i] = 0;
42819573Smckusick       } else {
42919573Smckusick 	if( cdebug ){
43019573Smckusick 	  settty();
43119573Smckusick 	  fprintf( cout , "save lookahead for state %d\n", i);
43219573Smckusick 	}
43319573Smckusick 	lookstate[i] = savedlook;
43419573Smckusick 	for (k = 0; k < tbitset; ++k)
43519573Smckusick 	  lastate[savedlook].lset[k] = wsets[lambdarule].ws[k];
43619573Smckusick 	savedlook++;
43719573Smckusick       }
43819573Smckusick     }
43919573Smckusick 
44019573Smckusick     size = 0;
44119573Smckusick     for( p0=1; p0<=nterms; ++p0 )
44219573Smckusick       if( (p1=temp1[p0])!=0 ) {
44319573Smckusick 	/***** UCB MOD - test actions are negative of symbol to be tested
44419573Smckusick 			 this speeds up the parser as it is easy to check for
44519573Smckusick 	 *****/
44619573Smckusick         arrval( -trmset[p0].value );
44719573Smckusick         if( p1 < 0 ) arrval( REDUCACT - p1 );
44819573Smckusick         else if( p1 == ACCEPTCODE ) arrval( ACCEPTACT );
44919573Smckusick         else if( p1 == ERRCODE ) arrval( ERRACT );
45019573Smckusick         else arrval( SHIFTACT + p1 );
45119573Smckusick         size += 2;
45219573Smckusick         }
45319573Smckusick     if( lastred ) arrval( REDUCACT + lastred );
45419573Smckusick     else arrval( ERRACT );
45519573Smckusick     tystate[i] = size+1; /* store entry size in tystate */
45619573Smckusick     zzacent += (size+1);
45719573Smckusick     return;
45819573Smckusick   }
45919573Smckusick 
wrstate(i)46019573Smckusick wrstate(i){ /* writes state i */
46119573Smckusick 	int j0,j1,s;
46219573Smckusick         struct item *pp, *qq;
46319573Smckusick 	settty();
46419573Smckusick 	fprintf( cout , "\nstate %d\n",i);
46519573Smckusick 	qq = pstate[i+1];
46619573Smckusick 	for( pp=pstate[i]; pp<qq; ++pp) fprintf( cout , "\t%s\n", writem(pp));
46719573Smckusick 
46819573Smckusick         /* check for state equal to another */
46919573Smckusick 
47019573Smckusick         if( tystate[i] <= 0 ){
47119573Smckusick           fprintf( cout , "\n\tsame as %d\n\n", -tystate[i] );
47219573Smckusick           return;
47319573Smckusick           }
47419573Smckusick 
47519573Smckusick 	for( j0=1; j0<=nterms; ++j0 ) if( (j1=temp1[j0]) != 0 ){
47619573Smckusick 	fprintf( cout , "\n\t%s  ", symnam(j0) );
47719573Smckusick              if( j1>0 ){ /* shift, error, or accept */
47819573Smckusick                if( j1 == ACCEPTCODE ) fprintf( cout ,  "accept" );
47919573Smckusick                else if( j1 == ERRCODE ) fprintf( cout ,  "error" );
48019573Smckusick                else fprintf( cout ,  "shift %d", j1 );
48119573Smckusick                }
48219573Smckusick 		   else fprintf( cout , "reduce %d",-j1 );
48319573Smckusick 	   }
48419573Smckusick 
48519573Smckusick 	/* output the final production */
48619573Smckusick 
48719573Smckusick 	if( lastred ) fprintf( cout , "\n\t.  reduce %d\n\n", lastred );
48819573Smckusick 	else fprintf( cout , "\n\t.  error\n\n" );
48919573Smckusick 
49019573Smckusick ret:
49119573Smckusick 	settab();
49219573Smckusick 	}
493