]> git.saurik.com Git - bison.git/blobdiff - src/print_graph.c
* lib/bitset.h (__INT_TO_PTR): Define to a value that presumes C89.
[bison.git] / src / print_graph.c
index cabf6842227e13666e003f9c6536b6d6a0022206..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 "xalloc.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"
-#include "quotearg.h"
 
 
-static graph_t graph;
+static graph static_graph;
+static FILE *fgraph = NULL;
 
 
-/* Return an unambiguous printable representated, allocated in slot 0,
-   for NAME, suitable for C strings.  */
-static char const *
-quote (char const *name)
-{
-  return quotearg_n_style (0, escape_quoting_style, name);
-}
 
 
-/* This part will construct the label of nodes. */
+/*----------------------------.
+| Construct the node labels.  |
+`----------------------------*/
+
 static void
 static void
-print_core (int state)
+print_core (struct obstack *oout, state *s)
 {
   int i;
 {
   int i;
-  int k;
-  int rule;
-  core *statep;
-  short *sp;
-  short *sp1;
-
-  statep = state_table[state];
-  k = statep->nitems;
+  item_number *sitems = s->items;
+  int snritems = s->nitems;
 
 
-  if (k == 0)
-    return;
-
-  obstack_sgrow (&graph_obstack, "\t\tlabel:\t\"");
+  /* 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 < k; i++)
+  obstack_fgrow1 (oout, "state %2d\n", s->number);
+  for (i = 0; i < snritems; i++)
     {
     {
-      if (i)
-       obstack_sgrow (&graph_obstack, "\\n");
+      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);
 
 
-      obstack_fgrow1 (&graph_obstack, "%d: ", rule);
-      obstack_fgrow1 (&graph_obstack, " %s  ->  ", quote (tags[rlhs[rule]]));
+      if (i)
+       obstack_1grow (oout, '\n');
+      obstack_fgrow1 (oout, " %s -> ",
+                     rules[r].lhs->tag);
 
 
-      for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
-       obstack_fgrow1 (&graph_obstack, "%s ", quote (tags[*sp]));
+      for (sp = rules[r].rhs; sp < sp1; sp++)
+       obstack_fgrow1 (oout, "%s ", symbols[*sp]->tag);
 
 
-      obstack_1grow (&graph_obstack, '.');
+      obstack_1grow (oout, '.');
 
 
-      while (*sp > 0)
-       obstack_fgrow1 (&graph_obstack, " %s", quote (tags[*sp++]));
+      for (/* Nothing */; *sp >= 0; ++sp)
+       obstack_fgrow1 (oout, " %s", symbols[*sp]->tag);
 
 
+      /* 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, "]");
+           }
+       }
     }
     }
-  obstack_sgrow (&graph_obstack, "\"\n");
 }
 
 }
 
+
+/*---------------------------------------------------------------.
+| Output in graph_obstack edges specifications in incidence with |
+| current node.                                                  |
+`---------------------------------------------------------------*/
+
 static void
 static void
-print_actions (int state, node_t *node)
+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 = shift_table[state];
-  redp = reduction_table[state];
-  errp = err_table[state];
+  transitions *trans = s->transitions;
+  reductions *reds = s->reductions;
 
 
-  if (!shiftp && !redp)
-    {
-#if 0
-      if (final_state == state)
-       fprintf (f, "    $default\taccept\n");
-      else
-       fprintf (f, "    NO ACTIONS\n");
-#endif
-      return;
-    }
-
-  if (shiftp)
-    {
-      k = shiftp->nshifts;
-
-      for (i = 0; i < k; i++)
-       {
-         if (!shiftp->shifts[i])
-           continue;
-         state1 = shiftp->shifts[i];
-         symbol = accessing_symbol[state1];
-
-         if (ISVAR (symbol))
-           break;
-
-         {
-           new_edge (&edge);
-
-           if (state > state1)
-             edge.type = back_edge;
-           open_edge (&edge, &graph_obstack);
-           edge.sourcename = node->title;
-           sprintf (buff, "%d", state1);
-           edge.targetname = buff;
-           edge.color = (symbol == 0) ? blue : red;
-           /* FIXME: Be aware that quote uses static memory.  The string
-              must be output immediately (which is the case here). */
-           edge.label = tags[symbol] ? quote (tags[symbol]) : NULL;
-           output_edge (&edge, &graph_obstack);
-           close_edge (&graph_obstack);
-         }
-       }
-    }
-  else
-    {
-      i = 0;
-      k = 0;
-    }
+  static char buff[10];
+  edge e;
 
 
-  if (errp)
-    {
-      int j, nerrs;
+  if (!trans->num && !reds)
+    return;
 
 
-      nerrs = errp->nerrs;
+  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);
+      }
+}
 
 
-      for (j = 0; j < nerrs; j++)
-       {
-         if (!errp->errs[j])
-           continue;
-         symbol = errp->errs[j];
-       }
-    }
 
 
-  if (consistent[state] && redp)
-    {
-      rule = redp->rules[0];
-      symbol = rlhs[rule];
-    }
-
-  if (i < k)
-    {
-      for (; i < k; i++)
-       {
-         if (!shiftp->shifts[i])
-           continue;
-         state1 = shiftp->shifts[i];
-         symbol = accessing_symbol[state1];
-
-         new_edge (&edge);
-         open_edge (&edge, &graph_obstack);
-         edge.sourcename = node->title;
-         sprintf (buff, "%d", state1);
-         edge.targetname = buff;
-         edge.color = red;
-         edge.label = tags[symbol] ? quote (tags[symbol]) : NULL;
-         output_edge (&edge, &graph_obstack);
-         close_edge (&graph_obstack);
-       }
-    }
-}
+/*-------------------------------------------------------------.
+| Output in FGRAPH the current node specifications and exiting |
+| edges.                                                       |
+`-------------------------------------------------------------*/
 
 static void
 
 static void
