]> git.saurik.com Git - bison.git/blob - src/print_graph.c
* src/state.h, src/state.c (reductions_new): New.
[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 "files.h"
23 #include "gram.h"
24 #include "LR0.h"
25 #include "lalr.h"
26 #include "conflicts.h"
27 #include "complain.h"
28 #include "getargs.h"
29 #include "state.h"
30 #include "reader.h"
31 #include "closure.h"
32 #include "obstack.h"
33 #include "print_graph.h"
34 #include "vcg.h"
35
36 static graph_t graph;
37 static FILE *fgraph = NULL;
38
39 /* This part will construct the label of nodes. */
40 static void
41 print_core (state_t *state, struct obstack *node_obstack)
42 {
43 int i;
44 short *sitems = state->items;
45 int snitems = state->nitems;
46
47 /* Output all the items of a state, not only its kernel. */
48 closure (sitems, snitems);
49 sitems = itemset;
50 snitems = nitemset;
51
52 obstack_fgrow1 (node_obstack, "%2d: ", state->number);
53 for (i = 0; i < snitems; i++)
54 {
55 short *sp;
56 short *sp1;
57 int rule;
58
59 sp1 = sp = ritem + sitems[i];
60
61 while (*sp > 0)
62 sp++;
63
64 rule = -(*sp);
65
66 if (i)
67 obstack_sgrow (node_obstack, "\n ");
68 obstack_fgrow1 (node_obstack, " %s -> ",
69 tags[rule_table[rule].lhs]);
70
71 for (sp = ritem + rule_table[rule].rhs; sp < sp1; sp++)
72 obstack_fgrow1 (node_obstack, "%s ", tags[*sp]);
73
74 obstack_1grow (node_obstack, '.');
75
76 for (/* Nothing */; *sp > 0; ++sp)
77 obstack_fgrow1 (node_obstack, " %s", tags[*sp]);
78 }
79 }
80
81
82 /*---------------------------------------------------------------.
83 | Output in graph_obstack edges specifications in incidence with |
84 | current node. |
85 `---------------------------------------------------------------*/
86
87 static void
88 print_actions (state_t *state, const char *node_name)
89 {
90 int i;
91
92 shifts *shiftp = state->shifts;
93 reductions *redp = state->reductions;
94
95 static char buff[10];
96 edge_t edge;
97
98 if (!shiftp->nshifts && !redp)
99 return;
100
101 for (i = 0; i < shiftp->nshifts; i++)
102 if (!SHIFT_IS_DISABLED (shiftp, i))
103 {
104 int state1 = shiftp->shifts[i];
105 int symbol = state_table[state1]->accessing_symbol;
106
107 new_edge (&edge);
108
109 if (state->number > state1)
110 edge.type = back_edge;
111 open_edge (&edge, fgraph);
112 /* The edge source is the current node. */
113 edge.sourcename = node_name;
114 sprintf (buff, "%d", state1);
115 edge.targetname = buff;
116 /* Shifts are blue, gotos are red. */
117 edge.color = SHIFT_IS_SHIFT(shiftp, i) ? blue : red;
118 edge.label = tags[symbol];
119 output_edge (&edge, fgraph);
120 close_edge (fgraph);
121 }
122 }
123
124
125 /*-------------------------------------------------------------.
126 | Output in FGRAPH the current node specifications and exiting |
127 | edges. |
128 `-------------------------------------------------------------*/
129
130 static void
131 print_state (state_t *state)
132 {
133 static char name[10];
134 struct obstack node_obstack;
135 node_t node;
136
137 /* The labels of the nodes are their the items. */
138 obstack_init (&node_obstack);
139 new_node (&node);
140 sprintf (name, "%d", state->number);
141 node.title = name;
142 print_core (state, &node_obstack);
143 obstack_1grow (&node_obstack, '\0');
144 node.label = obstack_finish (&node_obstack);
145
146 open_node (fgraph);
147 output_node (&node, fgraph);
148 close_node (fgraph);
149
150 /* Output the edges. */
151 print_actions (state, name);
152
153 obstack_free (&node_obstack, 0);
154 }
155 \f
156
157 void
158 print_graph (void)
159 {
160 int i;
161
162 /* Output file. */
163 fgraph = xfopen (spec_graph_file, "w");
164
165 new_graph (&graph);
166
167 #if 0
168 graph.smanhattan_edges = yes;
169 graph.manhattan_edges = yes;
170 #endif
171
172 graph.display_edge_labels = yes;
173 graph.layoutalgorithm = normal;
174
175 graph.port_sharing = no;
176 graph.finetuning = yes;
177 graph.straight_phase = yes;
178 graph.priority_phase = yes;
179 graph.splines = yes;
180
181 graph.crossing_weight = median;
182
183 /* Output graph options. */
184 open_graph (fgraph);
185 output_graph (&graph, fgraph);
186
187 /* Output nodes and edges. */
188 new_closure (nitems);
189 for (i = 0; i < nstates; i++)
190 print_state (state_table[i]);
191 free_closure ();
192
193 /* Close graph. */
194 close_graph (&graph, fgraph);
195 xfclose (fgraph);
196 }