1 /* $NetBSD: mkpar.c,v 1.11 2006/05/24 18:01:43 christos Exp $ */
4 * Copyright (c) 1989 The Regents of the University of California.
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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
35 #include <sys/cdefs.h>
36 #if defined(__RCSID) && !defined(lint)
38 static char sccsid
[] = "@(#)mkpar.c 5.3 (Berkeley) 1/20/91";
40 __RCSID("$NetBSD: mkpar.c,v 1.11 2006/05/24 18:01:43 christos Exp $");
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);
79 parser
= NEW2(nstates
, action
*);
80 for (i
= 0; i
< nstates
; i
++)
81 parser
[i
] = parse_actions(i
);
86 if (SRtotal
+ RRtotal
> 0) total_conflicts();
92 parse_actions(int stateno
)
96 actions
= get_shifts(stateno
);
97 actions
= add_reductions(stateno
, actions
);
103 get_shifts(int stateno
)
105 action
*actions
, *temp
;
112 sp
= shift_table
[stateno
];
116 for (i
= sp
->nshifts
- 1; i
>= 0; i
--)
119 symbol
= accessing_symbol
[k
];
123 temp
->next
= actions
;
124 temp
->symbol
= symbol
;
126 temp
->prec
= symbol_prec
[symbol
];
127 temp
->action_code
= SHIFT
;
128 temp
->assoc
= symbol_assoc
[symbol
];
137 add_reductions(int stateno
, action
*actions
)
140 int ruleno
, tokensetsize
;
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
--)
153 actions
= add_reduce(actions
, ruleno
, j
);
161 add_reduce(action
*actions
, int ruleno
, int symbol
)
163 action
*temp
, *prev
, *next
;
166 for (next
= actions
; next
&& next
->symbol
< symbol
; next
= next
->next
)
169 while (next
&& next
->symbol
== symbol
&& next
->action_code
== SHIFT
)
175 while (next
&& next
->symbol
== symbol
&&
176 next
->action_code
== REDUCE
&& next
->number
< ruleno
)
184 temp
->symbol
= symbol
;
185 temp
->number
= ruleno
;
186 temp
->prec
= rprec
[ruleno
];
187 temp
->action_code
= REDUCE
;
188 temp
->assoc
= rassoc
[ruleno
];
200 find_final_state(void)
209 for (i
= p
->nshifts
- 1; i
>= 0; --i
)
211 final_state
= state
[i
];
212 if (accessing_symbol
[final_state
] == goal
) break;
223 rules_used
= (short *) MALLOC(nrules
*sizeof(short));
224 if (rules_used
== 0) no_space();
226 for (i
= 0; i
< nrules
; ++i
)
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;
239 for (i
= 3; i
< nrules
; ++i
)
240 if (!rules_used
[i
]) ++nunused
;
244 fprintf(stderr
, "%s: 1 rule never reduced\n", myname
);
246 fprintf(stderr
, "%s: %d rules never reduced\n", myname
, nunused
);
252 remove_conflicts(void)
261 SRconflicts
= NEW2(nstates
, short);
262 RRconflicts
= NEW2(nstates
, short);
263 for (i
= 0; i
< nstates
; i
++)
268 for (p
= parser
[i
]; p
; p
= p
->next
)
270 if (p
->symbol
!= symbol
)
275 else if (i
== final_state
&& symbol
== 0)
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;
292 else if (pref
->prec
> p
->prec
)
296 else if (pref
->assoc
== LEFT
)
298 pref
->suppressed
= 2;
301 else if (pref
->assoc
== RIGHT
)
307 pref
->suppressed
= 2;
326 SRconflicts
[i
] = SRcount
;
327 RRconflicts
[i
] = RRcount
;
333 total_conflicts(void)
335 fprintf(stderr
, "%s: ", myname
);
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
, ", ");
345 fprintf(stderr
, "1 reduce/reduce conflict");
346 else if (RRtotal
> 1)
347 fprintf(stderr
, "%d reduce/reduce conflicts", RRtotal
);
349 fprintf(stderr
, ".\n");
354 sole_reduction(int stateno
)
361 for (p
= parser
[stateno
]; p
; p
= p
->next
)
363 if (p
->action_code
== SHIFT
&& p
->suppressed
== 0)
365 else if (p
->action_code
== REDUCE
&& p
->suppressed
== 0)
367 if (ruleno
> 0 && p
->number
!= ruleno
)
386 defred
= NEW2(nstates
, short);
387 for (i
= 0; i
< nstates
; i
++)
388 defred
[i
] = sole_reduction(i
);
392 free_action_row(action
*p
)
409 for (i
= 0; i
< nstates
; i
++)
410 free_action_row(parser
[i
]);