verbose.c revision 1590
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 * 3. All advertising materials mentioning features or use of this software
171590Srgrimes *    must display the following acknowledgement:
181590Srgrimes *	This product includes software developed by the University of
191590Srgrimes *	California, Berkeley and its contributors.
201590Srgrimes * 4. Neither the name of the University nor the names of its contributors
211590Srgrimes *    may be used to endorse or promote products derived from this software
221590Srgrimes *    without specific prior written permission.
231590Srgrimes *
241590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
251590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
261590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
271590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
281590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
291590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
301590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
311590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
321590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
331590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
341590Srgrimes * SUCH DAMAGE.
351590Srgrimes */
361590Srgrimes
371590Srgrimes#ifndef lint
381590Srgrimesstatic char sccsid[] = "@(#)verbose.c	5.3 (Berkeley) 1/20/91";
391590Srgrimes#endif /* not lint */
401590Srgrimes
411590Srgrimes#include "defs.h"
421590Srgrimes
431590Srgrimesstatic short *null_rules;
441590Srgrimes
451590Srgrimesverbose()
461590Srgrimes{
471590Srgrimes    register int i;
481590Srgrimes
491590Srgrimes    if (!vflag) return;
501590Srgrimes
511590Srgrimes    null_rules = (short *) MALLOC(nrules*sizeof(short));
521590Srgrimes    if (null_rules == 0) no_space();
531590Srgrimes    fprintf(verbose_file, "\f\n");
541590Srgrimes    for (i = 0; i < nstates; i++)
551590Srgrimes	print_state(i);
561590Srgrimes    FREE(null_rules);
571590Srgrimes
581590Srgrimes    if (nunused)
591590Srgrimes	log_unused();
601590Srgrimes    if (SRtotal || RRtotal)
611590Srgrimes	log_conflicts();
621590Srgrimes
631590Srgrimes    fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens,
641590Srgrimes	    nvars);
651590Srgrimes    fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates);
661590Srgrimes}
671590Srgrimes
681590Srgrimes
691590Srgrimeslog_unused()
701590Srgrimes{
711590Srgrimes    register int i;
721590Srgrimes    register short *p;
731590Srgrimes
741590Srgrimes    fprintf(verbose_file, "\n\nRules never reduced:\n");
751590Srgrimes    for (i = 3; i < nrules; ++i)
761590Srgrimes    {
771590Srgrimes	if (!rules_used[i])
781590Srgrimes	{
791590Srgrimes	    fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]);
801590Srgrimes	    for (p = ritem + rrhs[i]; *p >= 0; ++p)
811590Srgrimes		fprintf(verbose_file, " %s", symbol_name[*p]);
821590Srgrimes	    fprintf(verbose_file, "  (%d)\n", i - 2);
831590Srgrimes	}
841590Srgrimes    }
851590Srgrimes}
861590Srgrimes
871590Srgrimes
881590Srgrimeslog_conflicts()
891590Srgrimes{
901590Srgrimes    register int i;
911590Srgrimes
921590Srgrimes    fprintf(verbose_file, "\n\n");
931590Srgrimes    for (i = 0; i < nstates; i++)
941590Srgrimes    {
951590Srgrimes	if (SRconflicts[i] || RRconflicts[i])
961590Srgrimes	{
971590Srgrimes	    fprintf(verbose_file, "State %d contains ", i);
981590Srgrimes	    if (SRconflicts[i] == 1)
991590Srgrimes		fprintf(verbose_file, "1 shift/reduce conflict");
1001590Srgrimes	    else if (SRconflicts[i] > 1)
1011590Srgrimes		fprintf(verbose_file, "%d shift/reduce conflicts",
1021590Srgrimes			SRconflicts[i]);
1031590Srgrimes	    if (SRconflicts[i] && RRconflicts[i])
1041590Srgrimes		fprintf(verbose_file, ", ");
1051590Srgrimes	    if (RRconflicts[i] == 1)
1061590Srgrimes		fprintf(verbose_file, "1 reduce/reduce conflict");
1071590Srgrimes	    else if (RRconflicts[i] > 1)
1081590Srgrimes		fprintf(verbose_file, "%d reduce/reduce conflicts",
1091590Srgrimes			RRconflicts[i]);
1101590Srgrimes	    fprintf(verbose_file, ".\n");
1111590Srgrimes	}
1121590Srgrimes    }
1131590Srgrimes}
1141590Srgrimes
1151590Srgrimes
1161590Srgrimesprint_state(state)
1171590Srgrimesint state;
1181590Srgrimes{
1191590Srgrimes    if (state)
1201590Srgrimes	fprintf(verbose_file, "\n\n");
1211590Srgrimes    if (SRconflicts[state] || RRconflicts[state])
1221590Srgrimes	print_conflicts(state);
1231590Srgrimes    fprintf(verbose_file, "state %d\n", state);
1241590Srgrimes    print_core(state);
1251590Srgrimes    print_nulls(state);
1261590Srgrimes    print_actions(state);
1271590Srgrimes}
1281590Srgrimes
1291590Srgrimes
1301590Srgrimesprint_conflicts(state)
1311590Srgrimesint state;
1321590Srgrimes{
1331590Srgrimes    register int symbol, act, number;
1341590Srgrimes    register action *p;
1351590Srgrimes
1361590Srgrimes    symbol = -1;
1371590Srgrimes    for (p = parser[state]; p; p = p->next)
1381590Srgrimes    {
1391590Srgrimes	if (p->suppressed == 2)
1401590Srgrimes	    continue;
1411590Srgrimes
1421590Srgrimes	if (p->symbol != symbol)
1431590Srgrimes	{
1441590Srgrimes	    symbol = p->symbol;
1451590Srgrimes	    number = p->number;
1461590Srgrimes	    if (p->action_code == SHIFT)
1471590Srgrimes		act = SHIFT;
1481590Srgrimes	    else
1491590Srgrimes		act = REDUCE;
1501590Srgrimes	}
1511590Srgrimes	else if (p->suppressed == 1)
1521590Srgrimes	{
1531590Srgrimes	    if (state == final_state && symbol == 0)
1541590Srgrimes	    {
1551590Srgrimes		fprintf(verbose_file, "%d: shift/reduce conflict \
1561590Srgrimes(accept, reduce %d) on $end\n", state, p->number - 2);
1571590Srgrimes	    }
1581590Srgrimes	    else
1591590Srgrimes	    {
1601590Srgrimes		if (act == SHIFT)
1611590Srgrimes		{
1621590Srgrimes		    fprintf(verbose_file, "%d: shift/reduce conflict \
1631590Srgrimes(shift %d, reduce %d) on %s\n", state, number, p->number - 2,
1641590Srgrimes			    symbol_name[symbol]);
1651590Srgrimes		}
1661590Srgrimes		else
1671590Srgrimes		{
1681590Srgrimes		    fprintf(verbose_file, "%d: reduce/reduce conflict \
1691590Srgrimes(reduce %d, reduce %d) on %s\n", state, number - 2, p->number - 2,
1701590Srgrimes			    symbol_name[symbol]);
1711590Srgrimes		}
1721590Srgrimes	    }
1731590Srgrimes	}
1741590Srgrimes    }
1751590Srgrimes}
1761590Srgrimes
1771590Srgrimes
1781590Srgrimesprint_core(state)
1791590Srgrimesint state;
1801590Srgrimes{
1811590Srgrimes    register int i;
1821590Srgrimes    register int k;
1831590Srgrimes    register int rule;
1841590Srgrimes    register core *statep;
1851590Srgrimes    register short *sp;
1861590Srgrimes    register short *sp1;
1871590Srgrimes
1881590Srgrimes    statep = state_table[state];
1891590Srgrimes    k = statep->nitems;
1901590Srgrimes
1911590Srgrimes    for (i = 0; i < k; i++)
1921590Srgrimes    {
1931590Srgrimes	sp1 = sp = ritem + statep->items[i];
1941590Srgrimes
1951590Srgrimes	while (*sp >= 0) ++sp;
1961590Srgrimes	rule = -(*sp);
1971590Srgrimes	fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]);
1981590Srgrimes
1991590Srgrimes        for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
2001590Srgrimes	    fprintf(verbose_file, "%s ", symbol_name[*sp]);
2011590Srgrimes
2021590Srgrimes	putc('.', verbose_file);
2031590Srgrimes
2041590Srgrimes	while (*sp >= 0)
2051590Srgrimes	{
2061590Srgrimes	    fprintf(verbose_file, " %s", symbol_name[*sp]);
2071590Srgrimes	    sp++;
2081590Srgrimes	}
2091590Srgrimes	fprintf(verbose_file, "  (%d)\n", -2 - *sp);
2101590Srgrimes    }
2111590Srgrimes}
2121590Srgrimes
2131590Srgrimes
2141590Srgrimesprint_nulls(state)
2151590Srgrimesint state;
2161590Srgrimes{
2171590Srgrimes    register action *p;
2181590Srgrimes    register int i, j, k, nnulls;
2191590Srgrimes
2201590Srgrimes    nnulls = 0;
2211590Srgrimes    for (p = parser[state]; p; p = p->next)
2221590Srgrimes    {
2231590Srgrimes	if (p->action_code == REDUCE &&
2241590Srgrimes		(p->suppressed == 0 || p->suppressed == 1))
2251590Srgrimes	{
2261590Srgrimes	    i = p->number;
2271590Srgrimes	    if (rrhs[i] + 1 == rrhs[i+1])
2281590Srgrimes	    {
2291590Srgrimes		for (j = 0; j < nnulls && i > null_rules[j]; ++j)
2301590Srgrimes		    continue;
2311590Srgrimes
2321590Srgrimes		if (j == nnulls)
2331590Srgrimes		{
2341590Srgrimes		    ++nnulls;
2351590Srgrimes		    null_rules[j] = i;
2361590Srgrimes		}
2371590Srgrimes		else if (i != null_rules[j])
2381590Srgrimes		{
2391590Srgrimes		    ++nnulls;
2401590Srgrimes		    for (k = nnulls - 1; k > j; --k)
2411590Srgrimes			null_rules[k] = null_rules[k-1];
2421590Srgrimes		    null_rules[j] = i;
2431590Srgrimes		}
2441590Srgrimes	    }
2451590Srgrimes	}
2461590Srgrimes    }
2471590Srgrimes
2481590Srgrimes    for (i = 0; i < nnulls; ++i)
2491590Srgrimes    {
2501590Srgrimes	j = null_rules[i];
2511590Srgrimes	fprintf(verbose_file, "\t%s : .  (%d)\n", symbol_name[rlhs[j]],
2521590Srgrimes		j - 2);
2531590Srgrimes    }
2541590Srgrimes    fprintf(verbose_file, "\n");
2551590Srgrimes}
2561590Srgrimes
2571590Srgrimes
2581590Srgrimesprint_actions(stateno)
2591590Srgrimesint stateno;
2601590Srgrimes{
2611590Srgrimes    register action *p;
2621590Srgrimes    register shifts *sp;
2631590Srgrimes    register int as;
2641590Srgrimes
2651590Srgrimes    if (stateno == final_state)
2661590Srgrimes	fprintf(verbose_file, "\t$end  accept\n");
2671590Srgrimes
2681590Srgrimes    p = parser[stateno];
2691590Srgrimes    if (p)
2701590Srgrimes    {
2711590Srgrimes	print_shifts(p);
2721590Srgrimes	print_reductions(p, defred[stateno]);
2731590Srgrimes    }
2741590Srgrimes
2751590Srgrimes    sp = shift_table[stateno];
2761590Srgrimes    if (sp && sp->nshifts > 0)
2771590Srgrimes    {
2781590Srgrimes	as = accessing_symbol[sp->shift[sp->nshifts - 1]];
2791590Srgrimes	if (ISVAR(as))
2801590Srgrimes	    print_gotos(stateno);
2811590Srgrimes    }
2821590Srgrimes}
2831590Srgrimes
2841590Srgrimes
2851590Srgrimesprint_shifts(p)
2861590Srgrimesregister action *p;
2871590Srgrimes{
2881590Srgrimes    register int count;
2891590Srgrimes    register action *q;
2901590Srgrimes
2911590Srgrimes    count = 0;
2921590Srgrimes    for (q = p; q; q = q->next)
2931590Srgrimes    {
2941590Srgrimes	if (q->suppressed < 2 && q->action_code == SHIFT)
2951590Srgrimes	    ++count;
2961590Srgrimes    }
2971590Srgrimes
2981590Srgrimes    if (count > 0)
2991590Srgrimes    {
3001590Srgrimes	for (; p; p = p->next)
3011590Srgrimes	{
3021590Srgrimes	    if (p->action_code == SHIFT && p->suppressed == 0)
3031590Srgrimes		fprintf(verbose_file, "\t%s  shift %d\n",
3041590Srgrimes			    symbol_name[p->symbol], p->number);
3051590Srgrimes	}
3061590Srgrimes    }
3071590Srgrimes}
3081590Srgrimes
3091590Srgrimes
3101590Srgrimesprint_reductions(p, defred)
3111590Srgrimesregister action *p;
3121590Srgrimesregister int defred;
3131590Srgrimes{
3141590Srgrimes    register int k, anyreds;
3151590Srgrimes    register action *q;
3161590Srgrimes
3171590Srgrimes    anyreds = 0;
3181590Srgrimes    for (q = p; q ; q = q->next)
3191590Srgrimes    {
3201590Srgrimes	if (q->action_code == REDUCE && q->suppressed < 2)
3211590Srgrimes	{
3221590Srgrimes	    anyreds = 1;
3231590Srgrimes	    break;
3241590Srgrimes	}
3251590Srgrimes    }
3261590Srgrimes
3271590Srgrimes    if (anyreds == 0)
3281590Srgrimes	fprintf(verbose_file, "\t.  error\n");
3291590Srgrimes    else
3301590Srgrimes    {
3311590Srgrimes	for (; p; p = p->next)
3321590Srgrimes	{
3331590Srgrimes	    if (p->action_code == REDUCE && p->number != defred)
3341590Srgrimes	    {
3351590Srgrimes		k = p->number - 2;
3361590Srgrimes		if (p->suppressed == 0)
3371590Srgrimes		    fprintf(verbose_file, "\t%s  reduce %d\n",
3381590Srgrimes			    symbol_name[p->symbol], k);
3391590Srgrimes	    }
3401590Srgrimes	}
3411590Srgrimes
3421590Srgrimes        if (defred > 0)
3431590Srgrimes	    fprintf(verbose_file, "\t.  reduce %d\n", defred - 2);
3441590Srgrimes    }
3451590Srgrimes}
3461590Srgrimes
3471590Srgrimes
3481590Srgrimesprint_gotos(stateno)
3491590Srgrimesint stateno;
3501590Srgrimes{
3511590Srgrimes    register int i, k;
3521590Srgrimes    register int as;
3531590Srgrimes    register short *to_state;
3541590Srgrimes    register shifts *sp;
3551590Srgrimes
3561590Srgrimes    putc('\n', verbose_file);
3571590Srgrimes    sp = shift_table[stateno];
3581590Srgrimes    to_state = sp->shift;
3591590Srgrimes    for (i = 0; i < sp->nshifts; ++i)
3601590Srgrimes    {
3611590Srgrimes	k = to_state[i];
3621590Srgrimes	as = accessing_symbol[k];
3631590Srgrimes	if (ISVAR(as))
3641590Srgrimes	    fprintf(verbose_file, "\t%s  goto %d\n", symbol_name[as], k);
3651590Srgrimes    }
3661590Srgrimes}
367