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