don't bother resolving onbld python module deps
[unleashed.git] / bin / yacc / mkpar.c
blob14f2dbf3d0da51fd92c13c5b09569ffa7f4e8d28
1 /* $OpenBSD: mkpar.c,v 1.19 2017/05/25 20:11:03 tedu Exp $ */
2 /* $NetBSD: mkpar.c,v 1.4 1996/03/19 03:21:39 jtc Exp $ */
4 /*
5 * Copyright (c) 1989 The Regents of the University of California.
6 * All rights reserved.
8 * This code is derived from software contributed to Berkeley by
9 * Robert Paul Corbett.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
36 #include "defs.h"
38 action **parser;
39 int SRtotal;
40 int SRexpect = 0;
41 int RRtotal;
42 short *SRconflicts;
43 short *RRconflicts;
44 short *defred;
45 short *rules_used;
46 short nunused;
47 short final_state;
49 static int SRcount;
50 static int RRcount;
52 extern action *parse_actions(int);
53 extern action *get_shifts(int);
54 extern action *add_reductions(int, action *);
55 extern action *add_reduce(action *, int, int);
57 short sole_reduction(int);
58 void free_action_row(action *);
60 void find_final_state(void);
61 void unused_rules(void);
62 void remove_conflicts(void);
63 void total_conflicts(void);
64 void defreds(void);
67 void
68 make_parser(void)
70 int i;
72 parser = NEW2(nstates, action *);
73 for (i = 0; i < nstates; i++)
74 parser[i] = parse_actions(i);
76 find_final_state();
77 remove_conflicts();
78 unused_rules();
79 if (SRtotal + RRtotal > 0)
80 total_conflicts();
81 defreds();
85 action *
86 parse_actions(int stateno)
88 action *actions;
90 actions = get_shifts(stateno);
91 actions = add_reductions(stateno, actions);
92 return (actions);
96 action *
97 get_shifts(int stateno)
99 action *actions, *temp;
100 shifts *sp;
101 short *tto_state;
102 int i, k;
103 int symbol;
105 actions = 0;
106 sp = shift_table[stateno];
107 if (sp) {
108 tto_state = sp->shift;
109 for (i = sp->nshifts - 1; i >= 0; i--) {
110 k = tto_state[i];
111 symbol = accessing_symbol[k];
112 if (ISTOKEN(symbol)) {
113 temp = NEW(action);
114 temp->next = actions;
115 temp->symbol = symbol;
116 temp->number = k;
117 temp->prec = symbol_prec[symbol];
118 temp->action_code = SHIFT;
119 temp->assoc = symbol_assoc[symbol];
120 actions = temp;
124 return (actions);
127 action *
128 add_reductions(int stateno, action * actions)
130 int i, j, m, n;
131 int ruleno, tokensetsize;
132 unsigned *rowp;
134 tokensetsize = WORDSIZE(ntokens);
135 m = lookaheads[stateno];
136 n = lookaheads[stateno + 1];
137 for (i = m; i < n; i++) {
138 ruleno = LAruleno[i];
139 rowp = LA + i * tokensetsize;
140 for (j = ntokens - 1; j >= 0; j--) {
141 if (BIT(rowp, j))
142 actions = add_reduce(actions, ruleno, j);
145 return (actions);
149 action *
150 add_reduce(action * actions, int ruleno, int symbol)
152 action *temp, *prev, *next;
154 prev = 0;
155 for (next = actions; next && next->symbol < symbol; next = next->next)
156 prev = next;
158 while (next && next->symbol == symbol && next->action_code == SHIFT) {
159 prev = next;
160 next = next->next;
163 while (next && next->symbol == symbol &&
164 next->action_code == REDUCE && next->number < ruleno) {
165 prev = next;
166 next = next->next;
169 temp = NEW(action);
170 temp->next = next;
171 temp->symbol = symbol;
172 temp->number = ruleno;
173 temp->prec = rprec[ruleno];
174 temp->action_code = REDUCE;
175 temp->assoc = rassoc[ruleno];
177 if (prev)
178 prev->next = temp;
179 else
180 actions = temp;
182 return (actions);
186 void
187 find_final_state(void)
189 int goal, i;
190 short *tto_state;
191 shifts *p;
193 p = shift_table[0];
194 tto_state = p->shift;
195 goal = ritem[1];
196 for (i = p->nshifts - 1; i >= 0; --i) {
197 final_state = tto_state[i];
198 if (accessing_symbol[final_state] == goal)
199 break;
204 void
205 unused_rules(void)
207 int i;
208 action *p;
210 rules_used = calloc(nrules, sizeof(short));
211 if (rules_used == NULL)
212 no_space();
214 for (i = 0; i < nstates; ++i) {
215 for (p = parser[i]; p; p = p->next) {
216 if (p->action_code == REDUCE && p->suppressed == 0)
217 rules_used[p->number] = 1;
221 nunused = 0;
222 for (i = 3; i < nrules; ++i)
223 if (!rules_used[i])
224 ++nunused;
226 if (nunused) {
227 if (nunused == 1)
228 fprintf(stderr, "%s: 1 rule never reduced\n", __progname);
229 else
230 fprintf(stderr, "%s: %d rules never reduced\n", __progname,
231 nunused);
236 void
237 remove_conflicts(void)
239 int i;
240 int symbol;
241 action *p, *pref = NULL;
243 SRtotal = 0;
244 RRtotal = 0;
245 SRconflicts = NEW2(nstates, short);
246 RRconflicts = NEW2(nstates, short);
247 for (i = 0; i < nstates; i++) {
248 SRcount = 0;
249 RRcount = 0;
250 symbol = -1;
251 for (p = parser[i]; p; p = p->next) {
252 if (p->symbol != symbol) {
253 pref = p;
254 symbol = p->symbol;
255 } else if (i == final_state && symbol == 0) {
256 SRcount++;
257 p->suppressed = 1;
258 } else if (pref->action_code == SHIFT) {
259 if (pref->prec > 0 && p->prec > 0) {
260 if (pref->prec < p->prec) {
261 pref->suppressed = 2;
262 pref = p;
263 } else if (pref->prec > p->prec) {
264 p->suppressed = 2;
265 } else if (pref->assoc == LEFT) {
266 pref->suppressed = 2;
267 pref = p;
268 } else if (pref->assoc == RIGHT) {
269 p->suppressed = 2;
270 } else {
271 pref->suppressed = 2;
272 p->suppressed = 2;
274 } else {
275 SRcount++;
276 p->suppressed = 1;
278 } else {
279 RRcount++;
280 p->suppressed = 1;
283 SRtotal += SRcount;
284 RRtotal += RRcount;
285 SRconflicts[i] = SRcount;
286 RRconflicts[i] = RRcount;
291 void
292 total_conflicts(void)
294 /* Warn if s/r != expect or if any r/r */
295 if ((SRtotal != SRexpect) || RRtotal) {
296 if (SRtotal == 1)
297 fprintf(stderr, "%s: %s finds 1 shift/reduce conflict\n",
298 input_file_name, __progname);
299 else if (SRtotal > 1)
300 fprintf(stderr, "%s: %s finds %d shift/reduce conflicts\n",
301 input_file_name, __progname, SRtotal);
303 if (RRtotal == 1)
304 fprintf(stderr, "%s: %s finds 1 reduce/reduce conflict\n",
305 input_file_name, __progname);
306 else if (RRtotal > 1)
307 fprintf(stderr, "%s: %s finds %d reduce/reduce conflicts\n",
308 input_file_name, __progname, RRtotal);
312 short
313 sole_reduction(int stateno)
315 int count;
316 short ruleno;
317 action *p;
319 count = 0;
320 ruleno = 0;
321 for (p = parser[stateno]; p; p = p->next) {
322 if (p->action_code == SHIFT && p->suppressed == 0)
323 return (0);
324 else if (p->action_code == REDUCE && p->suppressed == 0) {
325 if (ruleno > 0 && p->number != ruleno)
326 return (0);
327 if (p->symbol != 1)
328 ++count;
329 ruleno = p->number;
333 if (count == 0)
334 return (0);
335 return (ruleno);
339 void
340 defreds(void)
342 int i;
344 defred = NEW2(nstates, short);
345 for (i = 0; i < nstates; i++)
346 defred[i] = sole_reduction(i);
349 void
350 free_action_row(action * p)
352 action *q;
354 while (p) {
355 q = p->next;
356 free(p);
357 p = q;
361 void
362 free_parser(void)
364 int i;
366 for (i = 0; i < nstates; i++)
367 free_action_row(parser[i]);
369 free(parser);