2 * Copyright (c) 1989 The Regents of the University of California.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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 * 4. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 static char sccsid[] = "@(#)mkpar.c 5.3 (Berkeley) 1/20/91";
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
58 static action *add_reduce(action *, int, int);
59 static action *add_reductions(int, action *);
60 static void defreds(void);
61 static void find_final_state(void);
62 static void free_action_row(action *);
63 static action *get_shifts(int);
64 static action *parse_actions(int);
65 static void remove_conflicts(void);
66 static int sole_reduction(int);
67 static void total_conflicts(void);
68 static void unused_rules(void);
76 parser = NEW2(nstates, action *);
77 for (i = 0; i < nstates; i++)
78 parser[i] = parse_actions(i);
83 if (SRtotal + RRtotal > 0) total_conflicts();
89 parse_actions(int stateno)
93 actions = get_shifts(stateno);
94 actions = add_reductions(stateno, actions);
100 get_shifts(int stateno)
102 action *actions, *temp;
109 sp = shift_table[stateno];
113 for (i = sp->nshifts - 1; i >= 0; i--)
116 symbol = accessing_symbol[k];
120 temp->next = actions;
121 temp->symbol = symbol;
123 temp->prec = symbol_prec[symbol];
124 temp->action_code = SHIFT;
125 temp->assoc = symbol_assoc[symbol];
134 add_reductions(int stateno, action *actions)
137 int ruleno, tokensetsize;
140 tokensetsize = WORDSIZE(ntokens);
141 m = lookaheads[stateno];
142 n = lookaheads[stateno + 1];
143 for (i = m; i < n; i++)
145 ruleno = LAruleno[i];
146 rowp = LA + i * tokensetsize;
147 for (j = ntokens - 1; j >= 0; j--)
150 actions = add_reduce(actions, ruleno, j);
158 add_reduce(action *actions, int ruleno, int symbol)
160 action *temp, *prev, *next;
163 for (next = actions; next && next->symbol < symbol; next = next->next)
166 while (next && next->symbol == symbol && next->action_code == SHIFT)
172 while (next && next->symbol == symbol &&
173 next->action_code == REDUCE && next->number < ruleno)
181 temp->symbol = symbol;
182 temp->number = ruleno;
183 temp->prec = rprec[ruleno];
184 temp->action_code = REDUCE;
185 temp->assoc = rassoc[ruleno];
197 find_final_state(void)
206 for (i = p->nshifts - 1; i >= 0; --i)
208 final_state = tostate[i];
209 if (accessing_symbol[final_state] == goal) break;
220 rules_used = malloc(nrules*sizeof(short));
221 if (rules_used == 0) no_space();
223 for (i = 0; i < nrules; ++i)
226 for (i = 0; i < nstates; ++i)
228 for (p = parser[i]; p; p = p->next)
230 if (p->action_code == REDUCE && p->suppressed == 0)
231 rules_used[p->number] = 1;
236 for (i = 3; i < nrules; ++i)
237 if (!rules_used[i]) ++nunused;
241 warnx("1 rule never reduced");
243 warnx("%d rules never reduced", nunused);
249 remove_conflicts(void)
258 SRconflicts = NEW2(nstates, short);
259 RRconflicts = NEW2(nstates, short);
260 for (i = 0; i < nstates; i++)
265 for (p = parser[i]; p; p = p->next)
267 if (p->symbol != symbol)
272 else if (i == final_state && symbol == 0)
277 else if (pref->action_code == SHIFT)
279 if (pref->prec > 0 && p->prec > 0)
281 if (pref->prec < p->prec)
283 pref->suppressed = 2;
286 else if (pref->prec > p->prec)
290 else if (pref->assoc == LEFT)
292 pref->suppressed = 2;
295 else if (pref->assoc == RIGHT)
301 pref->suppressed = 2;
319 SRconflicts[i] = SRcount;
320 RRconflicts[i] = RRcount;
326 total_conflicts(void)
328 /* Warn if s/r != expect or if any r/r */
329 if ((SRtotal != SRexpect) || RRtotal)
332 warnx("1 shift/reduce conflict");
333 else if (SRtotal > 1)
334 warnx("%d shift/reduce conflicts", SRtotal);
338 warnx("1 reduce/reduce conflict");
339 else if (RRtotal > 1)
340 warnx("%d reduce/reduce conflicts", RRtotal);
345 sole_reduction(int stateno)
352 for (p = parser[stateno]; p; p = p->next)
354 if (p->action_code == SHIFT && p->suppressed == 0)
356 else if (p->action_code == REDUCE && p->suppressed == 0)
358 if (ruleno > 0 && p->number != ruleno)
377 defred = NEW2(nstates, short);
378 for (i = 0; i < nstates; i++)
379 defred[i] = sole_reduction(i);
383 free_action_row(action *p)
400 for (i = 0; i < nstates; i++)
401 free_action_row(parser[i]);