1 /* $OpenBSD: verbose.c,v 1.14 2017/05/25 20:11:03 tedu Exp $ */
2 /* $NetBSD: verbose.c,v 1.4 1996/03/19 03:21:50 jtc Exp $ */
5 * Copyright (c) 1989 The Regents of the University of California.
8 * This code is derived from software contributed to Berkeley by
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 static short *null_rules
;
40 void log_unused(void);
41 void log_conflicts(void);
42 void print_state(int);
43 void print_conflicts(int);
45 void print_nulls(int);
46 void print_actions(int);
47 void print_shifts(action
*);
48 void print_reductions(action
*, int);
49 void print_gotos(int);
59 null_rules
= reallocarray(NULL
, nrules
, sizeof(short));
60 if (null_rules
== NULL
)
62 fprintf(verbose_file
, "\f\n");
63 for (i
= 0; i
< nstates
; i
++)
69 if (SRtotal
|| RRtotal
)
72 fprintf(verbose_file
, "\n\n%d terminals, %d nonterminals\n", ntokens
,
74 fprintf(verbose_file
, "%d grammar rules, %d states\n", nrules
- 2,
85 fprintf(verbose_file
, "\n\nRules never reduced:\n");
86 for (i
= 3; i
< nrules
; ++i
) {
88 fprintf(verbose_file
, "\t%s :", symbol_name
[rlhs
[i
]]);
89 for (p
= ritem
+ rrhs
[i
]; *p
>= 0; ++p
)
90 fprintf(verbose_file
, " %s", symbol_name
[*p
]);
91 fprintf(verbose_file
, " (%d)\n", i
- 2);
102 fprintf(verbose_file
, "\n\n");
103 for (i
= 0; i
< nstates
; i
++) {
104 if (SRconflicts
[i
] || RRconflicts
[i
]) {
105 fprintf(verbose_file
, "State %d contains ", i
);
106 if (SRconflicts
[i
] == 1)
107 fprintf(verbose_file
, "1 shift/reduce conflict");
108 else if (SRconflicts
[i
] > 1)
109 fprintf(verbose_file
, "%d shift/reduce conflicts",
111 if (SRconflicts
[i
] && RRconflicts
[i
])
112 fprintf(verbose_file
, ", ");
113 if (RRconflicts
[i
] == 1)
114 fprintf(verbose_file
, "1 reduce/reduce conflict");
115 else if (RRconflicts
[i
] > 1)
116 fprintf(verbose_file
, "%d reduce/reduce conflicts",
118 fprintf(verbose_file
, ".\n");
125 print_state(int state
)
128 fprintf(verbose_file
, "\n\n");
129 if (SRconflicts
[state
] || RRconflicts
[state
])
130 print_conflicts(state
);
131 fprintf(verbose_file
, "state %d\n", state
);
134 print_actions(state
);
139 print_conflicts(int state
)
141 int symbol
, act
= REDUCE
, number
= 0;
145 for (p
= parser
[state
]; p
; p
= p
->next
) {
146 if (p
->suppressed
== 2)
149 if (p
->symbol
!= symbol
) {
152 if (p
->action_code
== SHIFT
)
156 } else if (p
->suppressed
== 1) {
157 if (state
== final_state
&& symbol
== 0) {
158 fprintf(verbose_file
,
159 "%d: shift/reduce conflict "
160 "(accept, reduce %d) on $end\n",
161 state
, p
->number
- 2);
164 fprintf(verbose_file
,
165 "%d: shift/reduce conflict "
166 "(shift %d, reduce %d) on %s\n",
167 state
, number
, p
->number
- 2,
168 symbol_name
[symbol
]);
170 fprintf(verbose_file
,
171 "%d: reduce/reduce conflict "
172 "(reduce %d, reduce %d) on %s\n",
173 state
, number
- 2, p
->number
- 2,
174 symbol_name
[symbol
]);
183 print_core(int state
)
192 statep
= state_table
[state
];
195 for (i
= 0; i
< k
; i
++) {
196 sp1
= sp
= ritem
+ statep
->items
[i
];
201 fprintf(verbose_file
, "\t%s : ", symbol_name
[rlhs
[rule
]]);
203 for (sp
= ritem
+ rrhs
[rule
]; sp
< sp1
; sp
++)
204 fprintf(verbose_file
, "%s ", symbol_name
[*sp
]);
206 putc('.', verbose_file
);
209 fprintf(verbose_file
, " %s", symbol_name
[*sp
]);
212 fprintf(verbose_file
, " (%d)\n", -2 - *sp
);
218 print_nulls(int state
)
224 for (p
= parser
[state
]; p
; p
= p
->next
) {
225 if (p
->action_code
== REDUCE
&&
226 (p
->suppressed
== 0 || p
->suppressed
== 1)) {
228 if (rrhs
[i
] + 1 == rrhs
[i
+ 1]) {
229 for (j
= 0; j
< nnulls
&& i
> null_rules
[j
]; ++j
)
235 } else if (i
!= null_rules
[j
]) {
237 for (k
= nnulls
- 1; k
> j
; --k
)
238 null_rules
[k
] = null_rules
[k
- 1];
245 for (i
= 0; i
< nnulls
; ++i
) {
247 fprintf(verbose_file
, "\t%s : . (%d)\n", symbol_name
[rlhs
[j
]],
250 fprintf(verbose_file
, "\n");
255 print_actions(int stateno
)
261 if (stateno
== final_state
)
262 fprintf(verbose_file
, "\t$end accept\n");
267 print_reductions(p
, defred
[stateno
]);
269 sp
= shift_table
[stateno
];
270 if (sp
&& sp
->nshifts
> 0) {
271 as
= accessing_symbol
[sp
->shift
[sp
->nshifts
- 1]];
273 print_gotos(stateno
);
279 print_shifts(action
* p
)
285 for (q
= p
; q
; q
= q
->next
) {
286 if (q
->suppressed
< 2 && q
->action_code
== SHIFT
)
291 for (; p
; p
= p
->next
) {
292 if (p
->action_code
== SHIFT
&& p
->suppressed
== 0)
293 fprintf(verbose_file
, "\t%s shift %d\n",
294 symbol_name
[p
->symbol
], p
->number
);
301 print_reductions(action
* p
, int pdefred
)
307 for (q
= p
; q
; q
= q
->next
) {
308 if (q
->action_code
== REDUCE
&& q
->suppressed
< 2) {
315 fprintf(verbose_file
, "\t. error\n");
317 for (; p
; p
= p
->next
) {
318 if (p
->action_code
== REDUCE
&& p
->number
!= pdefred
) {
320 if (p
->suppressed
== 0)
321 fprintf(verbose_file
, "\t%s reduce %d\n",
322 symbol_name
[p
->symbol
], k
);
327 fprintf(verbose_file
, "\t. reduce %d\n", pdefred
- 2);
333 print_gotos(int stateno
)
340 putc('\n', verbose_file
);
341 sp
= shift_table
[stateno
];
342 tto_state
= sp
->shift
;
343 for (i
= 0; i
< sp
->nshifts
; ++i
) {
345 as
= accessing_symbol
[k
];
347 fprintf(verbose_file
, "\t%s goto %d\n",