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 * 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
36 * @(#)mkpar.c 5.3 (Berkeley) 1/20/91
37 * $FreeBSD: src/usr.bin/yacc/mkpar.c,v 1.10 1999/08/28 01:08:01 peter Exp $
38 * $DragonFly: src/usr.bin/yacc/mkpar.c,v 1.2 2003/06/17 04:29:34 dillon Exp $
58 static action *add_reduce __P((action *, int, int));
59 static action *add_reductions __P((int, action *));
60 static void defreds __P((void));
61 static void find_final_state __P((void));
62 static void free_action_row __P((action *));
63 static action *get_shifts __P((int));
64 static action *parse_actions __P((int));
65 static void remove_conflicts __P((void));
66 static int sole_reduction __P((int));
67 static void total_conflicts __P((void));
68 static void unused_rules __P((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(stateno)
92 register action *actions;
94 actions = get_shifts(stateno);
95 actions = add_reductions(stateno, actions);
104 register action *actions, *temp;
106 register short *to_state;
111 sp = shift_table[stateno];
114 to_state = sp->shift;
115 for (i = sp->nshifts - 1; i >= 0; i--)
118 symbol = accessing_symbol[k];
122 temp->next = actions;
123 temp->symbol = symbol;
125 temp->prec = symbol_prec[symbol];
126 temp->action_code = SHIFT;
127 temp->assoc = symbol_assoc[symbol];
136 add_reductions(stateno, actions)
138 register action *actions;
140 register int i, j, m, n;
141 register int ruleno, tokensetsize;
142 register unsigned *rowp;
144 tokensetsize = WORDSIZE(ntokens);
145 m = lookaheads[stateno];
146 n = lookaheads[stateno + 1];
147 for (i = m; i < n; i++)
149 ruleno = LAruleno[i];
150 rowp = LA + i * tokensetsize;
151 for (j = ntokens - 1; j >= 0; j--)
154 actions = add_reduce(actions, ruleno, j);
162 add_reduce(actions, ruleno, symbol)
163 register action *actions;
164 register int ruleno, symbol;
166 register action *temp, *prev, *next;
169 for (next = actions; next && next->symbol < symbol; next = next->next)
172 while (next && next->symbol == symbol && next->action_code == SHIFT)
178 while (next && next->symbol == symbol &&
179 next->action_code == REDUCE && next->number < ruleno)
187 temp->symbol = symbol;
188 temp->number = ruleno;
189 temp->prec = rprec[ruleno];
190 temp->action_code = REDUCE;
191 temp->assoc = rassoc[ruleno];
205 register int goal, i;
206 register short *to_state;
212 for (i = p->nshifts - 1; i >= 0; --i)
214 final_state = to_state[i];
215 if (accessing_symbol[final_state] == goal) break;
226 rules_used = (short *) MALLOC(nrules*sizeof(short));
227 if (rules_used == 0) no_space();
229 for (i = 0; i < nrules; ++i)
232 for (i = 0; i < nstates; ++i)
234 for (p = parser[i]; p; p = p->next)
236 if (p->action_code == REDUCE && p->suppressed == 0)
237 rules_used[p->number] = 1;
242 for (i = 3; i < nrules; ++i)
243 if (!rules_used[i]) ++nunused;
247 warnx("1 rule never reduced");
249 warnx("%d rules never reduced", nunused);
259 register action *p, *pref = NULL;
263 SRconflicts = NEW2(nstates, short);
264 RRconflicts = NEW2(nstates, short);
265 for (i = 0; i < nstates; i++)
270 for (p = parser[i]; p; p = p->next)
272 if (p->symbol != symbol)
277 else if (i == final_state && symbol == 0)
282 else if (pref->action_code == SHIFT)
284 if (pref->prec > 0 && p->prec > 0)
286 if (pref->prec < p->prec)
288 pref->suppressed = 2;
291 else if (pref->prec > p->prec)
295 else if (pref->assoc == LEFT)
297 pref->suppressed = 2;
300 else if (pref->assoc == RIGHT)
306 pref->suppressed = 2;
324 SRconflicts[i] = SRcount;
325 RRconflicts[i] = RRcount;
333 /* Warn if s/r != expect or if any r/r */
334 if ((SRtotal != SRexpect) || RRtotal)
337 warnx("1 shift/reduce conflict");
338 else if (SRtotal > 1)
339 warnx("%d shift/reduce conflicts", SRtotal);
343 warnx("1 reduce/reduce conflict");
344 else if (RRtotal > 1)
345 warnx("%d reduce/reduce conflicts", RRtotal);
350 sole_reduction(stateno)
353 register int count, ruleno;
358 for (p = parser[stateno]; p; p = p->next)
360 if (p->action_code == SHIFT && p->suppressed == 0)
362 else if (p->action_code == REDUCE && p->suppressed == 0)
364 if (ruleno > 0 && p->number != ruleno)
383 defred = NEW2(nstates, short);
384 for (i = 0; i < nstates; i++)
385 defred[i] = sole_reduction(i);
407 for (i = 0; i < nstates; i++)
408 free_action_row(parser[i]);