1 /* $NetBSD: mkpar.c,v 1.8 2015/01/03 23:22:52 christos Exp $ */
3 /* Id: mkpar.c,v 1.14 2014/04/01 23:05:37 tom Exp */
8 __RCSID("$NetBSD: mkpar.c,v 1.8 2015/01/03 23:22:52 christos Exp $");
10 #define NotSuppressed(p) ((p)->suppressed == 0)
13 #define MaySuppress(p) ((backtrack ? ((p)->suppressed <= 1) : (p)->suppressed == 0))
14 /* suppress the preferred action => enable backtracking */
15 #define StartBacktrack(p) if (backtrack && (p) != NULL && NotSuppressed(p)) (p)->suppressed = 1
17 #define MaySuppress(p) ((p)->suppressed == 0)
18 #define StartBacktrack(p) /*nothing */
21 static action
*add_reduce(action
*actions
, int ruleno
, int symbol
);
22 static action
*add_reductions(int stateno
, action
*actions
);
23 static action
*get_shifts(int stateno
);
24 static action
*parse_actions(int stateno
);
25 static int sole_reduction(int stateno
);
26 static void defreds(void);
27 static void find_final_state(void);
28 static void free_action_row(action
*p
);
29 static void remove_conflicts(void);
30 static void total_conflicts(void);
31 static void unused_rules(void);
48 static Value_t SRcount
;
49 static Value_t RRcount
;
56 parser
= NEW2(nstates
, action
*);
57 for (i
= 0; i
< nstates
; i
++)
58 parser
[i
] = parse_actions(i
);
63 if (SRtotal
+ RRtotal
> 0)
69 parse_actions(int stateno
)
73 actions
= get_shifts(stateno
);
74 actions
= add_reductions(stateno
, actions
);
79 get_shifts(int stateno
)
81 action
*actions
, *temp
;
88 sp
= shift_table
[stateno
];
91 to_state2
= sp
->shift
;
92 for (i
= (Value_t
) (sp
->nshifts
- 1); i
>= 0; i
--)
95 symbol
= accessing_symbol
[k
];
100 temp
->symbol
= symbol
;
102 temp
->prec
= symbol_prec
[symbol
];
103 temp
->action_code
= SHIFT
;
104 temp
->assoc
= symbol_assoc
[symbol
];
113 add_reductions(int stateno
, action
*actions
)
116 int ruleno
, tokensetsize
;
119 tokensetsize
= WORDSIZE(ntokens
);
120 m
= lookaheads
[stateno
];
121 n
= lookaheads
[stateno
+ 1];
122 for (i
= m
; i
< n
; i
++)
124 ruleno
= LAruleno
[i
];
125 rowp
= LA
+ i
* tokensetsize
;
126 for (j
= ntokens
- 1; j
>= 0; j
--)
129 actions
= add_reduce(actions
, ruleno
, j
);
136 add_reduce(action
*actions
,
140 action
*temp
, *prev
, *next
;
143 for (next
= actions
; next
&& next
->symbol
< symbol
; next
= next
->next
)
146 while (next
&& next
->symbol
== symbol
&& next
->action_code
== SHIFT
)
152 while (next
&& next
->symbol
== symbol
&&
153 next
->action_code
== REDUCE
&& next
->number
< ruleno
)
161 temp
->symbol
= (Value_t
) symbol
;
162 temp
->number
= (Value_t
) ruleno
;
163 temp
->prec
= rprec
[ruleno
];
164 temp
->action_code
= REDUCE
;
165 temp
->assoc
= rassoc
[ruleno
];
176 find_final_state(void)
183 to_state2
= p
->shift
;
185 for (i
= p
->nshifts
- 1; i
>= 0; --i
)
187 final_state
= to_state2
[i
];
188 if (accessing_symbol
[final_state
] == goal
)
199 rules_used
= TMALLOC(Value_t
, nrules
);
200 NO_SPACE(rules_used
);
202 for (i
= 0; i
< nrules
; ++i
)
205 for (i
= 0; i
< nstates
; ++i
)
207 for (p
= parser
[i
]; p
; p
= p
->next
)
209 if ((p
->action_code
== REDUCE
) && MaySuppress(p
))
210 rules_used
[p
->number
] = 1;
215 for (i
= 3; i
< nrules
; ++i
)
222 fprintf(stderr
, "%s: 1 rule never reduced\n", myname
);
224 fprintf(stderr
, "%s: %d rules never reduced\n", myname
, nunused
);
229 remove_conflicts(void)
233 action
*p
, *pref
= 0;
237 SRconflicts
= NEW2(nstates
, Value_t
);
238 RRconflicts
= NEW2(nstates
, Value_t
);
239 for (i
= 0; i
< nstates
; i
++)
244 #if defined(YYBTYACC)
247 for (p
= parser
[i
]; p
; p
= p
->next
)
249 if (p
->symbol
!= symbol
)
251 /* the first parse action for each symbol is the preferred action */
255 /* following conditions handle multiple, i.e., conflicting, parse actions */
256 else if (i
== final_state
&& symbol
== 0)
260 StartBacktrack(pref
);
262 else if (pref
!= 0 && pref
->action_code
== SHIFT
)
264 if (pref
->prec
> 0 && p
->prec
> 0)
266 if (pref
->prec
< p
->prec
)
268 pref
->suppressed
= 2;
271 else if (pref
->prec
> p
->prec
)
275 else if (pref
->assoc
== LEFT
)
277 pref
->suppressed
= 2;
280 else if (pref
->assoc
== RIGHT
)
286 pref
->suppressed
= 2;
294 StartBacktrack(pref
);
301 StartBacktrack(pref
);
306 SRconflicts
[i
] = SRcount
;
307 RRconflicts
[i
] = RRcount
;
312 total_conflicts(void)
314 fprintf(stderr
, "%s: ", myname
);
316 fprintf(stderr
, "1 shift/reduce conflict");
317 else if (SRtotal
> 1)
318 fprintf(stderr
, "%d shift/reduce conflicts", SRtotal
);
320 if (SRtotal
&& RRtotal
)
321 fprintf(stderr
, ", ");
324 fprintf(stderr
, "1 reduce/reduce conflict");
325 else if (RRtotal
> 1)
326 fprintf(stderr
, "%d reduce/reduce conflicts", RRtotal
);
328 fprintf(stderr
, ".\n");
330 if (SRexpect
>= 0 && SRtotal
!= SRexpect
)
332 fprintf(stderr
, "%s: ", myname
);
333 fprintf(stderr
, "expected %d shift/reduce conflict%s.\n",
334 SRexpect
, PLURAL(SRexpect
));
335 exit_code
= EXIT_FAILURE
;
337 if (RRexpect
>= 0 && RRtotal
!= RRexpect
)
339 fprintf(stderr
, "%s: ", myname
);
340 fprintf(stderr
, "expected %d reduce/reduce conflict%s.\n",
341 RRexpect
, PLURAL(RRexpect
));
342 exit_code
= EXIT_FAILURE
;
347 sole_reduction(int stateno
)
354 for (p
= parser
[stateno
]; p
; p
= p
->next
)
356 if (p
->action_code
== SHIFT
&& MaySuppress(p
))
358 else if ((p
->action_code
== REDUCE
) && MaySuppress(p
))
360 if (ruleno
> 0 && p
->number
!= ruleno
)
378 defred
= NEW2(nstates
, Value_t
);
379 for (i
= 0; i
< nstates
; i
++)
380 defred
[i
] = (Value_t
) sole_reduction(i
);
384 free_action_row(action
*p
)
401 for (i
= 0; i
< nstates
; i
++)
402 free_action_row(parser
[i
]);
413 DO_FREE(SRconflicts
);
414 DO_FREE(RRconflicts
);