-print_state (int state)
+print_state (state *s)
 {
   static char name[10];
 {
   static char name[10];
-  node_t node;
-
-  new_node (&node);
-  open_node (&graph_obstack);
-
-  sprintf (name, "%d", state);
-  node.title = name;
-  output_node (&node, &graph_obstack);
-
-  print_core (state);          /* node label */
-
-  close_node (&graph_obstack);
-
-  print_actions (state, &node);        /* edges */
+  struct obstack node_obstack;
+  node n;
+
+  /* The labels of the nodes are their the items.  */
+  obstack_init (&node_obstack);
+  new_node (&n);
+  sprintf (name, "%d", s->number);
+  n.title = name;
+  print_core (&node_obstack, s);
+  obstack_1grow (&node_obstack, '\0');
+  n.label = obstack_finish (&node_obstack);
+
+  open_node (fgraph);
+  output_node (&n, fgraph);
+  close_node (fgraph);
+
+  /* Output the edges.  */
+  print_actions (s, name);
+
+  obstack_free (&node_obstack, 0);
 }
 \f
 
 void
 print_graph (void)
 {
 }
 \f
 
 void
 print_graph (void)
 {
-  int i;
+  state_number i;
 
 
-  if (!graph_flag)
-    return;
-  new_graph (&graph);
+  /* Output file.  */
+  fgraph = xfopen (spec_graph_file, "w");
+
+  new_graph (&static_graph);
 
 
-  /* graph.smanhattan_edges = yes;
-     graph.manhattan_edges = yes; */
+#if 0
+  static_graph.smanhattan_edges = yes;
+  static_graph.manhattan_edges = yes;
+#endif
 
 
-  graph.display_edge_labels = yes;
-  graph.layoutalgorithm = 0;
+  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. */
 
   /* Output graph options. */
-  open_graph (&graph_obstack);
-  output_graph (&graph, &graph_obstack);
+  open_graph (fgraph);
+  output_graph (&static_graph, fgraph);
 
 
+  /* Output nodes and edges. */
+  new_closure (nritems);
   for (i = 0; i < nstates; i++)
   for (i = 0; i < nstates; i++)
-    /* Output nodes & edges. */
-    print_state (i);
+    print_state (states[i]);
+  free_closure ();
 
   /* Close graph. */
 
   /* Close graph. */
-  close_graph (&graph, &graph_obstack);
+  close_graph (&static_graph, fgraph);
+  xfclose (fgraph);
 }
 }