]> git.saurik.com Git - bison.git/blobdiff - src/print_graph.c
(derives_compute): Do not subtract NTOKENS from
[bison.git] / src / print_graph.c
index 7caba6f8e72b8711e808d754ff2073b92b8f5ad3..c92ae3577fdf89cf621484f9f98fc6073f998b2e 100644 (file)
@@ -1,5 +1,6 @@
 /* Output a VCG description on generated parser, for Bison,
 /* Output a VCG description on generated parser, for Bison,
-   Copyright 2001 Free Software Foundation, Inc.
+
+   Copyright (C) 2001, 2002 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
    This file is part of Bison, the GNU Compiler Compiler.
 
    Boston, MA 02111-1307, USA.  */
 
 #include "system.h"
    Boston, MA 02111-1307, USA.  */
 
 #include "system.h"
-#include "files.h"
-#include "gram.h"
+
+#include <obstack.h>
+#include <quotearg.h>
+
 #include "LR0.h"
 #include "LR0.h"
-#include "lalr.h"
-#include "conflicts.h"
+#include "closure.h"
 #include "complain.h"
 #include "complain.h"
+#include "conflicts.h"
+#include "files.h"
 #include "getargs.h"
 #include "getargs.h"
-#include "state.h"
-#include "reader.h"
-#include "obstack.h"
+#include "gram.h"
+#include "lalr.h"
 #include "print_graph.h"
 #include "print_graph.h"
+#include "reader.h"
+#include "state.h"
+#include "symtab.h"
 #include "vcg.h"
 
 #include "vcg.h"
 
-static graph_t graph;
+static graph static_graph;
 static FILE *fgraph = NULL;
 
 static FILE *fgraph = NULL;
 
-/* This part will construct the label of nodes. */
+
+/*----------------------------.
+| Construct the node labels.  |
+`----------------------------*/
+
 static void
 static void
-print_core (int state, struct obstack *node_obstack)
+print_core (struct obstack *oout, state *s)
 {
   int i;
 {
   int i;
-  core *statep = state_table[state].state;
+  item_number *sitems = s->items;
+  int snritems = s->nitems;
 
 
-  if (!statep->nitems)
-    return;
+  /* Output all the items of a state, not only its kernel.  */
+  if (report_flag & report_itemsets)
+    {
+      closure (sitems, snritems);
+      sitems = itemset;
+      snritems = nritemset;
+    }
 
 
-  for (i = 0; i < statep->nitems; i++)
+  obstack_fgrow1 (oout, "state %2d\n", s->number);
+  for (i = 0; i < snritems; i++)
     {
     {
-      short *sp;
-      short *sp1;
-      int rule;
+      item_number *sp;
+      item_number *sp1;
+      rule_number r;
 
 
-      sp1 = sp = ritem + statep->items[i];
+      sp1 = sp = ritem + sitems[i];
 
 
-      while (*sp > 0)
+      while (*sp >= 0)
        sp++;
 
        sp++;
 
-      rule = -(*sp);
+      r = item_number_as_rule_number (*sp);
 
       if (i)
 
       if (i)
-       obstack_1grow (node_obstack, '\n');
-      obstack_fgrow1 (node_obstack, "%d: ", rule);
-      obstack_fgrow1 (node_obstack, " %s  ->  ",
-                     tags[rule_table[rule].lhs]);
+       obstack_1grow (oout, '\n');
+      obstack_fgrow1 (oout, " %s -> ",
+                     rules[r].lhs->tag);
+
+      for (sp = rules[r].rhs; sp < sp1; sp++)
+       obstack_fgrow1 (oout, "%s ", symbols[*sp]->tag);
 
 
-      for (sp = ritem + rule_table[rule].rhs; sp < sp1; sp++)
-       obstack_fgrow1 (node_obstack, "%s ", tags[*sp]);
+      obstack_1grow (oout, '.');
 
 
-      obstack_1grow (node_obstack, '.');
+      for (/* Nothing */; *sp >= 0; ++sp)
+       obstack_fgrow1 (oout, " %s", symbols[*sp]->tag);
 
 
-      for (/* Nothing */; *sp > 0; ++sp)
-       obstack_fgrow1 (node_obstack, " %s", tags[*sp]);
+      /* Experimental feature: display the lookaheads. */
+      if (report_flag & report_lookaheads)
+       {
+         /* Find the reduction we are handling.  */
+         reductions *reds = s->reductions;
+         int redno = state_reduction_find (s, &rules[r]);
+
+         /* Print them if there are.  */
+         if (reds->lookaheads && redno != -1)
+           {
+             bitset_iterator biter;
+             int k;
+             int not_first = 0;
+             obstack_sgrow (oout, "[");
+             BITSET_FOR_EACH (biter, reds->lookaheads[redno], k, 0)
+               obstack_fgrow2 (oout, "%s%s",
+                               not_first++ ? ", " : "",
+                               symbols[k]->tag);
+             obstack_sgrow (oout, "]");
+           }
+       }
     }
 }
 
     }
 }
 
