]> git.saurik.com Git - bison.git/blame - src/print_graph.c
c++: style: use "unsigned", not "unsigned int"
[bison.git] / src / print_graph.c
CommitLineData
35fe0834 1/* Output a graph of the generated parser, for Bison.
16bb742f 2
3209eb1c 3 Copyright (C) 2001-2007, 2009-2015 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
ce4d5ce0 45static void
16bb742f 46print_core (struct obstack *oout, state *s)
ce4d5ce0 47{
fd7f0289
AD
48 item_number const *sitems = s->items;
49 symbol *previous_lhs = NULL;
ce6cf10f 50 size_t i;
f6fbd3da 51 size_t snritems = s->nitems;
22c2cbc0 52
fd7f0289 53 /* Output all the items of a state, not just its kernel. */
05811fd7 54 if (report_flag & report_itemsets)
30171f79 55 {
5123689b 56 closure (sitems, snritems);
30171f79 57 sitems = itemset;
b09f4f48 58 snritems = nitemset;
30171f79 59 }
22c2cbc0 60
8048226f 61 obstack_printf (oout, _("State %d"), s->number);
be3517b0 62 obstack_sgrow (oout, "\\n\\l");
5123689b 63 for (i = 0; i < snritems; i++)
ce4d5ce0 64 {
fd7f0289
AD
65 item_number const *sp1 = ritem + sitems[i];
66 item_number const *sp = sp1;
67 rule *r;
ce4d5ce0 68
fd7f0289 69 while (0 <= *sp)
e9690142 70 sp++;
ce4d5ce0 71
fd7f0289 72 r = &rules[item_number_as_rule_number (*sp)];
ce4d5ce0 73
fd7f0289
AD
74 obstack_printf (oout, "%3d ", r->number);
75 if (previous_lhs && UNIQSTR_EQ (previous_lhs->tag, r->lhs->tag))
76 obstack_printf (oout, "%*s| ",
77 (int) strlen (previous_lhs->tag), "");
78 else
79 obstack_printf (oout, "%s: ", escape (r->lhs->tag));
80 previous_lhs = r->lhs;
ce4d5ce0 81
fd7f0289 82 for (sp = r->rhs; sp < sp1; sp++)
a13121f7 83 obstack_printf (oout, "%s ", escape (symbols[*sp]->tag));
ce4d5ce0 84
32288c8c 85 obstack_1grow (oout, '.');
22c2cbc0 86
21cf8039
AD
87 if (0 <= *r->rhs)
88 for (/* Nothing */; *sp >= 0; ++sp)
89 obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
90 else
91 obstack_printf (oout, " %%empty");
d4e7d3a1 92
742e4900 93 /* Experimental feature: display the lookahead tokens. */
255a6b90
JD
94 if (report_flag & report_lookahead_tokens
95 && item_number_is_rule_number (*sp1))
e9690142
JD
96 {
97 /* Find the reduction we are handling. */
98 reductions *reds = s->reductions;
fd7f0289 99 int redno = state_reduction_find (s, r);
e9690142
JD
100
101 /* Print them if there are. */
102 if (reds->lookahead_tokens && redno != -1)
103 {
104 bitset_iterator biter;
105 int k;
106 char const *sep = "";
8048226f 107 obstack_sgrow (oout, " [");
e9690142
JD
108 BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0)
109 {
a13121f7
TR
110 obstack_sgrow (oout, sep);
111 obstack_sgrow (oout, escape (symbols[k]->tag));
e9690142
JD
112 sep = ", ";
113 }
a13121f7 114 obstack_1grow (oout, ']');
e9690142
JD
115 }
116 }
a13121f7 117 obstack_sgrow (oout, "\\l");
ce4d5ce0 118 }
ce4d5ce0
AD
119}
120
08a946e0
AD
121
122/*---------------------------------------------------------------.
123| Output in graph_obstack edges specifications in incidence with |
124| current node. |
125`---------------------------------------------------------------*/
126
ce4d5ce0 127static void
35fe0834 128print_actions (state const *s, FILE *fgraph)
ce4d5ce0 129{
35fe0834 130 transitions const *trans = s->transitions;
8048226f 131 int i;
22c2cbc0 132
35fe0834 133 if (!trans->num && !s->reductions)
5092aba5 134 return;
ce4d5ce0 135
16bb742f
PE
136 for (i = 0; i < trans->num; i++)
137 if (!TRANSITION_IS_DISABLED (trans, i))
d954473d 138 {
e9690142
JD
139 state *s1 = trans->states[i];
140 symbol_number sym = s1->accessing_symbol;
141
142 /* Shifts are solid, gotos are dashed, and error is dotted. */
143 char const *style =
144 (TRANSITION_IS_ERROR (trans, i) ? "dotted"
145 : TRANSITION_IS_SHIFT (trans, i) ? "solid"
146 : "dashed");
147
148 if (TRANSITION_IS_ERROR (trans, i)
f518dbaf 149 && STRNEQ (symbols[sym]->tag, "error"))
e9690142
JD
150 abort ();
151 output_edge (s->number, s1->number,
152 TRANSITION_IS_ERROR (trans, i) ? NULL : symbols[sym]->tag,
153 style, fgraph);
d954473d 154 }
be3517b0
TR
155 /* Display reductions. */
156 output_red (s, s->reductions, fgraph);
ce4d5ce0
AD
157}
158
08a946e0
AD
159
160/*-------------------------------------------------------------.
161| Output in FGRAPH the current node specifications and exiting |
162| edges. |
163`-------------------------------------------------------------*/
164
ce4d5ce0 165static void
35fe0834 166print_state (state *s, FILE *fgraph)
ce4d5ce0 167{
600cad3b 168 struct obstack node_obstack;
ce4d5ce0 169
35fe0834 170 /* A node's label contains its items. */
600cad3b 171 obstack_init (&node_obstack);
16bb742f 172 print_core (&node_obstack, s);
6fbe73b6 173 output_node (s->number, obstack_finish0 (&node_obstack), fgraph);
35fe0834 174 obstack_free (&node_obstack, 0);
342b8b6e 175
08a946e0 176 /* Output the edges. */
35fe0834 177 print_actions (s, fgraph);
ce4d5ce0
AD
178}
179\f
180
181void
182print_graph (void)
183{
16bb742f 184 state_number i;
35fe0834
PE
185 FILE *fgraph = xfopen (spec_graph_file, "w");
186 start_graph (fgraph);
ce4d5ce0 187
08a946e0 188 /* Output nodes and edges. */
9e7f6bbd 189 new_closure (nritems);
ce4d5ce0 190 for (i = 0; i < nstates; i++)
35fe0834 191 print_state (states[i], fgraph);
2e729273 192 free_closure ();
ce4d5ce0 193
35fe0834 194 finish_graph (fgraph);
342b8b6e 195 xfclose (fgraph);
ce4d5ce0 196}