home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / BYACC.ZIP / VERBOSE.C < prev    next >
C/C++ Source or Header  |  1992-03-16  |  7KB  |  331 lines

  1. #include <stdlib.h>
  2. #include "byacc.h"
  3.  
  4. static short *null_rules;
  5.  
  6. void
  7. verbose(void)
  8. {
  9.     register int i;
  10.  
  11.     if (!vflag) return;
  12.  
  13.     null_rules = (short *) MALLOC(nrules*sizeof(short));
  14.     if (null_rules == 0) no_space();
  15.     fprintf(verbose_file, "\f\n");
  16.     for (i = 0; i < nstates; i++)
  17.     print_state(i);
  18.     FREE(null_rules);
  19.  
  20.     if (nunused)
  21.     log_unused();
  22.     if (SRtotal || RRtotal)
  23.     log_conflicts();
  24.  
  25.     fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens,
  26.         nvars);
  27.     fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates);
  28. }
  29.  
  30. void
  31. log_unused(void)
  32. {
  33.     register int i;
  34.     register short *p;
  35.  
  36.     fprintf(verbose_file, "\n\nRules never reduced:\n");
  37.     for (i = 3; i < nrules; ++i)
  38.     {
  39.     if (!rules_used[i])
  40.     {
  41.         fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]);
  42.         for (p = ritem + rrhs[i]; *p >= 0; ++p)
  43.         fprintf(verbose_file, " %s", symbol_name[*p]);
  44.         fprintf(verbose_file, "  (%d)\n", i - 2);
  45.     }
  46.     }
  47. }
  48.  
  49.  
  50. void
  51. log_conflicts(void)
  52. {
  53.     register int i;
  54.  
  55.     fprintf(verbose_file, "\n\n");
  56.     for (i = 0; i < nstates; i++)
  57.     {
  58.     if (SRconflicts[i] || RRconflicts[i])
  59.     {
  60.         fprintf(verbose_file, "State %d contains ", i);
  61.         if (SRconflicts[i] == 1)
  62.         fprintf(verbose_file, "1 shift/reduce conflict");
  63.         else if (SRconflicts[i] > 1)
  64.         fprintf(verbose_file, "%d shift/reduce conflicts",
  65.             SRconflicts[i]);
  66.         if (SRconflicts[i] && RRconflicts[i])
  67.         fprintf(verbose_file, ", ");
  68.         if (RRconflicts[i] == 1)
  69.         fprintf(verbose_file, "1 reduce/reduce conflict");
  70.         else if (RRconflicts[i] > 1)
  71.         fprintf(verbose_file, "%d reduce/reduce conflicts",
  72.             RRconflicts[i]);
  73.         fprintf(verbose_file, ".\n");
  74.     }
  75.     }
  76. }
  77.  
  78. void
  79. print_state(int state)
  80. {
  81.     if (state)
  82.     fprintf(verbose_file, "\n\n");
  83.     if (SRconflicts[state] || RRconflicts[state])
  84.     print_conflicts(state);
  85.     fprintf(verbose_file, "state %d\n", state);
  86.     print_core(state);
  87.     print_nulls(state);
  88.     print_actions(state);
  89. }
  90.  
  91. void
  92. print_conflicts(int state)
  93. {
  94.     register int symbol;
  95.     register action *p, *q, *r;
  96.  
  97.     for (p = parser[state]; p; p = q->next)
  98.     {
  99.     q = p;
  100.     if (p->action_code == ERROR || p->suppressed == 2)
  101.         continue;
  102.  
  103.     symbol = p->symbol;
  104.     while (q->next && q->next->symbol == symbol)
  105.         q = q->next;
  106.     if (state == final_state && symbol == 0)
  107.     {
  108.         r = p;
  109.         for (;;)
  110.         {
  111.         fprintf(verbose_file, "%d: shift/reduce conflict \
  112. (accept, reduce %d) on $end\n", state, r->number);
  113.         if (r == q) break;
  114.         r = r->next;
  115.         }
  116.     }
  117.     else if (p != q)
  118.     {
  119.         r = p->next;
  120.         if (p->action_code == SHIFT)
  121.         {
  122.         for (;;)
  123.         {
  124.             if (r->action_code == REDUCE && p->suppressed != 2)
  125.             fprintf(verbose_file, "%d: shift/reduce conflict \
  126. (shift %d, reduce %d) on %s\n", state, p->number, r->number,
  127.                 symbol_name[symbol]);
  128.             if (r == q) break;
  129.             r = r->next;
  130.         }
  131.         }
  132.         else
  133.         {
  134.         for (;;)
  135.         {
  136.             if (r->action_code == REDUCE && p->suppressed != 2)
  137.             fprintf(verbose_file, "%d: reduce/reduce conflict \
  138. (reduce %d, reduce %d) on %s\n", state, p->number, r->number,
  139.                 symbol_name[symbol]);
  140.             if (r == q) break;
  141.             r = r->next;
  142.         }
  143.         }
  144.     }
  145.     }
  146. }
  147.  
  148. void
  149. print_core(int state)
  150. {
  151.     register int i;
  152.     register int k;
  153.     register int rule;
  154.     register core *statep;
  155.     register short *sp;
  156.     register short *sp1;
  157.  
  158.     statep = state_table[state];
  159.     k = statep->nitems;
  160.  
  161.     for (i = 0; i < k; i++)
  162.     {
  163.     sp1 = sp = ritem + statep->items[i];
  164.  
  165.     while (*sp >= 0) ++sp;
  166.     rule = -(*sp);
  167.     fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]);
  168.  
  169.         for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
  170.         fprintf(verbose_file, "%s ", symbol_name[*sp]);
  171.  
  172.     putc('.', verbose_file);
  173.  
  174.     while (*sp >= 0)
  175.     {
  176.         fprintf(verbose_file, " %s", symbol_name[*sp]);
  177.         sp++;
  178.     }
  179.     fprintf(verbose_file, "  (%d)\n", -2 - *sp);
  180.     }
  181. }
  182.  
  183. void
  184. print_nulls(int state)
  185. {
  186.     register action *p;
  187.     register int i, j, k, nnulls;
  188.  
  189.     nnulls = 0;
  190.     for (p = parser[state]; p; p = p->next)
  191.     {
  192.     if (p->action_code == REDUCE && p->suppressed == 0)
  193.     {
  194.         i = p->number;
  195.         if (rrhs[i] + 1 == rrhs[i+1])
  196.         {
  197.         for (j = 0; j < nnulls && i < null_rules[j]; ++j)
  198.             continue;
  199.         if (j == nnulls)
  200.         {
  201.             ++nnulls;
  202.             null_rules[j] = i;
  203.         }
  204.         else if (i != null_rules[j])
  205.         {
  206.             ++nnulls;
  207.             for (k = nnulls - 1; k > j; --k)
  208.             null_rules[k] = null_rules[k-1];
  209.             null_rules[j] = i;
  210.         }
  211.         }
  212.     }
  213.     }
  214.  
  215.     for (i = 0; i < nnulls; ++i)
  216.     {
  217.     j = null_rules[i];
  218.     fprintf(verbose_file, "\t%s : .  (%d)\n", symbol_name[rlhs[j]],
  219.         j - 2);
  220.     }
  221.     fprintf(verbose_file, "\n");
  222. }
  223.  
  224. void
  225. print_actions(int stateno)
  226. {
  227.     register action *p;
  228.     register shifts *sp;
  229.     register int as;
  230.  
  231.     if (stateno == final_state)
  232.     fprintf(verbose_file, "\t$end  accept\n");
  233.  
  234.     p = parser[stateno];
  235.     if (p)
  236.     {
  237.     print_shifts(p);
  238.     print_reductions(p, defred[stateno]);
  239.     }
  240.  
  241.     sp = shift_table[stateno];
  242.     if (sp && sp->nshifts > 0)
  243.     {
  244.     as = accessing_symbol[sp->shifts[sp->nshifts - 1]];
  245.     if (ISVAR(as))
  246.         print_gotos(stateno);
  247.     }
  248. }
  249.  
  250. void
  251. print_shifts(register action *p)
  252. {
  253.     register int count;
  254.     register action *q;
  255.  
  256.     count = 0;
  257.     for (q = p; q; q = q->next)
  258.     {
  259.     if (q->suppressed < 2 && q->action_code == SHIFT)
  260.         ++count;
  261.     }
  262.  
  263.     if (count > 0)
  264.     {
  265.     for (; p; p = p->next)
  266.     {
  267.         if (p->action_code == SHIFT && p->suppressed == 0)
  268.         fprintf(verbose_file, "\t%s  shift %d\n",
  269.                 symbol_name[p->symbol], p->number);
  270.     }
  271.     }
  272. }
  273.  
  274. void
  275. print_reductions(register action *p, register int defred)
  276. {
  277.     register int k, anyreds;
  278.     register action *q;
  279.  
  280.     anyreds = 0;
  281.     for (q = p; q ; q = q->next)
  282.     {
  283.     if (q->action_code == REDUCE && q->suppressed < 2)
  284.     {
  285.         anyreds = 1;
  286.         break;
  287.     }
  288.     }
  289.  
  290.     if (anyreds == 0)
  291.     fprintf(verbose_file, "\t.  error\n");
  292.     else
  293.     {
  294.     for (; p; p = p->next)
  295.     {
  296.         if (p->action_code == REDUCE && p->number != defred)
  297.         {
  298.         k = p->number - 2;
  299.         if (p->suppressed == 0)
  300.             fprintf(verbose_file, "\t%s  reduce %d\n",
  301.                 symbol_name[p->symbol], k);
  302.         }
  303.     }
  304.  
  305.         if (defred > 0)
  306.         fprintf(verbose_file, "\t.  reduce %d\n", defred - 2);
  307.     }
  308. }
  309.  
  310. void
  311. print_gotos(int stateno)
  312. {
  313.     register int i, k;
  314.     register int as;
  315.     register short *to_state;
  316.     register shifts *sp;
  317.  
  318.     putc('\n', verbose_file);
  319.     sp = shift_table[stateno];
  320.     to_state = sp->shifts;
  321.     for (i = sp->nshifts - 1; i >= 0; i--)
  322.     {
  323.     k = to_state[i];
  324.     as = accessing_symbol[k];
  325.     if (ISVAR(as))
  326.         fprintf(verbose_file, "\t%s  goto %d\n", symbol_name[as], k);
  327.     else
  328.         break;
  329.     }
  330. }
  331.