@@ -81,128 +119,43 @@ print_core (int state, struct obstack *node_obstack)
 `---------------------------------------------------------------*/
 
 static void
 `---------------------------------------------------------------*/
 
 static void
-print_actions (int state, const char *node_name)
+print_actions (state *s, const char *node_name)
 {
   int i;
 {
   int i;
-  int k;
-  int state1;
-  int symbol;
-  shifts *shiftp;
-  errs *errp;
-  reductions *redp;
-  int rule;
-  static char buff[10];
-  edge_t edge;
-
-  shiftp = state_table[state].shift_table;
-  redp = state_table[state].reduction_table;
-  errp = err_table[state];
-
-  if (!shiftp && !redp)
-    {
-#if 0
-      if (final_state == state)
-       obstack_sgrow (node_obstack, "$default: accept");
-      else
-       obstack_sgrow (node_obstack, "NO ACTIONS");
-#endif
-      return;
-    }
-
-  if (shiftp)
-    {
-      k = shiftp->nshifts;
-
-      for (i = 0; i < k; i++)
-       {
-         if (!shiftp->shifts[i])
-           continue;
-         state1 = shiftp->shifts[i];
-         symbol = state_table[state1].accessing_symbol;
-
-         if (ISVAR (symbol))
-           break;
-
-         {
-           new_edge (&edge);
-
-           if (state > state1)
-             edge.type = back_edge;
-           open_edge (&edge, fgraph);
-           /* The edge source is the current node.  */
-           edge.sourcename = node_name;
-           sprintf (buff, "%d", state1);
-           edge.targetname = buff;
-           edge.color = (symbol == 0) ? red : blue;
-           edge.label = tags[symbol];
-           output_edge (&edge, fgraph);
-           close_edge (fgraph);
-         }
-       }
-    }
-  else
-    {
-      i = 0;
-      k = 0;
-    }
 
 
-#if 0
-  if (errp)
-    {
-      int j, nerrs;
-
-      nerrs = errp->nerrs;
+  transitions *trans = s->transitions;
+  reductions *reds = s->reductions;
 
 
-      for (j = 0; j < nerrs; j++)
-       {
-         if (!errp->errs[j])
-           continue;
-         symbol = errp->errs[j];
-         /* If something has been added in the NODE_OBSTACK after
-            the declaration of the label, then we need a `\n'.
-         if (obstack_object_size (node_obstack) > node_output_size)
-           obstack_sgrow (node_obstack, "\n");
-           */
-         obstack_fgrow1 (node_obstack, _("%-4s\terror (nonassociative)"),
-                         tags[symbol]);
-       }
-      if (j > 0)
-       obstack_1grow (node_obstack, '\n');
-    }
+  static char buff[10];
+  edge e;
 
 
-  if (state_table[state].consistent && redp)
-    {
-      rule = redp->rules[0];
-      symbol = rule_table[rule].lhs;
-      /*
-      if (obstack_object_size (node_obstack) > node_output_size)
-       obstack_sgrow (node_obstack, "\n");
-       */
-      obstack_fgrow2 (node_obstack, _("$default\treduce using rule %d (%s)"),
-                     rule, tags[symbol]);
-    }
-#endif
+  if (!trans->num && !reds)
+    return;
 
 
-  if (i < k)
-    {
-      for (; i < k; i++)
-       {
-         if (!shiftp->shifts[i])
-           continue;
-         state1 = shiftp->shifts[i];
-         symbol = state_table[state1].accessing_symbol;
-
-         new_edge (&edge);
-         open_edge (&edge, fgraph);
-         edge.sourcename = node_name;
-         sprintf (buff, "%d", state1);
-         edge.targetname = buff;
-         edge.color = red;
-         edge.label = tags[symbol];
-         output_edge (&edge, fgraph);
-         close_edge (fgraph);
-       }
-    }
+  for (i = 0; i < trans->num; i++)
+    if (!TRANSITION_IS_DISABLED (trans, i))
+      {
+       state *s1 = trans->states[i];
+       symbol_number sym = s1->accessing_symbol;
+
+       new_edge (&e);
+
+       if (s->number > s1->number)
+         e.type = back_edge;
+       open_edge (&e, fgraph);
+       /* The edge source is the current node.  */
+       e.sourcename = node_name;
+       sprintf (buff, "%d", s1->number);
+       e.targetname = buff;
+       /* Shifts are blue, gotos are green, and error is red. */
+       if (TRANSITION_IS_ERROR (trans, i))
+         e.color = red;
+       else
+         e.color = TRANSITION_IS_SHIFT (trans, i) ? blue : green;
+       e.label = symbols[sym]->tag;
+       output_edge (&e, fgraph);
+       close_edge (fgraph);
+      }
 }
 
 
 }
 
 
