2 * Copyright (c) 1989 The Regents of the University of California.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * $FreeBSD: src/usr.bin/yacc/verbose.c,v 1.6 1999/08/28 01:08:03 peter Exp $
37 * $DragonFly: src/usr.bin/yacc/verbose.c,v 1.5 2005/01/05 15:26:05 joerg Exp $
39 * @(#)verbose.c 5.3 (Berkeley) 1/20/91
45 static void log_unused(void);
46 static void log_conflicts(void);
47 static void print_actions(int);
48 static void print_conflicts(int);
49 static void print_core(int);
50 static void print_gotos(int);
51 static void print_nulls(int);
52 static void print_reductions(action
*, int);
53 static void print_shifts(action
*);
54 static void print_state(int);
56 static short *null_rules
;
65 null_rules
= (short *) MALLOC(nrules
*sizeof(short));
66 if (null_rules
== 0) no_space();
67 fprintf(verbose_file
, "\f\n");
68 for (i
= 0; i
< nstates
; i
++)
74 if (SRtotal
|| RRtotal
)
77 fprintf(verbose_file
, "\n\n%d terminals, %d nonterminals\n", ntokens
,
79 fprintf(verbose_file
, "%d grammar rules, %d states\n", nrules
- 2, nstates
);
89 fprintf(verbose_file
, "\n\nRules never reduced:\n");
90 for (i
= 3; i
< nrules
; ++i
)
94 fprintf(verbose_file
, "\t%s :", symbol_name
[rlhs
[i
]]);
95 for (p
= ritem
+ rrhs
[i
]; *p
>= 0; ++p
)
96 fprintf(verbose_file
, " %s", symbol_name
[*p
]);
97 fprintf(verbose_file
, " (%d)\n", i
- 2);
108 fprintf(verbose_file
, "\n\n");
109 for (i
= 0; i
< nstates
; i
++)
111 if (SRconflicts
[i
] || RRconflicts
[i
])
113 fprintf(verbose_file
, "State %d contains ", i
);
114 if (SRconflicts
[i
] == 1)
115 fprintf(verbose_file
, "1 shift/reduce conflict");
116 else if (SRconflicts
[i
] > 1)
117 fprintf(verbose_file
, "%d shift/reduce conflicts",
119 if (SRconflicts
[i
] && RRconflicts
[i
])
120 fprintf(verbose_file
, ", ");
121 if (RRconflicts
[i
] == 1)
122 fprintf(verbose_file
, "1 reduce/reduce conflict");
123 else if (RRconflicts
[i
] > 1)
124 fprintf(verbose_file
, "%d reduce/reduce conflicts",
126 fprintf(verbose_file
, ".\n");
133 print_state(int state
)
136 fprintf(verbose_file
, "\n\n");
137 if (SRconflicts
[state
] || RRconflicts
[state
])
138 print_conflicts(state
);
139 fprintf(verbose_file
, "state %d\n", state
);
142 print_actions(state
);
147 print_conflicts(int state
)
149 int symbol
, act
= 0, number
= 0;
153 for (p
= parser
[state
]; p
; p
= p
->next
)
155 if (p
->suppressed
== 2)
158 if (p
->symbol
!= symbol
)
162 if (p
->action_code
== SHIFT
)
167 else if (p
->suppressed
== 1)
169 if (state
== final_state
&& symbol
== 0)
171 fprintf(verbose_file
, "%d: shift/reduce conflict \
172 (accept, reduce %d) on $end\n", state
, p
->number
- 2);
178 fprintf(verbose_file
, "%d: shift/reduce conflict \
179 (shift %d, reduce %d) on %s\n", state
, number
, p
->number
- 2,
180 symbol_name
[symbol
]);
184 fprintf(verbose_file
, "%d: reduce/reduce conflict \
185 (reduce %d, reduce %d) on %s\n", state
, number
- 2, p
->number
- 2,
186 symbol_name
[symbol
]);
195 print_core(int state
)
204 statep
= state_table
[state
];
207 for (i
= 0; i
< k
; i
++)
209 sp1
= sp
= ritem
+ statep
->items
[i
];
211 while (*sp
>= 0) ++sp
;
213 fprintf(verbose_file
, "\t%s : ", symbol_name
[rlhs
[rule
]]);
215 for (sp
= ritem
+ rrhs
[rule
]; sp
< sp1
; sp
++)
216 fprintf(verbose_file
, "%s ", symbol_name
[*sp
]);
218 putc('.', verbose_file
);
222 fprintf(verbose_file
, " %s", symbol_name
[*sp
]);
225 fprintf(verbose_file
, " (%d)\n", -2 - *sp
);
231 print_nulls(int state
)
237 for (p
= parser
[state
]; p
; p
= p
->next
)
239 if (p
->action_code
== REDUCE
&&
240 (p
->suppressed
== 0 || p
->suppressed
== 1))
243 if (rrhs
[i
] + 1 == rrhs
[i
+1])
245 for (j
= 0; j
< nnulls
&& i
> null_rules
[j
]; ++j
)
253 else if (i
!= null_rules
[j
])
256 for (k
= nnulls
- 1; k
> j
; --k
)
257 null_rules
[k
] = null_rules
[k
-1];
264 for (i
= 0; i
< nnulls
; ++i
)
267 fprintf(verbose_file
, "\t%s : . (%d)\n", symbol_name
[rlhs
[j
]],
270 fprintf(verbose_file
, "\n");
275 print_actions(int stateno
)
281 if (stateno
== final_state
)
282 fprintf(verbose_file
, "\t$end accept\n");
288 print_reductions(p
, defred
[stateno
]);
291 sp
= shift_table
[stateno
];
292 if (sp
&& sp
->nshifts
> 0)
294 as
= accessing_symbol
[sp
->shift
[sp
->nshifts
- 1]];
296 print_gotos(stateno
);
302 print_shifts(action
*p
)
308 for (q
= p
; q
; q
= q
->next
)
310 if (q
->suppressed
< 2 && q
->action_code
== SHIFT
)
316 for (; p
; p
= p
->next
)
318 if (p
->action_code
== SHIFT
&& p
->suppressed
== 0)
319 fprintf(verbose_file
, "\t%s shift %d\n",
320 symbol_name
[p
->symbol
], p
->number
);
327 print_reductions(action
*p
, int defreduc
)
333 for (q
= p
; q
; q
= q
->next
)
335 if (q
->action_code
== REDUCE
&& q
->suppressed
< 2)
343 fprintf(verbose_file
, "\t. error\n");
346 for (; p
; p
= p
->next
)
348 if (p
->action_code
== REDUCE
&& p
->number
!= defreduc
)
351 if (p
->suppressed
== 0)
352 fprintf(verbose_file
, "\t%s reduce %d\n",
353 symbol_name
[p
->symbol
], k
);
358 fprintf(verbose_file
, "\t. reduce %d\n", defreduc
- 2);
364 print_gotos(int stateno
)
371 putc('\n', verbose_file
);
372 sp
= shift_table
[stateno
];
373 loc_to_state
= sp
->shift
;
374 for (i
= 0; i
< sp
->nshifts
; ++i
)
377 as
= accessing_symbol
[k
];
379 fprintf(verbose_file
, "\t%s goto %d\n", symbol_name
[as
], k
);