]> git.saurik.com Git - bison.git/blame - src/print_graph.c
xml: match DOT output and xml2dot.xsl processing
[bison.git] / src / print_graph.c
CommitLineData
35fe0834 1/* Output a graph of the generated parser, for Bison.
16bb742f 2
c932d613 3 Copyright (C) 2001-2007, 2009-2012 Free Software Foundation, Inc.
ce4d5ce0
AD
4
5 This file is part of Bison, the GNU Compiler Compiler.
6
f16b0819 7 This program is free software: you can redistribute it and/or modify
ce4d5ce0 8 it under the terms of the GNU General Public License as published by
f16b0819
PE
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
ce4d5ce0 11
f16b0819 12 This program is distributed in the hope that it will be useful,
ce4d5ce0
AD
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
f16b0819 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
ce4d5ce0 19
2cec9080 20#include <config.h>
ce4d5ce0 21#include "system.h"
16bb742f 22
ce4d5ce0 23#include "LR0.h"
16bb742f 24#include "closure.h"
ce4d5ce0 25#include "complain.h"
16bb742f
PE
26#include "conflicts.h"
27#include "files.h"
ce4d5ce0 28#include "getargs.h"
16bb742f 29#include "gram.h"
35fe0834 30#include "graphviz.h"
16bb742f 31#include "lalr.h"
ce4d5ce0 32#include "print_graph.h"
16bb742f
PE
33#include "reader.h"
34#include "state.h"
35#include "symtab.h"
ce4d5ce0 36
8adfa272 37
6b98e4b5
AD
38/*----------------------------.
39| Construct the node labels. |
40`----------------------------*/
8adfa272 41
ce6cf10f
TR
42/* Print the lhs of a rule in such a manner that there is no vertical
43 repetition, like in *.output files. */
44
45static void
46print_lhs (struct obstack *oout, rule *previous_rule, rule *r)
47{
48 if (previous_rule && STREQ (previous_rule->lhs->tag, r->lhs->tag))
49 {
50 int i;
51 for (i = 0; i < strlen (r->lhs->tag); ++i)
52 obstack_1grow (oout, ' ');
53 obstack_1grow (oout, '|');
54 }
55 else
56 {
57 obstack_sgrow (oout, escape (r->lhs->tag));
58 obstack_1grow (oout, ':');
59 }
60}
61
ce4d5ce0 62static void
16bb742f 63print_core (struct obstack *oout, state *s)
ce4d5ce0 64{
16bb742f 65 item_number *sitems = s->items;
ce6cf10f
TR
66 rule *previous_rule = NULL;
67 size_t i;
f6fbd3da 68 size_t snritems = s->nitems;
22c2cbc0 69
2e729273 70 /* Output all the items of a state, not only its kernel. */
05811fd7 71 if (report_flag & report_itemsets)
30171f79 72 {
5123689b 73 closure (sitems, snritems);
30171f79 74 sitems = itemset;
b09f4f48 75 snritems = nitemset;
30171f79 76 }
22c2cbc0 77
8048226f 78 obstack_printf (oout, _("State %d"), s->number);
be3517b0 79 obstack_sgrow (oout, "\\n\\l");
5123689b 80 for (i = 0; i < snritems; i++)
ce4d5ce0 81 {
16bb742f
PE
82 item_number *sp;
83 item_number *sp1;
84 rule_number r;
c4b66126 85
2e729273 86 sp1 = sp = ritem + sitems[i];
ce4d5ce0 87
75142d45 88 while (*sp >= 0)
a13121f7 89 sp++;
ce4d5ce0 90
16bb742f 91 r = item_number_as_rule_number (*sp);
ce4d5ce0 92
ce6cf10f
TR
93 obstack_printf (oout, "%3d ", r);
94 print_lhs (oout, previous_rule, &rules[r]);
95 previous_rule = &rules[r];
ce4d5ce0 96
16bb742f 97 for (sp = rules[r].rhs; sp < sp1; sp++)
8048226f 98 obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
ce4d5ce0 99
8048226f 100 obstack_sgrow (oout, " .");
22c2cbc0 101
75142d45 102 for (/* Nothing */; *sp >= 0; ++sp)
a13121f7 103 obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
d4e7d3a1 104
742e4900 105 /* Experimental feature: display the lookahead tokens. */
255a6b90
JD
106 if (report_flag & report_lookahead_tokens
107 && item_number_is_rule_number (*sp1))
a13121f7
TR
108 {
109 /* Find the reduction we are handling. */
110 reductions *reds = s->reductions;
111 int redno = state_reduction_find (s, &rules[r]);
112
113 /* Print them if there are. */
114 if (reds->lookahead_tokens && redno != -1)
115 {
116 bitset_iterator biter;
117 int k;
118 char const *sep = "";
8048226f 119 obstack_sgrow (oout, " [");
a13121f7
TR
120 BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0)
121 {
122 obstack_sgrow (oout, sep);
123 obstack_sgrow (oout, escape (symbols[k]->tag));
124 sep = ", ";
125 }
126 obstack_1grow (oout, ']');
127 }
128 }
129 obstack_sgrow (oout, "\\l");
ce4d5ce0 130 }
ce4d5ce0
AD
131}
132
08a946e0
AD
133
134/*---------------------------------------------------------------.
135| Output in graph_obstack edges specifications in incidence with |
136| current node. |
137`---------------------------------------------------------------*/
138
ce4d5ce0 139static void
35fe0834 140print_actions (state const *s, FILE *fgraph)
ce4d5ce0 141{
35fe0834 142 transitions const *trans = s->transitions;
8048226f 143 int i;
22c2cbc0 144
35fe0834 145 if (!trans->num && !s->reductions)
5092aba5 146 return;
ce4d5ce0 147
16bb742f
PE
148 for (i = 0; i < trans->num; i++)
149 if (!TRANSITION_IS_DISABLED (trans, i))
d954473d 150 {
16bb742f
PE
151 state *s1 = trans->states[i];
152 symbol_number sym = s1->accessing_symbol;
d954473d 153
35fe0834
PE
154 /* Shifts are solid, gotos are dashed, and error is dotted. */
155 char const *style =
156 (TRANSITION_IS_ERROR (trans, i) ? "dotted"
157 : TRANSITION_IS_SHIFT (trans, i) ? "solid"
158 : "dashed");
159
160 if (TRANSITION_IS_ERROR (trans, i)
161 && strcmp (symbols[sym]->tag, "error") != 0)
162 abort ();
163 output_edge (s->number, s1->number,
164 TRANSITION_IS_ERROR (trans, i) ? NULL : symbols[sym]->tag,
165 style, fgraph);
d954473d 166 }
be3517b0
TR
167 /* Display reductions. */
168 output_red (s, s->reductions, fgraph);
ce4d5ce0
AD
169}
170
08a946e0
AD
171
172/*-------------------------------------------------------------.
173| Output in FGRAPH the current node specifications and exiting |
174| edges. |
175`-------------------------------------------------------------*/
176
ce4d5ce0 177static void
35fe0834 178print_state (state *s, FILE *fgraph)
ce4d5ce0 179{
600cad3b 180 struct obstack node_obstack;
ce4d5ce0 181
35fe0834 182 /* A node's label contains its items. */
600cad3b 183 obstack_init (&node_obstack);
16bb742f 184 print_core (&node_obstack, s);
08a946e0 185 obstack_1grow (&node_obstack, '\0');
35fe0834
PE
186 output_node (s->number, obstack_finish (&node_obstack), fgraph);
187 obstack_free (&node_obstack, 0);
342b8b6e 188
08a946e0 189 /* Output the edges. */
35fe0834 190 print_actions (s, fgraph);
ce4d5ce0
AD
191}
192\f
193
194void
195print_graph (void)
196{
16bb742f 197 state_number i;
35fe0834
PE
198 FILE *fgraph = xfopen (spec_graph_file, "w");
199 start_graph (fgraph);
ce4d5ce0 200
08a946e0 201 /* Output nodes and edges. */
9e7f6bbd 202 new_closure (nritems);
ce4d5ce0 203 for (i = 0; i < nstates; i++)
35fe0834 204 print_state (states[i], fgraph);
2e729273 205 free_closure ();
ce4d5ce0 206
35fe0834 207 finish_graph (fgraph);
342b8b6e 208 xfclose (fgraph);
ce4d5ce0 209}