• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Output a VCG description on generated parser, for Bison,
2 
3    Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 
5    This file is part of Bison, the GNU Compiler Compiler.
6 
7    Bison is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
11 
12    Bison is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with Bison; see the file COPYING.  If not, write to
19    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20    Boston, MA 02110-1301, USA.  */
21 
22 #include <config.h>
23 #include "system.h"
24 
25 #include <quotearg.h>
26 
27 #include "LR0.h"
28 #include "closure.h"
29 #include "complain.h"
30 #include "conflicts.h"
31 #include "files.h"
32 #include "getargs.h"
33 #include "gram.h"
34 #include "lalr.h"
35 #include "print_graph.h"
36 #include "reader.h"
37 #include "state.h"
38 #include "symtab.h"
39 #include "vcg.h"
40 
41 static graph static_graph;
42 static FILE *fgraph = NULL;
43 
44 
45 /*----------------------------.
46 | Construct the node labels.  |
47 `----------------------------*/
48 
49 static void
print_core(struct obstack * oout,state * s)50 print_core (struct obstack *oout, state *s)
51 {
52   size_t i;
53   item_number *sitems = s->items;
54   size_t snritems = s->nitems;
55 
56   /* Output all the items of a state, not only its kernel.  */
57   if (report_flag & report_itemsets)
58     {
59       closure (sitems, snritems);
60       sitems = itemset;
61       snritems = nritemset;
62     }
63 
64   obstack_fgrow1 (oout, "state %2d\n", s->number);
65   for (i = 0; i < snritems; i++)
66     {
67       item_number *sp;
68       item_number *sp1;
69       rule_number r;
70 
71       sp1 = sp = ritem + sitems[i];
72 
73       while (*sp >= 0)
74 	sp++;
75 
76       r = item_number_as_rule_number (*sp);
77 
78       if (i)
79 	obstack_1grow (oout, '\n');
80       obstack_fgrow1 (oout, " %s -> ",
81 		      rules[r].lhs->tag);
82 
83       for (sp = rules[r].rhs; sp < sp1; sp++)
84 	obstack_fgrow1 (oout, "%s ", symbols[*sp]->tag);
85 
86       obstack_1grow (oout, '.');
87 
88       for (/* Nothing */; *sp >= 0; ++sp)
89 	obstack_fgrow1 (oout, " %s", symbols[*sp]->tag);
90 
91       /* Experimental feature: display the look-ahead tokens. */
92       if (report_flag & report_look_ahead_tokens)
93 	{
94 	  /* Find the reduction we are handling.  */
95 	  reductions *reds = s->reductions;
96 	  int redno = state_reduction_find (s, &rules[r]);
97 
98 	  /* Print them if there are.  */
99 	  if (reds->look_ahead_tokens && redno != -1)
100 	    {
101 	      bitset_iterator biter;
102 	      int k;
103 	      char const *sep = "";
104 	      obstack_sgrow (oout, "[");
105 	      BITSET_FOR_EACH (biter, reds->look_ahead_tokens[redno], k, 0)
106 		{
107 		  obstack_fgrow2 (oout, "%s%s", sep, symbols[k]->tag);
108 		  sep = ", ";
109 		}
110 	      obstack_sgrow (oout, "]");
111 	    }
112 	}
113     }
114 }
115 
116 
117 /*---------------------------------------------------------------.
118 | Output in graph_obstack edges specifications in incidence with |
119 | current node.                                                  |
120 `---------------------------------------------------------------*/
121 
122 static void
print_actions(state * s,const char * node_name)123 print_actions (state *s, const char *node_name)
124 {
125   int i;
126 
127   transitions *trans = s->transitions;
128   reductions *reds = s->reductions;
129 
130   static char buff[10];
131   edge e;
132 
133   if (!trans->num && !reds)
134     return;
135 
136   for (i = 0; i < trans->num; i++)
137     if (!TRANSITION_IS_DISABLED (trans, i))
138       {
139 	state *s1 = trans->states[i];
140 	symbol_number sym = s1->accessing_symbol;
141 
142 	new_edge (&e);
143 
144 	if (s->number > s1->number)
145 	  e.type = back_edge;
146 	open_edge (&e, fgraph);
147 	/* The edge source is the current node.  */
148 	e.sourcename = node_name;
149 	sprintf (buff, "%d", s1->number);
150 	e.targetname = buff;
151 	/* Shifts are blue, gotos are green, and error is red. */
152 	if (TRANSITION_IS_ERROR (trans, i))
153 	  e.color = red;
154 	else
155 	  e.color = TRANSITION_IS_SHIFT (trans, i) ? blue : green;
156 	e.label = symbols[sym]->tag;
157 	output_edge (&e, fgraph);
158 	close_edge (fgraph);
159       }
160 }
161 
162 
163 /*-------------------------------------------------------------.
164 | Output in FGRAPH the current node specifications and exiting |
165 | edges.                                                       |
166 `-------------------------------------------------------------*/
167 
168 static void
print_state(state * s)169 print_state (state *s)
170 {
171   static char name[10];
172   struct obstack node_obstack;
173   node n;
174 
175   /* The labels of the nodes are their the items.  */
176   obstack_init (&node_obstack);
177   new_node (&n);
178   sprintf (name, "%d", s->number);
179   n.title = name;
180   print_core (&node_obstack, s);
181   obstack_1grow (&node_obstack, '\0');
182   n.label = obstack_finish (&node_obstack);
183 
184   open_node (fgraph);
185   output_node (&n, fgraph);
186   close_node (fgraph);
187 
188   /* Output the edges.  */
189   print_actions (s, name);
190 
191   obstack_free (&node_obstack, 0);
192 }
193 
194 
195 void
print_graph(void)196 print_graph (void)
197 {
198   state_number i;
199 
200   /* Output file.  */
201   fgraph = xfopen (spec_graph_file, "w");
202 
203   new_graph (&static_graph);
204 
205   static_graph.display_edge_labels = yes;
206 
207   static_graph.port_sharing = no;
208   static_graph.finetuning = yes;
209   static_graph.priority_phase = yes;
210   static_graph.splines = yes;
211 
212   static_graph.crossing_weight = median;
213 
214   /* Output graph options. */
215   open_graph (fgraph);
216   output_graph (&static_graph, fgraph);
217 
218   /* Output nodes and edges. */
219   new_closure (nritems);
220   for (i = 0; i < nstates; i++)
221     print_state (states[i]);
222   free_closure ();
223 
224   /* Close graph. */
225   close_graph (&static_graph, fgraph);
226   xfclose (fgraph);
227 }
228