]>
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
].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
= state_table
[state
].shift_table
;
108 redp
= state_table
[state
].reduction_table
;
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
= state_table
[state1
].accessing_symbol
;
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 (state_table
[state
].consistent
&& 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
= state_table
[state1
].accessing_symbol
;
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
);