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