Fix up mix of man(7)/mdoc(7).
[netbsd-mini2440.git] / usr.bin / yacc / mkpar.c
blob2f0821a548f23e48d91057d2f1464f333cfa347c
1 /* $NetBSD: mkpar.c,v 1.11 2006/05/24 18:01:43 christos Exp $ */
3 /*
4 * Copyright (c) 1989 The Regents of the University of California.
5 * All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Robert Paul Corbett.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
35 #include <sys/cdefs.h>
36 #if defined(__RCSID) && !defined(lint)
37 #if 0
38 static char sccsid[] = "@(#)mkpar.c 5.3 (Berkeley) 1/20/91";
39 #else
40 __RCSID("$NetBSD: mkpar.c,v 1.11 2006/05/24 18:01:43 christos Exp $");
41 #endif
42 #endif /* not lint */
44 #include "defs.h"
46 action **parser;
47 int SRtotal;
48 int RRtotal;
49 short *SRconflicts;
50 short *RRconflicts;
51 short *defred;
52 short *rules_used;
53 short nunused;
54 short final_state;
56 static int SRcount;
57 static int RRcount;
59 static action *parse_actions(int);
60 static action *get_shifts(int);
61 static action *add_reductions(int, action *);
62 static action *add_reduce(action *, int, int);
64 static int sole_reduction(int);
65 static void free_action_row(action *);
67 static void find_final_state(void);
68 static void unused_rules(void);
69 static void remove_conflicts(void);
70 static void total_conflicts(void);
71 static void defreds(void);
74 void
75 make_parser(void)
77 int i;
79 parser = NEW2(nstates, action *);
80 for (i = 0; i < nstates; i++)
81 parser[i] = parse_actions(i);
83 find_final_state();
84 remove_conflicts();
85 unused_rules();
86 if (SRtotal + RRtotal > 0) total_conflicts();
87 defreds();
91 static action *
92 parse_actions(int stateno)
94 action *actions;
96 actions = get_shifts(stateno);
97 actions = add_reductions(stateno, actions);
98 return (actions);
102 static action *
103 get_shifts(int stateno)
105 action *actions, *temp;
106 shifts *sp;
107 short *state;
108 int i, k;
109 int symbol;
111 actions = 0;
112 sp = shift_table[stateno];
113 if (sp)
115 state = sp->shift;
116 for (i = sp->nshifts - 1; i >= 0; i--)
118 k = state[i];
119 symbol = accessing_symbol[k];
120 if (ISTOKEN(symbol))
122 temp = NEW(action);
123 temp->next = actions;
124 temp->symbol = symbol;
125 temp->number = k;
126 temp->prec = symbol_prec[symbol];
127 temp->action_code = SHIFT;
128 temp->assoc = symbol_assoc[symbol];
129 actions = temp;
133 return (actions);
136 static action *
137 add_reductions(int stateno, action *actions)
139 int i, j, m, n;
140 int ruleno, tokensetsize;
141 unsigned *rowp;
143 tokensetsize = WORDSIZE(ntokens);
144 m = lookaheads[stateno];
145 n = lookaheads[stateno + 1];
146 for (i = m; i < n; i++)
148 ruleno = LAruleno[i];
149 rowp = LA + i * tokensetsize;
150 for (j = ntokens - 1; j >= 0; j--)
152 if (BIT(rowp, j))
153 actions = add_reduce(actions, ruleno, j);
156 return (actions);
160 static action *
161 add_reduce(action *actions, int ruleno, int symbol)
163 action *temp, *prev, *next;
165 prev = 0;
166 for (next = actions; next && next->symbol < symbol; next = next->next)
167 prev = next;
169 while (next && next->symbol == symbol && next->action_code == SHIFT)
171 prev = next;
172 next = next->next;
175 while (next && next->symbol == symbol &&
176 next->action_code == REDUCE && next->number < ruleno)
178 prev = next;
179 next = next->next;
182 temp = NEW(action);
183 temp->next = next;
184 temp->symbol = symbol;
185 temp->number = ruleno;
186 temp->prec = rprec[ruleno];
187 temp->action_code = REDUCE;
188 temp->assoc = rassoc[ruleno];
190 if (prev)
191 prev->next = temp;
192 else
193 actions = temp;
195 return (actions);
199 static void
200 find_final_state(void)
202 int goal, i;
203 short *state;
204 shifts *p;
206 p = shift_table[0];
207 state = p->shift;
208 goal = ritem[1];
209 for (i = p->nshifts - 1; i >= 0; --i)
211 final_state = state[i];
212 if (accessing_symbol[final_state] == goal) break;
217 static void
218 unused_rules(void)
220 int i;
221 action *p;
223 rules_used = (short *) MALLOC(nrules*sizeof(short));
224 if (rules_used == 0) no_space();
226 for (i = 0; i < nrules; ++i)
227 rules_used[i] = 0;
229 for (i = 0; i < nstates; ++i)
231 for (p = parser[i]; p; p = p->next)
233 if (p->action_code == REDUCE && p->suppressed == 0)
234 rules_used[p->number] = 1;
238 nunused = 0;
239 for (i = 3; i < nrules; ++i)
240 if (!rules_used[i]) ++nunused;
242 if (nunused) {
243 if (nunused == 1)
244 fprintf(stderr, "%s: 1 rule never reduced\n", myname);
245 else
246 fprintf(stderr, "%s: %d rules never reduced\n", myname, nunused);
251 static void
252 remove_conflicts(void)
254 int i;
255 int symbol;
256 action *p, *pref;
258 pref = NULL;
259 SRtotal = 0;
260 RRtotal = 0;
261 SRconflicts = NEW2(nstates, short);
262 RRconflicts = NEW2(nstates, short);
263 for (i = 0; i < nstates; i++)
265 SRcount = 0;
266 RRcount = 0;
267 symbol = -1;
268 for (p = parser[i]; p; p = p->next)
270 if (p->symbol != symbol)
272 pref = p;
273 symbol = p->symbol;
275 else if (i == final_state && symbol == 0)
277 SRcount++;
278 p->suppressed = 1;
280 else
282 assert(pref != NULL);
283 if (pref->action_code == SHIFT)
285 if (pref->prec > 0 && p->prec > 0)
287 if (pref->prec < p->prec)
289 pref->suppressed = 2;
290 pref = p;
292 else if (pref->prec > p->prec)
294 p->suppressed = 2;
296 else if (pref->assoc == LEFT)
298 pref->suppressed = 2;
299 pref = p;
301 else if (pref->assoc == RIGHT)
303 p->suppressed = 2;
305 else
307 pref->suppressed = 2;
308 p->suppressed = 2;
311 else
313 SRcount++;
314 p->suppressed = 1;
317 else
319 RRcount++;
320 p->suppressed = 1;
324 SRtotal += SRcount;
325 RRtotal += RRcount;
326 SRconflicts[i] = SRcount;
327 RRconflicts[i] = RRcount;
332 static void
333 total_conflicts(void)
335 fprintf(stderr, "%s: ", myname);
336 if (SRtotal == 1)
337 fprintf(stderr, "1 shift/reduce conflict");
338 else if (SRtotal > 1)
339 fprintf(stderr, "%d shift/reduce conflicts", SRtotal);
341 if (SRtotal && RRtotal)
342 fprintf(stderr, ", ");
344 if (RRtotal == 1)
345 fprintf(stderr, "1 reduce/reduce conflict");
346 else if (RRtotal > 1)
347 fprintf(stderr, "%d reduce/reduce conflicts", RRtotal);
349 fprintf(stderr, ".\n");
353 static int
354 sole_reduction(int stateno)
356 int count, ruleno;
357 action *p;
359 count = 0;
360 ruleno = 0;
361 for (p = parser[stateno]; p; p = p->next)
363 if (p->action_code == SHIFT && p->suppressed == 0)
364 return (0);
365 else if (p->action_code == REDUCE && p->suppressed == 0)
367 if (ruleno > 0 && p->number != ruleno)
368 return (0);
369 if (p->symbol != 1)
370 ++count;
371 ruleno = p->number;
375 if (count == 0)
376 return (0);
377 return (ruleno);
381 static void
382 defreds(void)
384 int i;
386 defred = NEW2(nstates, short);
387 for (i = 0; i < nstates; i++)
388 defred[i] = sole_reduction(i);
391 static void
392 free_action_row(action *p)
394 action *q;
396 while (p)
398 q = p->next;
399 FREE(p);
400 p = q;
404 void
405 free_parser(void)
407 int i;
409 for (i = 0; i < nstates; i++)
410 free_action_row(parser[i]);
412 FREE(parser);