]> git.saurik.com Git - bison.git/blob - src/print_graph.c
d3b9b8ce5875b79ab15678c443738ccf7ec45dc0
[bison.git] / src / print_graph.c
1 /* Output a VCG description on generated parser, for Bison,
2 Copyright 2001 Free Software Foundation, Inc.
3
4 This file is part of Bison, the GNU Compiler Compiler.
5
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)
9 any later version.
10
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.
15
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. */
20
21 #include "system.h"
22 #include "xalloc.h"
23 #include "files.h"
24 #include "gram.h"
25 #include "LR0.h"
26 #include "lalr.h"
27 #include "conflicts.h"
28 #include "complain.h"
29 #include "getargs.h"
30 #include "state.h"
31 #include "reader.h"
32 #include "obstack.h"
33 #include "print_graph.h"
34 #include "vcg.h"
35 #include "quote.h"
36
37 static graph_t graph;
38
39 /* This part will construct the label of nodes. */
40 static void
41 print_core (int state)
42 {
43 int i;
44 int k;
45 int rule;
46 core *statep;
47 short *sp;
48 short *sp1;
49
50 statep = state_table[state];
51 k = statep->nitems;
52
53 if (k == 0)
54 return;
55
56 obstack_sgrow (&graph_obstack, "\t\tlabel:\t\"");
57
58 for (i = 0; i < k; i++)
59 {
60 if (i)
61 obstack_sgrow (&graph_obstack, "\\n");
62
63 sp1 = sp = ritem + statep->items[i];
64
65 while (*sp > 0)
66 sp++;
67
68 rule = -(*sp);
69
70 obstack_fgrow1 (&graph_obstack, _("%d: "), rule);
71 obstack_fgrow1 (&graph_obstack, " %s -> ", quote (tags[rlhs[rule]]));
72
73 for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
74 obstack_fgrow1 (&graph_obstack, "%s ", quote (tags[*sp]));
75
76 obstack_1grow (&graph_obstack, '.');
77
78 while (*sp > 0)
79 obstack_fgrow1 (&graph_obstack, " %s", quote (tags[*sp++]));
80
81 }
82 obstack_sgrow (&graph_obstack, "\"\n");
83 }
84
85 static void
86 print_actions (int state, node_t *node)
87 {
88 int i;
89 int k;
90 int state1;
91 int symbol;
92 shifts *shiftp;
93 errs *errp;
94 reductions *redp;
95 int rule;
96 static char buff[10];
97 edge_t edge;
98
99 shiftp = shift_table[state];
100 redp = reduction_table[state];
101 errp = err_table[state];
102
103 if (!shiftp && !redp)
104 {
105 #if 0
106 if (final_state == state)
107 fprintf (f, " $default\taccept\n");
108 else
109 fprintf (f, " NO ACTIONS\n");
110 #endif
111 return;
112 }
113
114 if (shiftp)
115 {
116 k = shiftp->nshifts;
117
118 for (i = 0; i < k; i++)
119 {
120 if (!shiftp->shifts[i])
121 continue;
122 state1 = shiftp->shifts[i];
123 symbol = accessing_symbol[state1];
124
125 if (ISVAR (symbol))
126 break;
127
128 {
129 new_edge (&edge);
130
131 if (state > state1)
132 edge.type = back_edge;
133 open_edge (&edge, &graph_obstack);
134 edge.sourcename = node->title;
135 sprintf (buff, "%d", state1);
136 edge.targetname = buff;
137 edge.color = (symbol == 0) ? blue : red;
138 /* FIXME: Be aware that quote uses static memory. The string
139 must be output immediately (which is the case here). */
140 edge.label = tags[symbol] ? quote (tags[symbol]) : NULL;
141 output_edge (&edge, &graph_obstack);
142 close_edge (&graph_obstack);
143 }
144 }
145 }
146 else
147 {
148 i = 0;
149 k = 0;
150 }
151
152 if (errp)
153 {
154 int j, nerrs;
155
156 nerrs = errp->nerrs;
157
158 for (j = 0; j < nerrs; j++)
159 {
160 if (!errp->errs[j])
161 continue;
162 symbol = errp->errs[j];
163 }
164 }
165
166 if (consistent[state] && redp)
167 {
168 rule = redp->rules[0];
169 symbol = rlhs[rule];
170 }
171
172 if (i < k)
173 {
174 for (; i < k; i++)
175 {
176 if (!shiftp->shifts[i])
177 continue;
178 state1 = shiftp->shifts[i];
179 symbol = accessing_symbol[state1];
180
181 new_edge (&edge);
182 open_edge (&edge, &graph_obstack);
183 edge.sourcename = node->title;
184 sprintf (buff, "%d", state1);
185 edge.targetname = buff;
186 edge.color = red;
187 edge.label = tags[symbol] ? quote (tags[symbol]) : NULL;
188 output_edge (&edge, &graph_obstack);
189 close_edge (&graph_obstack);
190 }
191 }
192 }
193
194 static void
195 print_state (int state)
196 {
197 static char name[10];
198 node_t node;
199
200 new_node (&node);
201 open_node (&graph_obstack);
202
203 sprintf (name, "%d", state);
204 node.title = name;
205 output_node (&node, &graph_obstack);
206
207 print_core (state); /* node label */
208
209 close_node (&graph_obstack);
210
211 print_actions (state, &node); /* edges */
212 }
213 \f
214
215 void
216 print_graph (void)
217 {
218 int i;
219
220 if (!graph_flag)
221 return;
222 new_graph (&graph);
223
224 /* graph.smanhattan_edges = yes;
225 graph.manhattan_edges = yes; */
226
227 graph.display_edge_labels = yes;
228 graph.layoutalgorithm = 0;
229
230 graph.port_sharing = no;
231 graph.finetuning = yes;
232 graph.straight_phase = yes;
233 graph.priority_phase = yes;
234 graph.splines = yes;
235
236 graph.crossing_weight = median;
237
238 /* Output graph options. */
239 open_graph (&graph_obstack);
240 output_graph (&graph, &graph_obstack);
241
242 for (i = 0; i < nstates; i++)
243 /* Output nodes & edges. */
244 print_state (i);
245
246 /* Close graph. */
247 close_graph (&graph, &graph_obstack);
248 }