Bell 32V development
[unix-history] / usr / src / cmd / yacc / y3.c
CommitLineData
337dae54
TL
1# include "dextern"
2
3 /* important local variables */
4int lastred; /* the number of the last reduction of a state */
5int defact[NSTATES]; /* the default actions of states */
6
7output(){ /* print the output for the states */
8
9 int i, k, c;
10 register struct wset *u, *v;
11
12 fprintf( ftable, "short yyexca[] ={\n" );
13
14 SLOOP(i) { /* output the stuff for state i */
15 nolook = !(tystate[i]==MUSTLOOKAHEAD);
16 closure(i);
17 /* output actions */
18 nolook = 1;
19 aryfil( temp1, ntokens+nnonter+1, 0 );
20 WSLOOP(wsets,u){
21 c = *( u->pitem );
22 if( c>1 && c<NTBASE && temp1[c]==0 ) {
23 WSLOOP(u,v){
24 if( c == *(v->pitem) ) putitem( v->pitem+1, (struct looksets *)0 );
25 }
26 temp1[c] = state(c);
27 }
28 else if( c > NTBASE && temp1[ (c -= NTBASE) + ntokens ] == 0 ){
29 temp1[ c+ntokens ] = amem[indgo[i]+c];
30 }
31 }
32
33 if( i == 1 ) temp1[1] = ACCEPTCODE;
34
35 /* now, we have the shifts; look at the reductions */
36
37 lastred = 0;
38 WSLOOP(wsets,u){
39 c = *( u->pitem );
40 if( c<=0 ){ /* reduction */
41 lastred = -c;
42 TLOOP(k){
43 if( BIT(u->ws.lset,k) ){
44 if( temp1[k] == 0 ) temp1[k] = c;
45 else if( temp1[k]<0 ){ /* reduce/reduce conflict */
46 if( foutput!=NULL )
47 fprintf( foutput,
48 "\n%d: reduce/reduce conflict (red'ns %d and %d ) on %s",
49 i, -temp1[k], lastred, symnam(k) );
50 if( -temp1[k] > lastred ) temp1[k] = -lastred;
51 ++zzrrconf;
52 }
53 else { /* potential shift/reduce conflict */
54 precftn( lastred, k, i );
55 }
56 }
57 }
58 }
59 }
60 wract(i);
61 }
62
63 fprintf( ftable, "\t};\n" );
64
65 wdef( "YYNPROD", nprod );
66
67 }
68
69int pkdebug = 0;
70apack(p, n ) int *p;{ /* pack state i from temp1 into amem */
71 int off;
72 register *pp, *qq, *rr;
73 int *q, *r;
74
75 /* we don't need to worry about checking because we
76 we will only look entries known to be there... */
77
78 /* eliminate leading and trailing 0's */
79
80 q = p+n;
81 for( pp=p,off=0 ; *pp==0 && pp<=q; ++pp,--off ) /* VOID */ ;
82 if( pp > q ) return(0); /* no actions */
83 p = pp;
84
85 /* now, find a place for the elements from p to q, inclusive */
86
87 r = &amem[ACTSIZE-1];
88 for( rr=amem; rr<=r; ++rr,++off ){ /* try rr */
89 for( qq=rr,pp=p ; pp<=q ; ++pp,++qq){
90 if( *pp != 0 ){
91 if( *pp != *qq && *qq != 0 ) goto nextk;
92 }
93 }
94
95 /* we have found an acceptable k */
96
97 if( pkdebug && foutput!=NULL ) fprintf( foutput, "off = %d, k = %d\n", off, rr-amem );
98
99 for( qq=rr,pp=p; pp<=q; ++pp,++qq ){
100 if( *pp ){
101 if( qq > r ) error( "action table overflow" );
102 if( qq>memp ) memp = qq;
103 *qq = *pp;
104 }
105 }
106 if( pkdebug && foutput!=NULL ){
107 for( pp=amem; pp<= memp; pp+=10 ){
108 fprintf( foutput, "\t");
109 for( qq=pp; qq<=pp+9; ++qq ) fprintf( foutput, "%d ", *qq );
110 fprintf( foutput, "\n");
111 }
112 }
113 return( off );
114
115 nextk: ;
116 }
117 error("no space in action table" );
118 /* NOTREACHED */
119 }
120
121go2out(){ /* output the gotos for the nontermninals */
122 int i, j, k, best, count, cbest, times;
123
124 fprintf( ftemp, "$\n" ); /* mark begining of gotos */
125
126 for( i=1; i<=nnonter; ++i ) {
127 go2gen(i);
128
129 /* find the best one to make default */
130
131 best = -1;
132 times = 0;
133
134 for( j=0; j<=nstate; ++j ){ /* is j the most frequent */
135 if( tystate[j] == 0 ) continue;
136 if( tystate[j] == best ) continue;
137
138 /* is tystate[j] the most frequent */
139
140 count = 0;
141 cbest = tystate[j];
142
143 for( k=j; k<=nstate; ++k ) if( tystate[k]==cbest ) ++count;
144
145 if( count > times ){
146 best = cbest;
147 times = count;
148 }
149 }
150
151 /* best is now the default entry */
152
153 zzgobest += (times-1);
154 for( j=0; j<=nstate; ++j ){
155 if( tystate[j] != 0 && tystate[j]!=best ){
156 fprintf( ftemp, "%d,%d,", j, tystate[j] );
157 zzgoent += 1;
158 }
159 }
160
161 /* now, the default */
162
163 zzgoent += 1;
164 fprintf( ftemp, "%d\n", best );
165
166 }
167
168
169
170 }
171
172int g2debug = 0;
173go2gen(c){ /* output the gotos for nonterminal c */
174
175 int i, work, cc;
176 struct item *p, *q;
177
178
179 /* first, find nonterminals with gotos on c */
180
181 aryfil( temp1, nnonter+1, 0 );
182 temp1[c] = 1;
183
184 work = 1;
185 while( work ){
186 work = 0;
187 PLOOP(0,i){
188 if( (cc=prdptr[i][1]-NTBASE) >= 0 ){ /* cc is a nonterminal */
189 if( temp1[cc] != 0 ){ /* cc has a goto on c */
190 cc = *prdptr[i]-NTBASE; /* thus, the left side of production i does too */
191 if( temp1[cc] == 0 ){
192 work = 1;
193 temp1[cc] = 1;
194 }
195 }
196 }
197 }
198 }
199
200 /* now, we have temp1[c] = 1 if a goto on c in closure of cc */
201
202 if( g2debug && foutput!=NULL ){
203 fprintf( foutput, "%s: gotos on ", nontrst[c].name );
204 NTLOOP(i) if( temp1[i] ) fprintf( foutput, "%s ", nontrst[i].name);
205 fprintf( foutput, "\n");
206 }
207
208 /* now, go through and put gotos into tystate */
209
210 aryfil( tystate, nstate, 0 );
211 SLOOP(i){
212 ITMLOOP(i,p,q){
213 if( (cc= *p->pitem) >= NTBASE ){
214 if( temp1[cc -= NTBASE] ){ /* goto on c is possible */
215 tystate[i] = amem[indgo[i]+c];
216 break;
217 }
218 }
219 }
220 }
221 }
222
223precftn(r,t,s){ /* decide a shift/reduce conflict by precedence.
224 /* r is a rule number, t a token number */
225 /* the conflict is in state s */
226 /* temp1[t] is changed to reflect the action */
227
228 int lp,lt, action;
229
230 lp = levprd[r];
231 lt = toklev[t];
232 if( PLEVEL(lt) == 0 || PLEVEL(lp) == 0 ) {
233 /* conflict */
234 if( foutput != NULL ) fprintf( foutput, "\n%d: shift/reduce conflict (shift %d, red'n %d) on %s",
235 s, temp1[t], r, symnam(t) );
236 ++zzsrconf;
237 return;
238 }
239 if( PLEVEL(lt) == PLEVEL(lp) ) action = ASSOC(lt);
240 else if( PLEVEL(lt) > PLEVEL(lp) ) action = RASC; /* shift */
241 else action = LASC; /* reduce */
242
243 switch( action ){
244
245 case BASC: /* error action */
246 temp1[t] = ERRCODE;
247 return;
248
249 case LASC: /* reduce */
250 temp1[t] = -r;
251 return;
252
253 }
254 }
255
256wract(i){ /* output state i */
257 /* temp1 has the actions, lastred the default */
258 int p, p0, p1;
259 int ntimes, tred, count, j;
260 int flag;
261
262 /* find the best choice for lastred */
263
264 lastred = 0;
265 ntimes = 0;
266 TLOOP(j){
267 if( temp1[j] >= 0 ) continue;
268 if( temp1[j]+lastred == 0 ) continue;
269 /* count the number of appearances of temp1[j] */
270 count = 0;
271 tred = -temp1[j];
272 levprd[tred] |= REDFLAG;
273 TLOOP(p){
274 if( temp1[p]+tred == 0 ) ++count;
275 }
276 if( count >ntimes ){
277 lastred = tred;
278 ntimes = count;
279 }
280 }
281
282 /* for error recovery, arrange that, if there is a shift on the
283 /* error recovery token, `error', that the default be the error action */
284 if( temp1[1] > 0 ) lastred = 0;
285
286 /* clear out entries in temp1 which equal lastred */
287 TLOOP(p) if( temp1[p]+lastred == 0 )temp1[p]=0;
288
289 wrstate(i);
290 defact[i] = lastred;
291
292 flag = 0;
293 TLOOP(p0){
294 if( (p1=temp1[p0])!=0 ) {
295 if( p1 < 0 ){
296 p1 = -p1;
297 goto exc;
298 }
299 else if( p1 == ACCEPTCODE ) {
300 p1 = -1;
301 goto exc;
302 }
303 else if( p1 == ERRCODE ) {
304 p1 = 0;
305 goto exc;
306 exc:
307 if( flag++ == 0 ) fprintf( ftable, "-1, %d,\n", i );
308 fprintf( ftable, "\t%d, %d,\n", tokset[p0].value, p1 );
309 ++zzexcp;
310 }
311 else {
312 fprintf( ftemp, "%d,%d,", tokset[p0].value, p1 );
313 ++zzacent;
314 }
315 }
316 }
317 if( flag ) {
318 defact[i] = -2;
319 fprintf( ftable, "\t-2, %d,\n", lastred );
320 }
321 fprintf( ftemp, "\n" );
322 return;
323 }
324
325wrstate(i){ /* writes state i */
326 register j0,j1;
327 register struct item *pp, *qq;
328 register struct wset *u;
329
330 if( foutput == NULL ) return;
331 fprintf( foutput, "\nstate %d\n",i);
332 ITMLOOP(i,pp,qq) fprintf( foutput, "\t%s\n", writem(pp->pitem));
333 if( tystate[i] == MUSTLOOKAHEAD ){
334 /* print out empty productions in closure */
335 WSLOOP( wsets+(pstate[i+1]-pstate[i]), u ){
336 if( *(u->pitem) < 0 ) fprintf( foutput, "\t%s\n", writem(u->pitem) );
337 }
338 }
339
340 /* check for state equal to another */
341
342 TLOOP(j0) if( (j1=temp1[j0]) != 0 ){
343 fprintf( foutput, "\n\t%s ", symnam(j0) );
344 if( j1>0 ){ /* shift, error, or accept */
345 if( j1 == ACCEPTCODE ) fprintf( foutput, "accept" );
346 else if( j1 == ERRCODE ) fprintf( foutput, "error" );
347 else fprintf( foutput, "shift %d", j1 );
348 }
349 else fprintf( foutput, "reduce %d",-j1 );
350 }
351
352 /* output the final production */
353
354 if( lastred ) fprintf( foutput, "\n\t. reduce %d\n\n", lastred );
355 else fprintf( foutput, "\n\t. error\n\n" );
356
357 /* now, output nonterminal actions */
358
359 j1 = ntokens;
360 for( j0 = 1; j0 <= nnonter; ++j0 ){
361 if( temp1[++j1] ) fprintf( foutput, "\t%s goto %d\n", symnam( j0+NTBASE), temp1[j1] );
362 }
363
364 }
365
366wdef( s, n ) char *s; { /* output a definition of s to the value n */
367 fprintf( ftable, "# define %s %d\n", s, n );
368 }
369
370warray( s, v, n ) char *s; int *v, n; {
371
372 register i;
373
374 fprintf( ftable, "short %s[]={\n", s );
375 for( i=0; i<n; ){
376 if( i%10 == 0 ) fprintf( ftable, "\n" );
377 fprintf( ftable, "%4d", v[i] );
378 if( ++i == n ) fprintf( ftable, " };\n" );
379 else fprintf( ftable, "," );
380 }
381 }
382
383hideprod(){
384 /* in order to free up the mem and amem arrays for the optimizer,
385 /* and still be able to output yyr1, etc., after the sizes of
386 /* the action array is known, we hide the nonterminals
387 /* derived by productions in levprd.
388 */
389
390 register i, j;
391
392 j = 0;
393 levprd[0] = 0;
394 PLOOP(1,i){
395 if( !(levprd[i] & REDFLAG) ){
396 ++j;
397 if( foutput != NULL ){
398 fprintf( foutput, "Rule not reduced: %s\n", writem( prdptr[i] ) );
399 }
400 }
401 levprd[i] = *prdptr[i] - NTBASE;
402 }
403 if( j ) fprintf( stdout, "%d rules never reduced\n", j );
404 }