hi,

Here is a bare bones implementation (mostly a weekend hack) of graphviz
(dot) format output for Bison; The code is very similiar to current VCG
implementation.  I ran it against the calc++ example..the dot file is
attached here, and this graph is generated by running it thru `dot' with the
-Tpng option: http://cs.uic.edu/~spopuri/la.png

Comments please..

thanks,
satya.

Attachment: calc++-parser.dot
Description: MS-Word document

/* Output Graphviz specification of a state machine genetated by Bison.
   Copyright (C) 2001, 2002, 2005, 2006 Free Software Foundation, Inc.

   This file is part of Bison, the GNU Compiler Compiler.

   Bison is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   Bison is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with Bison; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

#include <config.h>
#include "system.h"

#include <quotearg.h>

#include "graphviz.h"
#include "graphviz_defaults.h"

/** Local functions */
static void output_color(enum color, FILE *);
static void output_node_attributes(struct node_attributes *, FILE *);
static void output_edge_attributes(struct edge_attributes *, FILE *);
static void output_graph_attributes(struct graph_attributes *, FILE *);
static void new_node_attributes(struct node_attributes *);
static void new_edge_attributes(struct edge_attributes *);
static void new_graph_attributes(struct graph_attributes *);
static bool  output_separator(bool, FILE *);

/* Return an unambiguous printable representated, for NAME, suitable
   for C strings.  Use slot 2 since the user may use slots 0 and 1.
*/

static char const *
quote (char const *name)
{
  return quotearg_n_style (2, c_quoting_style, name);
}

void
new_graph (graph *g)
{
  g->title = G_TITLE;
  new_graph_attributes(&g->graph_attributes);
  /* Some default attributes for all nodes and edges */
  new_node_attributes(&g->node_attributes);
  g->node_attributes.shape = circle;
  g->node_attributes.fillcolor = white;
  g->node_attributes.textcolor = blue;
  g->node_attributes.bordercolor = black;

  new_edge_attributes(&g->edge_attributes);
  g->edge_attributes.weight=2.0;
  g->edge_attributes.color=black;
  g->edge_attributes.textcolor=black;
  g->edge_attributes.arrowstyle=normal;
}

void
open_graph (FILE *fout)
{
  fprintf(fout,"digraph ");
}

void
output_graph(graph *g, FILE *fout)
{
  bool atleastone= false;
  
  /* output the graph attributes first */
  if(g->title != G_TITLE)
  {
    fprintf(fout,"%s {\n",g->title);
  }
  
  fprintf(fout,"\tgraph");
  output_graph_attributes(&g->graph_attributes,fout); 
  fprintf(fout,"\n");
  
  /* Done with graph params; output node and edge params */
  fprintf(fout,"\tnode");
  output_node_attributes(&g->node_attributes,fout);
  fprintf(fout,"\n");
  
  fprintf(fout,"\tedge");
  output_edge_attributes(&g->edge_attributes,fout);
  fprintf(fout,"\n");

  /*An extra new line to separate the states */
  fprintf(fout,"\n");
}

void
close_graph(FILE *fout)
{
  fprintf(fout,"\n}");
}

/** Create a new node */
void
new_node(node *n)
{
  n->title = N_TITLE;
  new_node_attributes(&n->attrs);
}

void 
open_node(FILE *fout)
{
  fprintf(fout,"\t");
}

void 
output_node(node *n, FILE *fout)
{
  /** Ouput the node name and then properties */
  fprintf(fout, "%s",n->title);
  output_node_attributes(&n->attrs,fout);
}

void 
close_node(FILE *fout)
{
  fprintf(fout,"\n");
}

/** Create a new edge. */
void
new_edge(edge *e)
{
  e->sourcename = E_SOURCENAME;
  e->targetname = E_TARGETNAME;

  new_edge_attributes(&e->attrs);
}

void 
open_edge(FILE *fout)
{
  fprintf(fout,"\t");
}

void 
output_edge(edge *e, FILE *fout)
{
  fprintf(fout,"%s -> %s",e->sourcename,e->targetname);
  output_edge_attributes(&e->attrs,fout);
}

void 
close_edge(FILE *fout)
{
  fprintf(fout, "\n");
}

void
output_color(enum color color, FILE *fout)
{
  switch(color)
  {
    case black: fprintf(fout, "black"); break;
    case red:   fprintf(fout, "red"); 	break;
    case blue:	fprintf(fout, "blue");	break;
    case green: fprintf(fout, "green");	break;
    case white: 
    default:	fprintf(fout, "white"); break;
  }
} 

void
output_node_attributes(struct node_attributes *na, FILE *fout)
{
  bool atleastone = false;
  fprintf(fout,"  [");

  /** Output the label */
  if(na->label != NA_LABEL)
  {
    fprintf(fout,"label=%s", quote(na->label));
    atleastone = true;
  }
  
  /** Output shape attribute. */
  if(na->shape != NA_SHAPE)
  {
    atleastone = output_separator(atleastone,fout);
    fprintf(fout,"shape=");
    switch(na->shape)
    {
      case box:	 		fprintf(fout,"box");
		 		break;
      case doublecircle: 	fprintf(fout, "doublecircle");
		       		break;
      case circle:
      default: 			fprintf(fout,"circle");
				break;
    }
  }
  
  /** Output fillcolor. */
  if(na->fillcolor != NA_FILLCOLOR)
  {
    atleastone = output_separator(atleastone,fout);
    fprintf(fout,"fillcolor=");
    output_color(na->fillcolor,fout);
  }
    /** Output node textcolor. */
  if(na->textcolor != NA_FONTCOLOR)
  {
    atleastone = output_separator(atleastone,fout);
    fprintf(fout,"fontcolor=");
    output_color(na->textcolor, fout);
  }
  
  /** Output node border color. */
  if(na->bordercolor != NA_COLOR)
  {
    atleastone = output_separator(atleastone,fout);
    fprintf(fout,"color=");
    output_color(na->bordercolor, fout);
  }
  
  /** Close the node attributes. */
  fprintf(fout, "];");
}

void
output_edge_attributes(struct edge_attributes *ea, FILE *fout){
  bool atleastone = false;
  
  /** Output generic edge properties. */
  fprintf(fout, "  [");
  
  /** Edge label */
  if(ea->label != EA_LABEL)
  {
    fprintf(fout, "label=%s",quote(ea->label));
    atleastone = true;
  }
  
  /** Edge weight. */
  if(ea->weight != EA_WEIGHT)
  {
    atleastone = output_separator(atleastone,fout);
    fprintf(fout, "weight=%2.1f", ea->weight);
  }
  
  /** Edge colors. */
  if(ea->color != EA_COLOR)
  {
    atleastone = output_separator(atleastone,fout);
    fprintf(fout, "fontcolor=");
    output_color(ea->color,fout);
  }
  
  if(ea->textcolor != EA_FONTCOLOR)
  {
    atleastone = output_separator(atleastone,fout);
    fprintf(fout, "color=");
    output_color(ea->textcolor, fout);
  }
  
  /** Arrow style. */
  if(ea->arrowstyle != EA_ARROWSTYLE)
  {
    atleastone = output_separator(atleastone,fout);
    fprintf(fout, "arrowhead=");
    switch(ea->arrowstyle)
    {
      case empty:	fprintf(fout, "empty" );  break;
      case vee:	 	fprintf(fout, "vee"   );  break;
      case normal: 
      default:	 	fprintf(fout, "normal");  break;
    }
  }
  /** Close the general edge properties */
  fprintf(fout, "];");
}

void 
output_graph_attributes(struct graph_attributes *ga, FILE *fout)
{
  bool atleastone = false;
  
  fprintf(fout," [");
  
  if(ga->orientation != G_ORIENTATION)
  {
    fprintf(fout,"rankdir=");
    switch(ga->orientation)
    {
      case top_to_bottom: fprintf(fout,"TB");
			break;
      case right_to_left: fprintf(fout,"RL");
			break;
      case bottom_to_top: fprintf(fout,"BT");
			break;

      case left_to_right: 
      default:		fprintf(fout,"LR");
			break;
    }
    atleastone = true;
  }
  
  if(ga->splines != G_SPLINES)
  {
    atleastone = output_separator(atleastone,fout);
    fprintf(fout,"splines=");
    if(ga->splines == yes)
      fprintf(fout,"true");
    else
      fprintf(fout,"false");
  }
  
  if(ga->center != G_CENTER)
  { 
    atleastone = output_separator(atleastone,fout);
    fprintf(fout, "center=");
    if(ga->center == yes)
      fprintf(fout,"true");
    else
      fprintf(fout,"false");
  }
  
  if(ga->landscape != G_LANDSCAPE)
  {
    atleastone = output_separator(atleastone,fout);
    fprintf(fout,"landscape=");
    if(ga->landscape == yes)
      fprintf(fout,"true");
    else
      fprintf(fout,"false");
  }
  fprintf(fout,"];");
}

void
new_node_attributes(struct node_attributes *na)
{
  na->label 	= NA_LABEL;
  na->shape 	= NA_SHAPE;
  na->fillcolor = NA_FILLCOLOR;
  na->textcolor = NA_FONTCOLOR;
  na->bordercolor = NA_COLOR;
}

void
new_edge_attributes(struct edge_attributes *ea)
{
  ea->label	= EA_LABEL;
  ea->weight	= EA_WEIGHT;
  ea->color	= EA_COLOR;
  ea->textcolor	= EA_FONTCOLOR;
  ea->arrowstyle= EA_ARROWSTYLE;
}

void new_graph_attributes(struct graph_attributes *ga){
  ga->orientation = G_ORIENTATION;
  ga->splines	  = G_SPLINES;
  ga->center	  = G_CENTER;
  ga->landscape	  = G_LANDSCAPE;
}

bool
output_separator(bool atleastone, FILE *fout)
{
  if(atleastone)
  {
    fprintf(fout,", ");
  }
  return true;
}
/* Graphviz description handler for Bison. Some default values.

   Copyright (C) 2001, 2002, 2005, 2006 Free Software Foundation, Inc.

   This file is part of Bison, the GNU Compiler Compiler.

   Bison is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   Bison is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with Bison; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

#ifndef GRAPHVIZ_DEFAULTS_H_
# define GRAPHVIZ_DEFAULTS_H_

/* Graph defaults. */
# define G_TITLE		NULL
# define G_ORIENTATION		top_to_bottom
# define G_SPLINES		(-1)	/* Default undefined. */
# define G_CENTER		no
# define G_LANDSCAPE		no

/* Nodes defaults. */
# define N_TITLE		NULL	/* Mandatory. */
# define NA_LABEL		NULL
# define NA_SHAPE		ellipse
# define NA_COLOR		black
# define NA_FILLCOLOR		lightgrey
# define NA_FONTCOLOR		black

/* Edge defaults. */
# define E_SOURCENAME		NULL	/* Mandatory. */
# define E_TARGETNAME		NULL	/* Mandatory. */
# define EA_LABEL		NULL
# define EA_WEIGHT		1.0
# define EA_COLOR		black
# define EA_FONTCOLOR		black
# define EA_ARROWSTYLE		normal

#endif /* not Graphviz_DEFAULTS_H_ */
/* Definitions for Graphviz output of state machines genetated by Bison.
   Copyright (C) 2001, 2002, 2005, 2006 Free Software Foundation, Inc.

   This file is part of Bison, the GNU Compiler Compiler.

   Bison is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   Bison is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with Bison; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

#ifndef GRAPHVIZ_H_
# define GRAPHVIZ_H_

#include <stdio.h>
/** Graph orientations supported by GraphViz. */
enum graph_direction
{
  top_to_bottom,
  bottom_to_top,
  left_to_right,
  right_to_left
};

/** Some node shapes supported by GraphViz. */
enum shape
{
  box,
  ellipse,
  circle,
  doublecircle
};

/** Some basic colors from the X11 color scheme. */
enum color
{
 white,
 black,
 blue,
 red,
 green,
 lightgrey
};

/** Some arrow types supported by GraphViz. */
enum arrow_type
{
  normal,
  empty,
  vee
};

enum decision
{
  yes,
  no
};

struct node_attributes
{
  const char *label;
  enum shape shape;
  enum color fillcolor;
  enum color textcolor;
  enum color bordercolor; 
};

struct edge_attributes
{
  const char *label;
  double weight;
  enum color color;
  enum color textcolor;
  enum arrow_type arrowstyle;
};

struct graph_attributes
{
  enum graph_direction orientation;
  enum decision splines;
  enum decision center;
  enum decision landscape;  
};

struct edge
{
 
  const char *sourcename;
  const char *targetname;
  struct edge_attributes attrs;
};

struct node
{
  const char *title;
  struct node_attributes attrs;
};


struct graph
{
  const char *title;
  
  /** General properties of a graph. */
  struct graph_attributes graph_attributes;

  /** General node and edge attributes that apply to the entire graph. */
  struct node_attributes  node_attributes;
  struct edge_attributes  edge_attributes;
};

typedef struct graph 			graph;
typedef struct node  			node;
typedef struct edge  			edge;

void new_graph(graph *g);
void new_node(node *n);
void new_edge(edge *e);

void open_node(FILE *fout);
void output_node(node *n, FILE *fout);
void close_node(FILE *fout);

void open_edge(FILE *fout);
void output_edge(edge *e, FILE *fout);
void close_edge(FILE *fout);

/** Start a DOT graph description */
void open_graph(FILE *fout);

/** output a graph description */
void output_graph(graph *g, FILE *fout);

/** Close a graph description */
void close_graph(FILE *fout);

#endif
Index: Makefile.am
===================================================================
RCS file: /sources/bison/bison/src/Makefile.am,v
retrieving revision 1.71
diff -u -r1.71 Makefile.am
--- Makefile.am 15 Sep 2006 18:59:40 -0000      1.71
+++ Makefile.am 28 Sep 2006 20:27:46 -0000
@@ -65,8 +65,8 @@
        system.h                                  \
        tables.h tables.c                         \
        uniqstr.c uniqstr.h                       \
-       vcg.c vcg.h                               \
-       vcg_defaults.h
+       graphviz.c graphviz.h                             \
+       graphviz_defaults.h
 
 EXTRA_bison_SOURCES = scan-code.l scan-skel.l scan-gram.l
 
Index: files.c
===================================================================
RCS file: /sources/bison/bison/src/files.c,v
retrieving revision 1.96
diff -u -r1.96 files.c
--- files.c     9 Jul 2006 03:44:51 -0000       1.96
+++ files.c     28 Sep 2006 20:27:46 -0000
@@ -323,7 +323,7 @@
   if (graph_flag)
     {
       if (! spec_graph_file)
-       spec_graph_file = concat2 (all_but_tab_ext, ".vcg");
+       spec_graph_file = concat2 (all_but_tab_ext, ".dot");
       name[names++] = spec_graph_file;
     }
 
Index: print_graph.c
===================================================================
RCS file: /sources/bison/bison/src/print_graph.c,v
retrieving revision 1.61
diff -u -r1.61 print_graph.c
--- print_graph.c       10 Jun 2006 03:02:23 -0000      1.61
+++ print_graph.c       28 Sep 2006 20:27:46 -0000
@@ -36,7 +36,7 @@
 #include "reader.h"
 #include "state.h"
 #include "symtab.h"
-#include "vcg.h"
+#include "graphviz.h"
 
 static graph static_graph;
 static FILE *fgraph = NULL;
@@ -127,7 +127,7 @@
   transitions *trans = s->transitions;
   reductions *reds = s->reductions;
 
-  static char buff[10];
+  static char buff[16];
   edge e;
 
   if (!trans->num && !reds)
@@ -141,19 +141,17 @@
 
        new_edge (&e);
 
-       if (s->number > s1->number)
-         e.type = back_edge;
-       open_edge (&e, fgraph);
+       open_edge (fgraph);
        /* The edge source is the current node.  */
        e.sourcename = node_name;
-       sprintf (buff, "%d", s1->number);
+       sprintf (buff, "state_%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;
+         e.attrs.color = red;
        else
-         e.color = TRANSITION_IS_SHIFT (trans, i) ? blue : green;
-       e.label = symbols[sym]->tag;
+         e.attrs.color = TRANSITION_IS_SHIFT (trans, i) ? blue : green;
+       e.attrs.label = symbols[sym]->tag;
        output_edge (&e, fgraph);
        close_edge (fgraph);
       }
@@ -168,18 +166,21 @@
 static void
 print_state (state *s)
 {
-  static char name[10];
+  static char name[16];
   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);
+  sprintf (name, "state_%d", s->number);
   n.title = name;
+  if(s->number == final_state->number)
+    n.attrs.shape = doublecircle;
+
   print_core (&node_obstack, s);
   obstack_1grow (&node_obstack, '\0');
-  n.label = obstack_finish (&node_obstack);
+  n.attrs.label = obstack_finish (&node_obstack);
 
   open_node (fgraph);
   output_node (&n, fgraph);
@@ -201,15 +202,12 @@
   fgraph = xfopen (spec_graph_file, "w");
 
   new_graph (&static_graph);
+  static_graph.title = "Automaton";
+  static_graph.graph_attributes.orientation = left_to_right;
+  static_graph.graph_attributes.splines = yes;
+  static_graph.graph_attributes.center  = yes;
+  static_graph.graph_attributes.landscape = yes;
 
-  static_graph.display_edge_labels = yes;
-
-  static_graph.port_sharing = no;
-  static_graph.finetuning = yes;
-  static_graph.priority_phase = yes;
-  static_graph.splines = yes;
-
-  static_graph.crossing_weight = median;
 
   /* Output graph options. */
   open_graph (fgraph);
@@ -222,6 +220,6 @@
   free_closure ();
 
   /* Close graph. */
-  close_graph (&static_graph, fgraph);
+  close_graph (fgraph);
   xfclose (fgraph);
 }

Reply via email to