]>
git.saurik.com Git - bison.git/blob - src/print_graph.c
   1 /* Output a VCG description on generated parser, for Bison, 
   2    Copyright 2001 Free Software Foundation, Inc. 
   4    This file is part of Bison, the GNU Compiler Compiler. 
   6    Bison is free software; you can redistribute it and/or modify 
   7    it under the terms of the GNU General Public License as published by 
   8    the Free Software Foundation; either version 2, or (at your option) 
  11    Bison is distributed in the hope that it will be useful, 
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of 
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  14    GNU General Public License for more details. 
  16    You should have received a copy of the GNU General Public License 
  17    along with Bison; see the file COPYING.  If not, write to 
  18    the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
  19    Boston, MA 02111-1307, USA.  */ 
  26 #include "conflicts.h" 
  32 #include "print_graph.h" 
  37 static FILE *fgraph 
= NULL
; 
  39 static size_t node_output_size 
= 0; 
  41 /* Return an unambiguous printable representated, allocated in slot 0, 
  42    for NAME, suitable for C strings.  */ 
  44 quote (char const *name
) 
  46   return quotearg_n_style (0, escape_quoting_style
, name
); 
  49 /* This part will construct the label of nodes. */ 
  51 print_core (int state
, struct obstack 
*node_obstack
) 
  60   statep 
= state_table
[state
]; 
  66   for (i 
= 0; i 
< k
; i
++) 
  69         obstack_sgrow (node_obstack
, "\\n"); 
  71       sp1 
= sp 
= ritem 
+ statep
->items
[i
]; 
  78       obstack_fgrow1 (node_obstack
, "%d: ", rule
); 
  79       obstack_fgrow1 (node_obstack
, " %s  ->  ", quote (tags
[rlhs
[rule
]])); 
  81       for (sp 
= ritem 
+ rrhs
[rule
]; sp 
< sp1
; sp
++) 
  82         obstack_fgrow1 (node_obstack
, "%s ", quote (tags
[*sp
])); 
  84       obstack_1grow (node_obstack
, '.'); 
  87         obstack_fgrow1 (node_obstack
, " %s", quote (tags
[*sp
++])); 
  91 /* Output in graph_obstack edges specifications in incidence with current  
  94 print_actions (int state
, const char *node_name
, struct obstack 
*node_obstack
) 
 104   static char buff
[10]; 
 107   shiftp 
= shift_table
[state
]; 
 108   redp 
= reduction_table
[state
]; 
 109   errp 
= err_table
[state
]; 
 111   if (!shiftp 
&& !redp
) 
 113       if (final_state 
== state
) 
 114         obstack_sgrow (node_obstack
, "$default: accept"); 
 116         obstack_sgrow (node_obstack
, "NO ACTIONS"); 
 124       for (i 
= 0; i 
< k
; i
++) 
 126           if (!shiftp
->shifts
[i
]) 
 128           state1 
= shiftp
->shifts
[i
]; 
 129           symbol 
= accessing_symbol
[state1
]; 
 138               edge
.type 
= back_edge
; 
 139             open_edge (&edge
, fgraph
); 
 140             /* The edge source is the current node.  */ 
 141             edge
.sourcename 
= node_name
; 
 142             sprintf (buff
, "%d", state1
); 
 143             edge
.targetname 
= buff
; 
 144             edge
.color 
= (symbol 
== 0) ? red 
: blue
; 
 145             /* FIXME: Be aware that quote uses static memory.  The string 
 146                must be output immediately (which is the case here). */ 
 147             edge
.label 
= tags
[symbol
] ? quote (tags
[symbol
]) : NULL
; 
 148             output_edge (&edge
, fgraph
); 
 165       for (j 
= 0; j 
< nerrs
; j
++) 
 169           symbol 
= errp
->errs
[j
]; 
 170           /* If something has been added in the NODE_OBSTACK after 
 171              the declaration of the label, then we need a `\n'.  */ 
 172           if (obstack_object_size (node_obstack
) > node_output_size
) 
 173             obstack_sgrow (node_obstack
, "\\n"); 
 174           obstack_fgrow1 (node_obstack
, _("%-4s\terror (nonassociative)"), 
 178         obstack_sgrow (node_obstack
, "\\n"); 
 181   if (consistent
[state
] && redp
) 
 183       rule 
= redp
->rules
[0]; 
 185       if (obstack_object_size (node_obstack
) > node_output_size
) 
 186         obstack_sgrow (node_obstack
, "\\n"); 
 187       obstack_fgrow2 (node_obstack
, _("$default\treduce using rule %d (%s)"), 
 195           if (!shiftp
->shifts
[i
]) 
 197           state1 
= shiftp
->shifts
[i
]; 
 198           symbol 
= accessing_symbol
[state1
]; 
 201           open_edge (&edge
, fgraph
); 
 202           edge
.sourcename 
= node_name
; 
 203           sprintf (buff
, "%d", state1
); 
 204           edge
.targetname 
= buff
; 
 206           edge
.label 
= tags
[symbol
] ? quote (tags
[symbol
]) : NULL
; 
 207           output_edge (&edge
, fgraph
); 
 213 /* Output in GRAPH_OBSTACK the current node specifications and edges  
 214    which go out from that node.  */ 
 216 print_state (int state
) 
 218   static char name
[10]; 
 219   struct obstack node_obstack
; 
 222   obstack_init (&node_obstack
); 
 223   new_node (&node
);     /* Set node attributs default value.  */ 
 224   sprintf (name
, "%d", state
); 
 225   node
.title 
= name
;    /* Give a name to the node.  */ 
 228     /* Here we begin to compute the node label. */   
 229     obstack_sgrow (&node_obstack
, "\t\tlabel:\t\"");    /* Open Label  */ 
 231     /* Keep the size of NODE_OBSTACK before computing the label. It is  
 232        useful to format the label.  */ 
 233     node_output_size 
= obstack_object_size (&node_obstack
); 
 235     /* Compute the labels of nodes on the fly.  */ 
 236     print_core (state
, &node_obstack
); 
 237     /* Compute edges and additionnal parts of node label.  */ 
 238     print_actions (state
, node
.title
, &node_obstack
); 
 240     obstack_sgrow (&node_obstack
, "\"\n");              /* Close Label.  */ 
 244   /* Output a VCG formatted attributs list.  */ 
 245   output_node (&node
, fgraph
); 
 246   /* Save the node label.  */ 
 247   fwrite (obstack_base (&node_obstack
),  
 248           obstack_object_size (&node_obstack
), 1, fgraph
); 
 251   obstack_free (&node_obstack
, 0); 
 264   fgraph 
= xfopen (spec_graph_file
, "w"); 
 269   graph
.smanhattan_edges 
= yes
; 
 270   graph
.manhattan_edges 
= yes
;  
 273   graph
.display_edge_labels 
= yes
; 
 274   graph
.layoutalgorithm 
= normal
; 
 276   graph
.port_sharing 
= no
; 
 277   graph
.finetuning 
= yes
; 
 278   graph
.straight_phase 
= yes
; 
 279   graph
.priority_phase 
= yes
; 
 282   graph
.crossing_weight 
= median
; 
 284   /* Output graph options. */ 
 286   output_graph (&graph
, fgraph
); 
 288   for (i 
= 0; i 
< nstates
; i
++) 
 289     /* Output nodes & edges. */ 
 293   close_graph (&graph
, fgraph
);