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