@@ -212,27 +165,27 @@ print_actions (int state, const char *node_name)
 `-------------------------------------------------------------*/
 
 static void
 `-------------------------------------------------------------*/
 
 static void
-print_state (int state)
+print_state (state *s)
 {
   static char name[10];
   struct obstack node_obstack;
 {
   static char name[10];
   struct obstack node_obstack;
-  node_t node;
+  node n;
 
   /* The labels of the nodes are their the items.  */
   obstack_init (&node_obstack);
 
   /* The labels of the nodes are their the items.  */
   obstack_init (&node_obstack);
-  new_node (&node);
-  sprintf (name, "%d", state);
-  node.title = name;
-  print_core (state, &node_obstack);
+  new_node (&n);
+  sprintf (name, "%d", s->number);
+  n.title = name;
+  print_core (&node_obstack, s);
   obstack_1grow (&node_obstack, '\0');
   obstack_1grow (&node_obstack, '\0');
-  node.label = obstack_finish (&node_obstack);
+  n.label = obstack_finish (&node_obstack);
 
   open_node (fgraph);
 
   open_node (fgraph);
-  output_node (&node, fgraph);
+  output_node (&n, fgraph);
   close_node (fgraph);
 
   /* Output the edges.  */
   close_node (fgraph);
 
   /* Output the edges.  */
-  print_actions (state, name);
+  print_actions (s, name);
 
   obstack_free (&node_obstack, 0);
 }
 
   obstack_free (&node_obstack, 0);
 }
@@ -241,41 +194,40 @@ print_state (int state)
 void
 print_graph (void)
 {
 void
 print_graph (void)
 {
-  int i;
-
-  if (!graph_flag)
-    return;
+  state_number i;
 
   /* Output file.  */
   fgraph = xfopen (spec_graph_file, "w");
 
 
   /* Output file.  */
   fgraph = xfopen (spec_graph_file, "w");
 
-  new_graph (&graph);
+  new_graph (&static_graph);
 
 #if 0
 
 #if 0
-  graph.smanhattan_edges = yes;
-  graph.manhattan_edges = yes;
+  static_graph.smanhattan_edges = yes;
+  static_graph.manhattan_edges = yes;
 #endif
 
 #endif
 
-  graph.display_edge_labels = yes;
-  graph.layoutalgorithm = normal;
+  static_graph.display_edge_labels = yes;
+  static_graph.layoutalgorithm = normal;
 
 
-  graph.port_sharing = no;
-  graph.finetuning = yes;
-  graph.straight_phase = yes;
-  graph.priority_phase = yes;
-  graph.splines = yes;
+  static_graph.port_sharing = no;
+  static_graph.finetuning = yes;
+  static_graph.long_straight_phase = yes;
+  static_graph.priority_phase = yes;
+  static_graph.splines = yes;
 
 
-  graph.crossing_weight = median;
+  static_graph.crossing_weight = median;
 
   /* Output graph options. */
   open_graph (fgraph);
 
   /* Output graph options. */
   open_graph (fgraph);
-  output_graph (&graph, fgraph);
+  output_graph (&static_graph, fgraph);
 
   /* Output nodes and edges. */
 
   /* Output nodes and edges. */
+  new_closure (nritems);
   for (i = 0; i < nstates; i++)
   for (i = 0; i < nstates; i++)
-    print_state (i);
+    print_state (states[i]);
+  free_closure ();
 
   /* Close graph. */
 
   /* Close graph. */
-  close_graph (&graph, fgraph);
+  close_graph (&static_graph, fgraph);
   xfclose (fgraph);
 }
   xfclose (fgraph);
 }