31 |
#include "obstack.h" |
#include "obstack.h" |
32 |
#include "print_graph.h" |
#include "print_graph.h" |
33 |
#include "vcg.h" |
#include "vcg.h" |
|
#include "quotearg.h" |
|
34 |
|
|
35 |
static graph_t graph; |
static graph_t graph; |
36 |
static FILE *fgraph = NULL; |
static FILE *fgraph = NULL; |
37 |
|
|
|
static size_t node_output_size = 0; |
|
|
|
|
|
/* Return an unambiguous printable representated, allocated in slot 0, |
|
|
for NAME, suitable for C strings. */ |
|
|
static char const * |
|
|
quote (char const *name) |
|
|
{ |
|
|
return quotearg_n_style (0, escape_quoting_style, name); |
|
|
} |
|
|
|
|
38 |
/* This part will construct the label of nodes. */ |
/* This part will construct the label of nodes. */ |
39 |
static void |
static void |
40 |
print_core (int state, struct obstack *node_obstack) |
print_core (int state, struct obstack *node_obstack) |
55 |
for (i = 0; i < k; i++) |
for (i = 0; i < k; i++) |
56 |
{ |
{ |
57 |
if (i) |
if (i) |
58 |
obstack_sgrow (node_obstack, "\\n"); |
obstack_1grow (node_obstack, '\n'); |
59 |
|
|
60 |
sp1 = sp = ritem + statep->items[i]; |
sp1 = sp = ritem + statep->items[i]; |
61 |
|
|
66 |
|
|
67 |
obstack_fgrow1 (node_obstack, "%d: ", rule); |
obstack_fgrow1 (node_obstack, "%d: ", rule); |
68 |
obstack_fgrow1 (node_obstack, " %s -> ", |
obstack_fgrow1 (node_obstack, " %s -> ", |
69 |
quote (tags[rule_table[rule].lhs])); |
tags[rule_table[rule].lhs]); |
70 |
|
|
71 |
for (sp = ritem + rule_table[rule].rhs; sp < sp1; sp++) |
for (sp = ritem + rule_table[rule].rhs; sp < sp1; sp++) |
72 |
obstack_fgrow1 (node_obstack, "%s ", quote (tags[*sp])); |
obstack_fgrow1 (node_obstack, "%s ", tags[*sp]); |
73 |
|
|
74 |
obstack_1grow (node_obstack, '.'); |
obstack_1grow (node_obstack, '.'); |
75 |
|
|
76 |
while (*sp > 0) |
while (*sp > 0) |
77 |
obstack_fgrow1 (node_obstack, " %s", quote (tags[*sp++])); |
obstack_fgrow1 (node_obstack, " %s", tags[*sp++]); |
78 |
} |
} |
79 |
} |
} |
80 |
|
|
81 |
/* Output in graph_obstack edges specifications in incidence with current |
|
82 |
node. */ |
/*---------------------------------------------------------------. |
83 |
|
| Output in graph_obstack edges specifications in incidence with | |
84 |
|
| current node. | |
85 |
|
`---------------------------------------------------------------*/ |
86 |
|
|
87 |
static void |
static void |
88 |
print_actions (int state, const char *node_name, struct obstack *node_obstack) |
print_actions (int state, const char *node_name) |
89 |
{ |
{ |
90 |
int i; |
int i; |
91 |
int k; |
int k; |
104 |
|
|
105 |
if (!shiftp && !redp) |
if (!shiftp && !redp) |
106 |
{ |
{ |
107 |
|
#if 0 |
108 |
if (final_state == state) |
if (final_state == state) |
109 |
obstack_sgrow (node_obstack, "$default: accept"); |
obstack_sgrow (node_obstack, "$default: accept"); |
110 |
else |
else |
111 |
obstack_sgrow (node_obstack, "NO ACTIONS"); |
obstack_sgrow (node_obstack, "NO ACTIONS"); |
112 |
|
#endif |
113 |
return; |
return; |
114 |
} |
} |
115 |
|
|
138 |
sprintf (buff, "%d", state1); |
sprintf (buff, "%d", state1); |
139 |
edge.targetname = buff; |
edge.targetname = buff; |
140 |
edge.color = (symbol == 0) ? red : blue; |
edge.color = (symbol == 0) ? red : blue; |
141 |
/* FIXME: Be aware that quote uses static memory. The string |
edge.label = tags[symbol]; |
|
must be output immediately (which is the case here). */ |
|
|
edge.label = tags[symbol] ? quote (tags[symbol]) : NULL; |
|
142 |
output_edge (&edge, fgraph); |
output_edge (&edge, fgraph); |
143 |
close_edge (fgraph); |
close_edge (fgraph); |
144 |
} |
} |
150 |
k = 0; |
k = 0; |
151 |
} |
} |
152 |
|
|
153 |
|
#if 0 |
154 |
if (errp) |
if (errp) |
155 |
{ |
{ |
156 |
int j, nerrs; |
int j, nerrs; |
163 |
continue; |
continue; |
164 |
symbol = errp->errs[j]; |
symbol = errp->errs[j]; |
165 |
/* If something has been added in the NODE_OBSTACK after |
/* If something has been added in the NODE_OBSTACK after |
166 |
the declaration of the label, then we need a `\n'. */ |
the declaration of the label, then we need a `\n'. |
167 |
if (obstack_object_size (node_obstack) > node_output_size) |
if (obstack_object_size (node_obstack) > node_output_size) |
168 |
obstack_sgrow (node_obstack, "\\n"); |
obstack_sgrow (node_obstack, "\n"); |
169 |
|
*/ |
170 |
obstack_fgrow1 (node_obstack, _("%-4s\terror (nonassociative)"), |
obstack_fgrow1 (node_obstack, _("%-4s\terror (nonassociative)"), |
171 |
tags[symbol]); |
tags[symbol]); |
172 |
} |
} |
173 |
if (j > 0) |
if (j > 0) |
174 |
obstack_sgrow (node_obstack, "\\n"); |
obstack_1grow (node_obstack, '\n'); |
175 |
} |
} |
176 |
|
|
177 |
if (state_table[state].consistent && redp) |
if (state_table[state].consistent && redp) |
178 |
{ |
{ |
179 |
rule = redp->rules[0]; |
rule = redp->rules[0]; |
180 |
symbol = rule_table[rule].lhs; |
symbol = rule_table[rule].lhs; |
181 |
|
/* |
182 |
if (obstack_object_size (node_obstack) > node_output_size) |
if (obstack_object_size (node_obstack) > node_output_size) |
183 |
obstack_sgrow (node_obstack, "\\n"); |
obstack_sgrow (node_obstack, "\n"); |
184 |
|
*/ |
185 |
obstack_fgrow2 (node_obstack, _("$default\treduce using rule %d (%s)"), |
obstack_fgrow2 (node_obstack, _("$default\treduce using rule %d (%s)"), |
186 |
rule, tags[symbol]); |
rule, tags[symbol]); |
187 |
} |
} |
188 |
|
#endif |
189 |
|
|
190 |
if (i < k) |
if (i < k) |
191 |
{ |
{ |
202 |
sprintf (buff, "%d", state1); |
sprintf (buff, "%d", state1); |
203 |
edge.targetname = buff; |
edge.targetname = buff; |
204 |
edge.color = red; |
edge.color = red; |
205 |
edge.label = tags[symbol] ? quote (tags[symbol]) : NULL; |
edge.label = tags[symbol]; |
206 |
output_edge (&edge, fgraph); |
output_edge (&edge, fgraph); |
207 |
close_edge (fgraph); |
close_edge (fgraph); |
208 |
} |
} |
209 |
} |
} |
210 |
} |
} |
211 |
|
|
212 |
/* Output in GRAPH_OBSTACK the current node specifications and edges |
|
213 |
which go out from that node. */ |
/*-------------------------------------------------------------. |
214 |
|
| Output in FGRAPH the current node specifications and exiting | |
215 |
|
| edges. | |
216 |
|
`-------------------------------------------------------------*/ |
217 |
|
|
218 |
static void |
static void |
219 |
print_state (int state) |
print_state (int state) |
220 |
{ |
{ |
222 |
struct obstack node_obstack; |
struct obstack node_obstack; |
223 |
node_t node; |
node_t node; |
224 |
|
|
225 |
|
/* The labels of the nodes are their the items. */ |
226 |
obstack_init (&node_obstack); |
obstack_init (&node_obstack); |
227 |
new_node (&node); /* Set node attributs default value. */ |
new_node (&node); |
228 |
sprintf (name, "%d", state); |
sprintf (name, "%d", state); |
229 |
node.title = name; /* Give a name to the node. */ |
node.title = name; |
230 |
|
print_core (state, &node_obstack); |
231 |
{ |
obstack_1grow (&node_obstack, '\0'); |
232 |
/* Here we begin to compute the node label. */ |
node.label = obstack_finish (&node_obstack); |
|
obstack_sgrow (&node_obstack, "\t\tlabel:\t\""); /* Open Label */ |
|
|
|
|
|
/* Keep the size of NODE_OBSTACK before computing the label. It is |
|
|
useful to format the label. */ |
|
|
node_output_size = obstack_object_size (&node_obstack); |
|
|
|
|
|
/* Compute the labels of nodes on the fly. */ |
|
|
print_core (state, &node_obstack); |
|
|
/* Compute edges and additionnal parts of node label. */ |
|
|
print_actions (state, node.title, &node_obstack); |
|
|
|
|
|
obstack_sgrow (&node_obstack, "\"\n"); /* Close Label. */ |
|
|
} |
|
233 |
|
|
234 |
open_node (fgraph); |
open_node (fgraph); |
|
/* Output a VCG formatted attributs list. */ |
|
235 |
output_node (&node, fgraph); |
output_node (&node, fgraph); |
|
/* Save the node label. */ |
|
|
fwrite (obstack_base (&node_obstack), |
|
|
obstack_object_size (&node_obstack), 1, fgraph); |
|
236 |
close_node (fgraph); |
close_node (fgraph); |
237 |
|
|
238 |
|
/* Output the edges. */ |
239 |
|
print_actions (state, name); |
240 |
|
|
241 |
obstack_free (&node_obstack, 0); |
obstack_free (&node_obstack, 0); |
242 |
} |
} |
243 |
|
|
275 |
open_graph (fgraph); |
open_graph (fgraph); |
276 |
output_graph (&graph, fgraph); |
output_graph (&graph, fgraph); |
277 |
|
|
278 |
|
/* Output nodes and edges. */ |
279 |
for (i = 0; i < nstates; i++) |
for (i = 0; i < nstates; i++) |
|
/* Output nodes & edges. */ |
|
280 |
print_state (i); |
print_state (i); |
281 |
|
|
282 |
/* Close graph. */ |
/* Close graph. */ |