2010-01-03 Zoltan Varga <vargaz@gmail.com>
[mcs.git] / jay / mkpar.c
blob42ead14514d5c4b68daed0d1277a9d21e1333aa4
1 /*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Robert Paul Corbett.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
37 #ifndef lint
38 static char sccsid[] = "@(#)mkpar.c 5.3 (Berkeley) 1/20/91";
39 #endif /* not lint */
41 #include "defs.h"
43 action **parser;
44 int SRtotal;
45 int RRtotal;
46 short *SRconflicts;
47 short *RRconflicts;
48 short *defred;
49 short *rules_used;
50 short nunused;
51 short final_state;
53 static int SRcount;
54 static int RRcount;
56 extern action *parse_actions();
57 extern action *get_shifts();
58 extern action *add_reductions();
59 extern action *add_reduce();
62 make_parser()
64 register int i;
66 parser = NEW2(nstates, action *);
67 for (i = 0; i < nstates; i++)
68 parser[i] = parse_actions(i);
70 find_final_state();
71 remove_conflicts();
72 unused_rules();
73 if (SRtotal + RRtotal > 0) total_conflicts();
74 defreds();
78 action *
79 parse_actions(stateno)
80 register int stateno;
82 register action *actions;
84 actions = get_shifts(stateno);
85 actions = add_reductions(stateno, actions);
86 return (actions);
90 action *
91 get_shifts(stateno)
92 int stateno;
94 register action *actions, *temp;
95 register shifts *sp;
96 register short *to_state;
97 register int i, k;
98 register int symbol;
100 actions = 0;
101 sp = shift_table[stateno];
102 if (sp)
104 to_state = sp->shift;
105 for (i = sp->nshifts - 1; i >= 0; i--)
107 k = to_state[i];
108 symbol = accessing_symbol[k];
109 if (ISTOKEN(symbol))
111 temp = NEW(action);
112 temp->next = actions;
113 temp->symbol = symbol;
114 temp->number = k;
115 temp->prec = symbol_prec[symbol];
116 temp->action_code = SHIFT;
117 temp->assoc = symbol_assoc[symbol];
118 actions = temp;
122 return (actions);
125 action *
126 add_reductions(stateno, actions)
127 int stateno;
128 register action *actions;
130 register int i, j, m, n;
131 register int ruleno, tokensetsize;
132 register unsigned *rowp;
134 tokensetsize = WORDSIZE(ntokens);
135 m = lookaheads[stateno];
136 n = lookaheads[stateno + 1];
137 for (i = m; i < n; i++)
139 ruleno = LAruleno[i];
140 rowp = LA + i * tokensetsize;
141 for (j = ntokens - 1; j >= 0; j--)
143 if (BIT(rowp, j))
144 actions = add_reduce(actions, ruleno, j);
147 return (actions);
151 action *
152 add_reduce(actions, ruleno, symbol)
153 register action *actions;
154 register int ruleno, symbol;
156 register action *temp, *prev, *next;
158 prev = 0;
159 for (next = actions; next && next->symbol < symbol; next = next->next)
160 prev = next;
162 while (next && next->symbol == symbol && next->action_code == SHIFT)
164 prev = next;
165 next = next->next;
168 while (next && next->symbol == symbol &&
169 next->action_code == REDUCE && next->number < ruleno)
171 prev = next;
172 next = next->next;
175 temp = NEW(action);
176 temp->next = next;
177 temp->symbol = symbol;
178 temp->number = ruleno;
179 temp->prec = rprec[ruleno];
180 temp->action_code = REDUCE;
181 temp->assoc = rassoc[ruleno];
183 if (prev)
184 prev->next = temp;
185 else
186 actions = temp;
188 return (actions);
192 find_final_state()
194 register int goal, i;
195 register short *to_state;
196 register shifts *p;
198 p = shift_table[0];
199 to_state = p->shift;
200 goal = ritem[1];
201 for (i = p->nshifts - 1; i >= 0; --i)
203 final_state = to_state[i];
204 if (accessing_symbol[final_state] == goal) break;
209 unused_rules()
211 register int i;
212 register action *p;
214 rules_used = (short *) MALLOC(nrules*sizeof(short));
215 if (rules_used == 0) no_space();
217 for (i = 0; i < nrules; ++i)
218 rules_used[i] = 0;
220 for (i = 0; i < nstates; ++i)
222 for (p = parser[i]; p; p = p->next)
224 if (p->action_code == REDUCE && p->suppressed == 0)
225 rules_used[p->number] = 1;
229 nunused = 0;
230 for (i = 3; i < nrules; ++i)
231 if (!rules_used[i]) ++nunused;
233 if (nunused)
234 if (nunused == 1)
235 fprintf(stderr, "%s: 1 rule never reduced\n", myname);
236 else
237 fprintf(stderr, "%s: %d rules never reduced\n", myname, nunused);
241 remove_conflicts()
243 register int i;
244 register int symbol;
245 register action *p, *pref;
247 SRtotal = 0;
248 RRtotal = 0;
249 SRconflicts = NEW2(nstates, short);
250 RRconflicts = NEW2(nstates, short);
251 for (i = 0; i < nstates; i++)
253 SRcount = 0;
254 RRcount = 0;
255 symbol = -1;
256 for (p = parser[i]; p; p = p->next)
258 if (p->symbol != symbol)
260 pref = p;
261 symbol = p->symbol;
263 else if (i == final_state && symbol == 0)
265 SRcount++;
266 p->suppressed = 1;
268 else if (pref->action_code == SHIFT)
270 if (pref->prec > 0 && p->prec > 0)
272 if (pref->prec < p->prec)
274 pref->suppressed = 2;
275 pref = p;
277 else if (pref->prec > p->prec)
279 p->suppressed = 2;
281 else if (pref->assoc == LEFT)
283 pref->suppressed = 2;
284 pref = p;
286 else if (pref->assoc == RIGHT)
288 p->suppressed = 2;
290 else
292 pref->suppressed = 2;
293 p->suppressed = 2;
296 else
298 SRcount++;
299 p->suppressed = 1;
302 else
304 RRcount++;
305 p->suppressed = 1;
308 SRtotal += SRcount;
309 RRtotal += RRcount;
310 SRconflicts[i] = SRcount;
311 RRconflicts[i] = RRcount;
316 total_conflicts()
318 fprintf(stderr, "%s: ", myname);
319 if (SRtotal == 1)
320 fprintf(stderr, "1 shift/reduce conflict");
321 else if (SRtotal > 1)
322 fprintf(stderr, "%d shift/reduce conflicts", SRtotal);
324 if (SRtotal && RRtotal)
325 fprintf(stderr, ", ");
327 if (RRtotal == 1)
328 fprintf(stderr, "1 reduce/reduce conflict");
329 else if (RRtotal > 1)
330 fprintf(stderr, "%d reduce/reduce conflicts", RRtotal);
332 fprintf(stderr, ".\n");
337 sole_reduction(stateno)
338 int stateno;
340 register int count, ruleno;
341 register action *p;
343 count = 0;
344 ruleno = 0;
345 for (p = parser[stateno]; p; p = p->next)
347 if (p->action_code == SHIFT && p->suppressed == 0)
348 return (0);
349 else if (p->action_code == REDUCE && p->suppressed == 0)
351 if (ruleno > 0 && p->number != ruleno)
352 return (0);
353 if (p->symbol != 1)
354 ++count;
355 ruleno = p->number;
359 if (count == 0)
360 return (0);
361 return (ruleno);
365 defreds()
367 register int i;
369 defred = NEW2(nstates, short);
370 for (i = 0; i < nstates; i++)
371 defred[i] = sole_reduction(i);
374 free_action_row(p)
375 register action *p;
377 register action *q;
379 while (p)
381 q = p->next;
382 FREE(p);
383 p = q;
387 free_parser()
389 register int i;
391 for (i = 0; i < nstates; i++)
392 free_action_row(parser[i]);
394 FREE(parser);