Merge branch 'vendor/BYACC'
[dragonfly.git] / contrib / byacc / mkpar.c
1 /* $Id: mkpar.c,v 1.12 2012/05/26 00:42:18 tom Exp $ */
2
3 #include "defs.h"
4
5 static action *add_reduce(action *actions, int ruleno, int symbol);
6 static action *add_reductions(int stateno, action *actions);
7 static action *get_shifts(int stateno);
8 static action *parse_actions(int stateno);
9 static int sole_reduction(int stateno);
10 static void defreds(void);
11 static void find_final_state(void);
12 static void free_action_row(action *p);
13 static void remove_conflicts(void);
14 static void total_conflicts(void);
15 static void unused_rules(void);
16
17 action **parser;
18
19 int SRexpect;
20 int RRexpect;
21
22 int SRtotal;
23 int RRtotal;
24
25 Value_t *SRconflicts;
26 Value_t *RRconflicts;
27 Value_t *defred;
28 Value_t *rules_used;
29 Value_t nunused;
30 Value_t final_state;
31
32 static Value_t SRcount;
33 static Value_t RRcount;
34
35 void
36 make_parser(void)
37 {
38     int i;
39
40     parser = NEW2(nstates, action *);
41     for (i = 0; i < nstates; i++)
42         parser[i] = parse_actions(i);
43
44     find_final_state();
45     remove_conflicts();
46     unused_rules();
47     if (SRtotal + RRtotal > 0)
48         total_conflicts();
49     defreds();
50 }
51
52 static action *
53 parse_actions(int stateno)
54 {
55     action *actions;
56
57     actions = get_shifts(stateno);
58     actions = add_reductions(stateno, actions);
59     return (actions);
60 }
61
62 static action *
63 get_shifts(int stateno)
64 {
65     action *actions, *temp;
66     shifts *sp;
67     Value_t *to_state2;
68     Value_t i, k;
69     Value_t symbol;
70
71     actions = 0;
72     sp = shift_table[stateno];
73     if (sp)
74     {
75         to_state2 = sp->shift;
76         for (i = (Value_t) (sp->nshifts - 1); i >= 0; i--)
77         {
78             k = to_state2[i];
79             symbol = accessing_symbol[k];
80             if (ISTOKEN(symbol))
81             {
82                 temp = NEW(action);
83                 temp->next = actions;
84                 temp->symbol = symbol;
85                 temp->number = k;
86                 temp->prec = symbol_prec[symbol];
87                 temp->action_code = SHIFT;
88                 temp->assoc = symbol_assoc[symbol];
89                 actions = temp;
90             }
91         }
92     }
93     return (actions);
94 }
95
96 static action *
97 add_reductions(int stateno, action *actions)
98 {
99     int i, j, m, n;
100     int ruleno, tokensetsize;
101     unsigned *rowp;
102
103     tokensetsize = WORDSIZE(ntokens);
104     m = lookaheads[stateno];
105     n = lookaheads[stateno + 1];
106     for (i = m; i < n; i++)
107     {
108         ruleno = LAruleno[i];
109         rowp = LA + i * tokensetsize;
110         for (j = ntokens - 1; j >= 0; j--)
111         {
112             if (BIT(rowp, j))
113                 actions = add_reduce(actions, ruleno, j);
114         }
115     }
116     return (actions);
117 }
118
119 static action *
120 add_reduce(action *actions,
121            int ruleno,
122            int symbol)
123 {
124     action *temp, *prev, *next;
125
126     prev = 0;
127     for (next = actions; next && next->symbol < symbol; next = next->next)
128         prev = next;
129
130     while (next && next->symbol == symbol && next->action_code == SHIFT)
131     {
132         prev = next;
133         next = next->next;
134     }
135
136     while (next && next->symbol == symbol &&
137            next->action_code == REDUCE && next->number < ruleno)
138     {
139         prev = next;
140         next = next->next;
141     }
142
143     temp = NEW(action);
144     temp->next = next;
145     temp->symbol = (Value_t) symbol;
146     temp->number = (Value_t) ruleno;
147     temp->prec = rprec[ruleno];
148     temp->action_code = REDUCE;
149     temp->assoc = rassoc[ruleno];
150
151     if (prev)
152         prev->next = temp;
153     else
154         actions = temp;
155
156     return (actions);
157 }
158
159 static void
160 find_final_state(void)
161 {
162     int goal, i;
163     Value_t *to_state2;
164     shifts *p;
165
166     p = shift_table[0];
167     to_state2 = p->shift;
168     goal = ritem[1];
169     for (i = p->nshifts - 1; i >= 0; --i)
170     {
171         final_state = to_state2[i];
172         if (accessing_symbol[final_state] == goal)
173             break;
174     }
175 }
176
177 static void
178 unused_rules(void)
179 {
180     int i;
181     action *p;
182
183     rules_used = TMALLOC(Value_t, nrules);
184     NO_SPACE(rules_used);
185
186     for (i = 0; i < nrules; ++i)
187         rules_used[i] = 0;
188
189     for (i = 0; i < nstates; ++i)
190     {
191         for (p = parser[i]; p; p = p->next)
192         {
193             if (p->action_code == REDUCE && p->suppressed == 0)
194                 rules_used[p->number] = 1;
195         }
196     }
197
198     nunused = 0;
199     for (i = 3; i < nrules; ++i)
200         if (!rules_used[i])
201             ++nunused;
202
203     if (nunused)
204     {
205         if (nunused == 1)
206             fprintf(stderr, "%s: 1 rule never reduced\n", myname);
207         else
208             fprintf(stderr, "%s: %d rules never reduced\n", myname, nunused);
209     }
210 }
211
212 static void
213 remove_conflicts(void)
214 {
215     int i;
216     int symbol;
217     action *p, *pref = 0;
218
219     SRtotal = 0;
220     RRtotal = 0;
221     SRconflicts = NEW2(nstates, Value_t);
222     RRconflicts = NEW2(nstates, Value_t);
223     for (i = 0; i < nstates; i++)
224     {
225         SRcount = 0;
226         RRcount = 0;
227         symbol = -1;
228         for (p = parser[i]; p; p = p->next)
229         {
230             if (p->symbol != symbol)
231             {
232                 pref = p;
233                 symbol = p->symbol;
234             }
235             else if (i == final_state && symbol == 0)
236             {
237                 SRcount++;
238                 p->suppressed = 1;
239             }
240             else if (pref != 0 && pref->action_code == SHIFT)
241             {
242                 if (pref->prec > 0 && p->prec > 0)
243                 {
244                     if (pref->prec < p->prec)
245                     {
246                         pref->suppressed = 2;
247                         pref = p;
248                     }
249                     else if (pref->prec > p->prec)
250                     {
251                         p->suppressed = 2;
252                     }
253                     else if (pref->assoc == LEFT)
254                     {
255                         pref->suppressed = 2;
256                         pref = p;
257                     }
258                     else if (pref->assoc == RIGHT)
259                     {
260                         p->suppressed = 2;
261                     }
262                     else
263                     {
264                         pref->suppressed = 2;
265                         p->suppressed = 2;
266                     }
267                 }
268                 else
269                 {
270                     SRcount++;
271                     p->suppressed = 1;
272                 }
273             }
274             else
275             {
276                 RRcount++;
277                 p->suppressed = 1;
278             }
279         }
280         SRtotal += SRcount;
281         RRtotal += RRcount;
282         SRconflicts[i] = SRcount;
283         RRconflicts[i] = RRcount;
284     }
285 }
286
287 static void
288 total_conflicts(void)
289 {
290     fprintf(stderr, "%s: ", myname);
291     if (SRtotal == 1)
292         fprintf(stderr, "1 shift/reduce conflict");
293     else if (SRtotal > 1)
294         fprintf(stderr, "%d shift/reduce conflicts", SRtotal);
295
296     if (SRtotal && RRtotal)
297         fprintf(stderr, ", ");
298
299     if (RRtotal == 1)
300         fprintf(stderr, "1 reduce/reduce conflict");
301     else if (RRtotal > 1)
302         fprintf(stderr, "%d reduce/reduce conflicts", RRtotal);
303
304     fprintf(stderr, ".\n");
305
306     if (SRexpect >= 0 && SRtotal != SRexpect)
307     {
308         fprintf(stderr, "%s: ", myname);
309         fprintf(stderr, "expected %d shift/reduce conflict%s.\n",
310                 SRexpect, PLURAL(SRexpect));
311         exit_code = EXIT_FAILURE;
312     }
313     if (RRexpect >= 0 && RRtotal != RRexpect)
314     {
315         fprintf(stderr, "%s: ", myname);
316         fprintf(stderr, "expected %d reduce/reduce conflict%s.\n",
317                 RRexpect, PLURAL(RRexpect));
318         exit_code = EXIT_FAILURE;
319     }
320 }
321
322 static int
323 sole_reduction(int stateno)
324 {
325     int count, ruleno;
326     action *p;
327
328     count = 0;
329     ruleno = 0;
330     for (p = parser[stateno]; p; p = p->next)
331     {
332         if (p->action_code == SHIFT && p->suppressed == 0)
333             return (0);
334         else if (p->action_code == REDUCE && p->suppressed == 0)
335         {
336             if (ruleno > 0 && p->number != ruleno)
337                 return (0);
338             if (p->symbol != 1)
339                 ++count;
340             ruleno = p->number;
341         }
342     }
343
344     if (count == 0)
345         return (0);
346     return (ruleno);
347 }
348
349 static void
350 defreds(void)
351 {
352     int i;
353
354     defred = NEW2(nstates, Value_t);
355     for (i = 0; i < nstates; i++)
356         defred[i] = (Value_t) sole_reduction(i);
357 }
358
359 static void
360 free_action_row(action *p)
361 {
362     action *q;
363
364     while (p)
365     {
366         q = p->next;
367         FREE(p);
368         p = q;
369     }
370 }
371
372 void
373 free_parser(void)
374 {
375     int i;
376
377     for (i = 0; i < nstates; i++)
378         free_action_row(parser[i]);
379
380     FREE(parser);
381 }
382
383 #ifdef NO_LEAKS
384 void
385 mkpar_leaks(void)
386 {
387     DO_FREE(defred);
388     DO_FREE(rules_used);
389     DO_FREE(SRconflicts);
390     DO_FREE(RRconflicts);
391 }
392 #endif