]> git.saurik.com Git - bison.git/blame_incremental - src/print_graph.c
* tests/local.at (AT_COMPILE_CXX): Treat LDFLAGS like AT_COMPILE does.
[bison.git] / src / print_graph.c
... / ...
CommitLineData
1/* Output a VCG description on generated parser, for Bison,
2
3 Copyright (C) 2001, 2002, 2003, 2004 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., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22#include "system.h"
23
24#include <obstack.h>
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
41static graph static_graph;
42static FILE *fgraph = NULL;
43
44
45/*----------------------------.
46| Construct the node labels. |
47`----------------------------*/
48
49static void
50print_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
122static void
123print_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
168static void
169print_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\f
194
195void
196print_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}