11590Srgrimes/*
21590Srgrimes * Copyright (c) 1989 The Regents of the University of California.
31590Srgrimes * All rights reserved.
41590Srgrimes *
51590Srgrimes * This code is derived from software contributed to Berkeley by
61590Srgrimes * Robert Paul Corbett.
71590Srgrimes *
81590Srgrimes * Redistribution and use in source and binary forms, with or without
91590Srgrimes * modification, are permitted provided that the following conditions
101590Srgrimes * are met:
111590Srgrimes * 1. Redistributions of source code must retain the above copyright
121590Srgrimes *    notice, this list of conditions and the following disclaimer.
131590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
141590Srgrimes *    notice, this list of conditions and the following disclaimer in the
151590Srgrimes *    documentation and/or other materials provided with the distribution.
161590Srgrimes * 4. Neither the name of the University nor the names of its contributors
171590Srgrimes *    may be used to endorse or promote products derived from this software
181590Srgrimes *    without specific prior written permission.
191590Srgrimes *
201590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
211590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
221590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
231590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
241590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
251590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
261590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
271590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
281590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
291590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
301590Srgrimes * SUCH DAMAGE.
311590Srgrimes */
321590Srgrimes
3387628Sdwmalone#if 0
3487628Sdwmalone#ifndef lint
3587628Sdwmalonestatic char sccsid[] = "@(#)verbose.c	5.3 (Berkeley) 1/20/91";
3687628Sdwmalone#endif
3787628Sdwmalone#endif
3887628Sdwmalone
3987234Smarkm#include <sys/cdefs.h>
4087234Smarkm__FBSDID("$FreeBSD$");
4187234Smarkm
4221622Ssteve#include <stdlib.h>
431590Srgrimes#include "defs.h"
441590Srgrimes
4593834Sobrienstatic short *null_rules;
4693834Sobrien
4792922Simpstatic void log_unused(void);
4892922Simpstatic void log_conflicts(void);
4992922Simpstatic void print_actions(int);
5092922Simpstatic void print_conflicts(int);
5192922Simpstatic void print_core(int);
5292922Simpstatic void print_gotos(int);
5392922Simpstatic void print_nulls(int);
5492922Simpstatic void print_reductions(action *, register int);
5592922Simpstatic void print_shifts(action *);
5692922Simpstatic void print_state(int);
5721622Ssteve
5821622Sstevevoid
59214959Sobrienverbose(void)
601590Srgrimes{
6187171Smarkm    int i;
621590Srgrimes
631590Srgrimes    if (!vflag) return;
641590Srgrimes
65214961Sobrien    null_rules = malloc(nrules*sizeof(short));
661590Srgrimes    if (null_rules == 0) no_space();
671590Srgrimes    fprintf(verbose_file, "\f\n");
681590Srgrimes    for (i = 0; i < nstates; i++)
691590Srgrimes	print_state(i);
70214961Sobrien    free(null_rules);
711590Srgrimes
721590Srgrimes    if (nunused)
731590Srgrimes	log_unused();
741590Srgrimes    if (SRtotal || RRtotal)
751590Srgrimes	log_conflicts();
761590Srgrimes
771590Srgrimes    fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens,
781590Srgrimes	    nvars);
791590Srgrimes    fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates);
801590Srgrimes}
811590Srgrimes
821590Srgrimes
8321622Sstevestatic void
84214959Sobrienlog_unused(void)
851590Srgrimes{
8687171Smarkm    int i;
8787171Smarkm    short *p;
881590Srgrimes
891590Srgrimes    fprintf(verbose_file, "\n\nRules never reduced:\n");
901590Srgrimes    for (i = 3; i < nrules; ++i)
911590Srgrimes    {
921590Srgrimes	if (!rules_used[i])
931590Srgrimes	{
941590Srgrimes	    fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]);
951590Srgrimes	    for (p = ritem + rrhs[i]; *p >= 0; ++p)
961590Srgrimes		fprintf(verbose_file, " %s", symbol_name[*p]);
971590Srgrimes	    fprintf(verbose_file, "  (%d)\n", i - 2);
981590Srgrimes	}
991590Srgrimes    }
1001590Srgrimes}
1011590Srgrimes
1021590Srgrimes
10321622Sstevestatic void
104214959Sobrienlog_conflicts(void)
1051590Srgrimes{
10687171Smarkm    int i;
1071590Srgrimes
1081590Srgrimes    fprintf(verbose_file, "\n\n");
1091590Srgrimes    for (i = 0; i < nstates; i++)
1101590Srgrimes    {
1111590Srgrimes	if (SRconflicts[i] || RRconflicts[i])
1121590Srgrimes	{
1131590Srgrimes	    fprintf(verbose_file, "State %d contains ", i);
1141590Srgrimes	    if (SRconflicts[i] == 1)
1151590Srgrimes		fprintf(verbose_file, "1 shift/reduce conflict");
1161590Srgrimes	    else if (SRconflicts[i] > 1)
1171590Srgrimes		fprintf(verbose_file, "%d shift/reduce conflicts",
1181590Srgrimes			SRconflicts[i]);
1191590Srgrimes	    if (SRconflicts[i] && RRconflicts[i])
1201590Srgrimes		fprintf(verbose_file, ", ");
1211590Srgrimes	    if (RRconflicts[i] == 1)
1221590Srgrimes		fprintf(verbose_file, "1 reduce/reduce conflict");
1231590Srgrimes	    else if (RRconflicts[i] > 1)
1241590Srgrimes		fprintf(verbose_file, "%d reduce/reduce conflicts",
1251590Srgrimes			RRconflicts[i]);
1261590Srgrimes	    fprintf(verbose_file, ".\n");
1271590Srgrimes	}
1281590Srgrimes    }
1291590Srgrimes}
1301590Srgrimes
1311590Srgrimes
13221622Sstevestatic void
133214959Sobrienprint_state(int state)
1341590Srgrimes{
1351590Srgrimes    if (state)
1361590Srgrimes	fprintf(verbose_file, "\n\n");
1371590Srgrimes    if (SRconflicts[state] || RRconflicts[state])
1381590Srgrimes	print_conflicts(state);
1391590Srgrimes    fprintf(verbose_file, "state %d\n", state);
1401590Srgrimes    print_core(state);
1411590Srgrimes    print_nulls(state);
1421590Srgrimes    print_actions(state);
1431590Srgrimes}
1441590Srgrimes
1451590Srgrimes
14621622Sstevestatic void
147214959Sobrienprint_conflicts(int state)
1481590Srgrimes{
14987171Smarkm    int symbol, act = 0, number = 0;
15087171Smarkm    action *p;
1511590Srgrimes
1521590Srgrimes    symbol = -1;
1531590Srgrimes    for (p = parser[state]; p; p = p->next)
1541590Srgrimes    {
1551590Srgrimes	if (p->suppressed == 2)
1561590Srgrimes	    continue;
1571590Srgrimes
1581590Srgrimes	if (p->symbol != symbol)
1591590Srgrimes	{
1601590Srgrimes	    symbol = p->symbol;
1611590Srgrimes	    number = p->number;
1621590Srgrimes	    if (p->action_code == SHIFT)
1631590Srgrimes		act = SHIFT;
1641590Srgrimes	    else
1651590Srgrimes		act = REDUCE;
1661590Srgrimes	}
1671590Srgrimes	else if (p->suppressed == 1)
1681590Srgrimes	{
1691590Srgrimes	    if (state == final_state && symbol == 0)
1701590Srgrimes	    {
1711590Srgrimes		fprintf(verbose_file, "%d: shift/reduce conflict \
1721590Srgrimes(accept, reduce %d) on $end\n", state, p->number - 2);
1731590Srgrimes	    }
1741590Srgrimes	    else
1751590Srgrimes	    {
1761590Srgrimes		if (act == SHIFT)
1771590Srgrimes		{
1781590Srgrimes		    fprintf(verbose_file, "%d: shift/reduce conflict \
1791590Srgrimes(shift %d, reduce %d) on %s\n", state, number, p->number - 2,
1801590Srgrimes			    symbol_name[symbol]);
1811590Srgrimes		}
1821590Srgrimes		else
1831590Srgrimes		{
1841590Srgrimes		    fprintf(verbose_file, "%d: reduce/reduce conflict \
1851590Srgrimes(reduce %d, reduce %d) on %s\n", state, number - 2, p->number - 2,
1861590Srgrimes			    symbol_name[symbol]);
1871590Srgrimes		}
1881590Srgrimes	    }
1891590Srgrimes	}
1901590Srgrimes    }
1911590Srgrimes}
1921590Srgrimes
1931590Srgrimes
19421622Sstevestatic void
195214959Sobrienprint_core(int state)
1961590Srgrimes{
19787171Smarkm    int i;
19887171Smarkm    int k;
19987171Smarkm    int rule;
20087171Smarkm    core *statep;
20187171Smarkm    short *sp;
20287171Smarkm    short *sp1;
2031590Srgrimes
2041590Srgrimes    statep = state_table[state];
2051590Srgrimes    k = statep->nitems;
2061590Srgrimes
2071590Srgrimes    for (i = 0; i < k; i++)
2081590Srgrimes    {
2091590Srgrimes	sp1 = sp = ritem + statep->items[i];
2101590Srgrimes
2111590Srgrimes	while (*sp >= 0) ++sp;
2121590Srgrimes	rule = -(*sp);
2131590Srgrimes	fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]);
2141590Srgrimes
2151590Srgrimes        for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
2161590Srgrimes	    fprintf(verbose_file, "%s ", symbol_name[*sp]);
2171590Srgrimes
2181590Srgrimes	putc('.', verbose_file);
2191590Srgrimes
2201590Srgrimes	while (*sp >= 0)
2211590Srgrimes	{
2221590Srgrimes	    fprintf(verbose_file, " %s", symbol_name[*sp]);
2231590Srgrimes	    sp++;
2241590Srgrimes	}
2251590Srgrimes	fprintf(verbose_file, "  (%d)\n", -2 - *sp);
2261590Srgrimes    }
2271590Srgrimes}
2281590Srgrimes
2291590Srgrimes
23021622Sstevestatic void
231214959Sobrienprint_nulls(int state)
2321590Srgrimes{
23387171Smarkm    action *p;
23487171Smarkm    int i, j, k, nnulls;
2351590Srgrimes
2361590Srgrimes    nnulls = 0;
2371590Srgrimes    for (p = parser[state]; p; p = p->next)
2381590Srgrimes    {
2391590Srgrimes	if (p->action_code == REDUCE &&
2401590Srgrimes		(p->suppressed == 0 || p->suppressed == 1))
2411590Srgrimes	{
2421590Srgrimes	    i = p->number;
2431590Srgrimes	    if (rrhs[i] + 1 == rrhs[i+1])
2441590Srgrimes	    {
2451590Srgrimes		for (j = 0; j < nnulls && i > null_rules[j]; ++j)
2461590Srgrimes		    continue;
2471590Srgrimes
2481590Srgrimes		if (j == nnulls)
2491590Srgrimes		{
2501590Srgrimes		    ++nnulls;
2511590Srgrimes		    null_rules[j] = i;
2521590Srgrimes		}
2531590Srgrimes		else if (i != null_rules[j])
2541590Srgrimes		{
2551590Srgrimes		    ++nnulls;
2561590Srgrimes		    for (k = nnulls - 1; k > j; --k)
2571590Srgrimes			null_rules[k] = null_rules[k-1];
2581590Srgrimes		    null_rules[j] = i;
2591590Srgrimes		}
2601590Srgrimes	    }
2611590Srgrimes	}
2621590Srgrimes    }
2631590Srgrimes
2641590Srgrimes    for (i = 0; i < nnulls; ++i)
2651590Srgrimes    {
2661590Srgrimes	j = null_rules[i];
2671590Srgrimes	fprintf(verbose_file, "\t%s : .  (%d)\n", symbol_name[rlhs[j]],
2681590Srgrimes		j - 2);
2691590Srgrimes    }
2701590Srgrimes    fprintf(verbose_file, "\n");
2711590Srgrimes}
2721590Srgrimes
2731590Srgrimes
27421622Sstevestatic void
275214959Sobrienprint_actions(int stateno)
2761590Srgrimes{
27787171Smarkm    action *p;
27887171Smarkm    shifts *sp;
27987171Smarkm    int as;
2801590Srgrimes
2811590Srgrimes    if (stateno == final_state)
2821590Srgrimes	fprintf(verbose_file, "\t$end  accept\n");
2831590Srgrimes
2841590Srgrimes    p = parser[stateno];
2851590Srgrimes    if (p)
2861590Srgrimes    {
2871590Srgrimes	print_shifts(p);
2881590Srgrimes	print_reductions(p, defred[stateno]);
2891590Srgrimes    }
2901590Srgrimes
2911590Srgrimes    sp = shift_table[stateno];
2921590Srgrimes    if (sp && sp->nshifts > 0)
2931590Srgrimes    {
2941590Srgrimes	as = accessing_symbol[sp->shift[sp->nshifts - 1]];
2951590Srgrimes	if (ISVAR(as))
2961590Srgrimes	    print_gotos(stateno);
2971590Srgrimes    }
2981590Srgrimes}
2991590Srgrimes
3001590Srgrimes
30121622Sstevestatic void
302214959Sobrienprint_shifts(action *p)
3031590Srgrimes{
30487171Smarkm    int count;
30587171Smarkm    action *q;
3061590Srgrimes
3071590Srgrimes    count = 0;
3081590Srgrimes    for (q = p; q; q = q->next)
3091590Srgrimes    {
3101590Srgrimes	if (q->suppressed < 2 && q->action_code == SHIFT)
3111590Srgrimes	    ++count;
3121590Srgrimes    }
3131590Srgrimes
3141590Srgrimes    if (count > 0)
3151590Srgrimes    {
3161590Srgrimes	for (; p; p = p->next)
3171590Srgrimes	{
3181590Srgrimes	    if (p->action_code == SHIFT && p->suppressed == 0)
3191590Srgrimes		fprintf(verbose_file, "\t%s  shift %d\n",
3201590Srgrimes			    symbol_name[p->symbol], p->number);
3211590Srgrimes	}
3221590Srgrimes    }
3231590Srgrimes}
3241590Srgrimes
3251590Srgrimes
32621622Sstevestatic void
327214959Sobrienprint_reductions(action *p, int defreduct)
3281590Srgrimes{
32987171Smarkm    int k, anyreds;
33087171Smarkm    action *q;
3311590Srgrimes
3321590Srgrimes    anyreds = 0;
3331590Srgrimes    for (q = p; q ; q = q->next)
3341590Srgrimes    {
3351590Srgrimes	if (q->action_code == REDUCE && q->suppressed < 2)
3361590Srgrimes	{
3371590Srgrimes	    anyreds = 1;
3381590Srgrimes	    break;
3391590Srgrimes	}
3401590Srgrimes    }
3411590Srgrimes
3421590Srgrimes    if (anyreds == 0)
3431590Srgrimes	fprintf(verbose_file, "\t.  error\n");
3441590Srgrimes    else
3451590Srgrimes    {
3461590Srgrimes	for (; p; p = p->next)
3471590Srgrimes	{
34887171Smarkm	    if (p->action_code == REDUCE && p->number != defreduct)
3491590Srgrimes	    {
3501590Srgrimes		k = p->number - 2;
3511590Srgrimes		if (p->suppressed == 0)
3521590Srgrimes		    fprintf(verbose_file, "\t%s  reduce %d\n",
3531590Srgrimes			    symbol_name[p->symbol], k);
3541590Srgrimes	    }
3551590Srgrimes	}
3561590Srgrimes
35787171Smarkm        if (defreduct > 0)
35887171Smarkm	    fprintf(verbose_file, "\t.  reduce %d\n", defreduct - 2);
3591590Srgrimes    }
3601590Srgrimes}
3611590Srgrimes
3621590Srgrimes
36321622Sstevestatic void
364214959Sobrienprint_gotos(int stateno)
3651590Srgrimes{
36687171Smarkm    int i, k;
36787171Smarkm    int as;
36887171Smarkm    short *tostate;
36987171Smarkm    shifts *sp;
3701590Srgrimes
3711590Srgrimes    putc('\n', verbose_file);
3721590Srgrimes    sp = shift_table[stateno];
37387171Smarkm    tostate = sp->shift;
3741590Srgrimes    for (i = 0; i < sp->nshifts; ++i)
3751590Srgrimes    {
37687171Smarkm	k = tostate[i];
3771590Srgrimes	as = accessing_symbol[k];
3781590Srgrimes	if (ISVAR(as))
3791590Srgrimes	    fprintf(verbose_file, "\t%s  goto %d\n", symbol_name[as], k);
3801590Srgrimes    }
3811590Srgrimes}
382