1 /* $NetBSD: mkpar.c,v 1.7 2013/04/06 14:52:24 christos Exp $ */
3 /* Id: mkpar.c,v 1.12 2012/05/26 00:42:18 tom Exp */
8 __RCSID("$NetBSD: mkpar.c,v 1.7 2013/04/06 14:52:24 christos Exp $");
10 static action
*add_reduce(action
*actions
, int ruleno
, int symbol
);
11 static action
*add_reductions(int stateno
, action
*actions
);
12 static action
*get_shifts(int stateno
);
13 static action
*parse_actions(int stateno
);
14 static int sole_reduction(int stateno
);
15 static void defreds(void);
16 static void find_final_state(void);
17 static void free_action_row(action
*p
);
18 static void remove_conflicts(void);
19 static void total_conflicts(void);
20 static void unused_rules(void);
37 static Value_t SRcount
;
38 static Value_t RRcount
;
45 parser
= NEW2(nstates
, action
*);
46 for (i
= 0; i
< nstates
; i
++)
47 parser
[i
] = parse_actions(i
);
52 if (SRtotal
+ RRtotal
> 0)
58 parse_actions(int stateno
)
62 actions
= get_shifts(stateno
);
63 actions
= add_reductions(stateno
, actions
);
68 get_shifts(int stateno
)
70 action
*actions
, *temp
;
77 sp
= shift_table
[stateno
];
80 to_state2
= sp
->shift
;
81 for (i
= (Value_t
) (sp
->nshifts
- 1); i
>= 0; i
--)
84 symbol
= accessing_symbol
[k
];
89 temp
->symbol
= symbol
;
91 temp
->prec
= symbol_prec
[symbol
];
92 temp
->action_code
= SHIFT
;
93 temp
->assoc
= symbol_assoc
[symbol
];
102 add_reductions(int stateno
, action
*actions
)
105 int ruleno
, tokensetsize
;
108 tokensetsize
= WORDSIZE(ntokens
);
109 m
= lookaheads
[stateno
];
110 n
= lookaheads
[stateno
+ 1];
111 for (i
= m
; i
< n
; i
++)
113 ruleno
= LAruleno
[i
];
114 rowp
= LA
+ i
* tokensetsize
;
115 for (j
= ntokens
- 1; j
>= 0; j
--)
118 actions
= add_reduce(actions
, ruleno
, j
);
125 add_reduce(action
*actions
,
129 action
*temp
, *prev
, *next
;
132 for (next
= actions
; next
&& next
->symbol
< symbol
; next
= next
->next
)
135 while (next
&& next
->symbol
== symbol
&& next
->action_code
== SHIFT
)
141 while (next
&& next
->symbol
== symbol
&&
142 next
->action_code
== REDUCE
&& next
->number
< ruleno
)
150 temp
->symbol
= (Value_t
) symbol
;
151 temp
->number
= (Value_t
) ruleno
;
152 temp
->prec
= rprec
[ruleno
];
153 temp
->action_code
= REDUCE
;
154 temp
->assoc
= rassoc
[ruleno
];
165 find_final_state(void)
172 to_state2
= p
->shift
;
174 for (i
= p
->nshifts
- 1; i
>= 0; --i
)
176 final_state
= to_state2
[i
];
177 if (accessing_symbol
[final_state
] == goal
)
188 rules_used
= TMALLOC(Value_t
, nrules
);
189 NO_SPACE(rules_used
);
191 for (i
= 0; i
< nrules
; ++i
)
194 for (i
= 0; i
< nstates
; ++i
)
196 for (p
= parser
[i
]; p
; p
= p
->next
)
198 if (p
->action_code
== REDUCE
&& p
->suppressed
== 0)
199 rules_used
[p
->number
] = 1;
204 for (i
= 3; i
< nrules
; ++i
)
211 fprintf(stderr
, "%s: 1 rule never reduced\n", myname
);
213 fprintf(stderr
, "%s: %d rules never reduced\n", myname
, nunused
);
218 remove_conflicts(void)
222 action
*p
, *pref
= 0;
226 SRconflicts
= NEW2(nstates
, Value_t
);
227 RRconflicts
= NEW2(nstates
, Value_t
);
228 for (i
= 0; i
< nstates
; i
++)
233 for (p
= parser
[i
]; p
; p
= p
->next
)
235 if (p
->symbol
!= symbol
)
240 else if (i
== final_state
&& symbol
== 0)
245 else if (pref
!= 0 && pref
->action_code
== SHIFT
)
247 if (pref
->prec
> 0 && p
->prec
> 0)
249 if (pref
->prec
< p
->prec
)
251 pref
->suppressed
= 2;
254 else if (pref
->prec
> p
->prec
)
258 else if (pref
->assoc
== LEFT
)
260 pref
->suppressed
= 2;
263 else if (pref
->assoc
== RIGHT
)
269 pref
->suppressed
= 2;
287 SRconflicts
[i
] = SRcount
;
288 RRconflicts
[i
] = RRcount
;
293 total_conflicts(void)
295 fprintf(stderr
, "%s: ", myname
);
297 fprintf(stderr
, "1 shift/reduce conflict");
298 else if (SRtotal
> 1)
299 fprintf(stderr
, "%d shift/reduce conflicts", SRtotal
);
301 if (SRtotal
&& RRtotal
)
302 fprintf(stderr
, ", ");
305 fprintf(stderr
, "1 reduce/reduce conflict");
306 else if (RRtotal
> 1)
307 fprintf(stderr
, "%d reduce/reduce conflicts", RRtotal
);
309 fprintf(stderr
, ".\n");
311 if (SRexpect
>= 0 && SRtotal
!= SRexpect
)
313 fprintf(stderr
, "%s: ", myname
);
314 fprintf(stderr
, "expected %d shift/reduce conflict%s.\n",
315 SRexpect
, PLURAL(SRexpect
));
316 exit_code
= EXIT_FAILURE
;
318 if (RRexpect
>= 0 && RRtotal
!= RRexpect
)
320 fprintf(stderr
, "%s: ", myname
);
321 fprintf(stderr
, "expected %d reduce/reduce conflict%s.\n",
322 RRexpect
, PLURAL(RRexpect
));
323 exit_code
= EXIT_FAILURE
;
328 sole_reduction(int stateno
)
335 for (p
= parser
[stateno
]; p
; p
= p
->next
)
337 if (p
->action_code
== SHIFT
&& p
->suppressed
== 0)
339 else if (p
->action_code
== REDUCE
&& p
->suppressed
== 0)
341 if (ruleno
> 0 && p
->number
!= ruleno
)
359 defred
= NEW2(nstates
, Value_t
);
360 for (i
= 0; i
< nstates
; i
++)
361 defred
[i
] = (Value_t
) sole_reduction(i
);
365 free_action_row(action
*p
)
382 for (i
= 0; i
< nstates
; i
++)
383 free_action_row(parser
[i
]);
394 DO_FREE(SRconflicts
);
395 DO_FREE(RRconflicts
);