1 /* Output a graph of the generated parser, for Bison.
3 Copyright (C) 2001-2007, 2009-2015, 2018-2019 Free Software
6 This file is part of Bison, the GNU Compiler Compiler.
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 #include "print-graph.h"
28 #include "conflicts.h"
40 /*----------------------------.
41 | Construct the node labels. |
42 `----------------------------*/
44 /* Print the lhs of a rule in such a manner that there is no vertical
45 repetition, like in *.output files. */
48 print_core (struct obstack
*oout
, state
*s
)
50 item_number
const *sitems
= s
->items
;
51 sym_content
*previous_lhs
= NULL
;
52 size_t snritems
= s
->nitems
;
54 /* Output all the items of a state, not just its kernel. */
55 if (report_flag
& report_itemsets
)
57 closure (sitems
, snritems
);
62 obstack_printf (oout
, _("State %d"), s
->number
);
63 obstack_sgrow (oout
, "\\n\\l");
64 for (size_t i
= 0; i
< snritems
; ++i
)
66 item_number
const *sp1
= ritem
+ sitems
[i
];
67 rule
const *r
= item_rule (sp1
);
69 obstack_printf (oout
, "%3d ", r
->number
);
70 if (previous_lhs
&& UNIQSTR_EQ (previous_lhs
->symbol
->tag
,
72 obstack_printf (oout
, "%*s| ",
73 (int) strlen (previous_lhs
->symbol
->tag
), "");
75 obstack_printf (oout
, "%s: ", escape (r
->lhs
->symbol
->tag
));
76 previous_lhs
= r
->lhs
;
78 for (item_number
const *sp
= r
->rhs
; sp
< sp1
; sp
++)
79 obstack_printf (oout
, "%s ", escape (symbols
[*sp
]->tag
));
81 obstack_1grow (oout
, '.');
84 for (item_number
const *sp
= sp1
; 0 <= *sp
; ++sp
)
85 obstack_printf (oout
, " %s", escape (symbols
[*sp
]->tag
));
87 obstack_printf (oout
, " %%empty");
89 /* Experimental feature: display the lookahead tokens. */
90 if (report_flag
& report_lookahead_tokens
91 && item_number_is_rule_number (*sp1
))
93 /* Find the reduction we are handling. */
94 reductions
*reds
= s
->reductions
;
95 int redno
= state_reduction_find (s
, r
);
97 /* Print them if there are. */
98 if (reds
->lookahead_tokens
&& redno
!= -1)
100 bitset_iterator biter
;
102 char const *sep
= "";
103 obstack_sgrow (oout
, " [");
104 BITSET_FOR_EACH (biter
, reds
->lookahead_tokens
[redno
], k
, 0)
106 obstack_sgrow (oout
, sep
);
107 obstack_sgrow (oout
, escape (symbols
[k
]->tag
));
110 obstack_1grow (oout
, ']');
113 obstack_sgrow (oout
, "\\l");
118 /*---------------------------------------------------------------.
119 | Output in graph_obstack edges specifications in incidence with |
121 `---------------------------------------------------------------*/
124 print_actions (state
const *s
, FILE *fgraph
)
126 transitions
const *trans
= s
->transitions
;
128 if (!trans
->num
&& !s
->reductions
)
131 for (int i
= 0; i
< trans
->num
; i
++)
132 if (!TRANSITION_IS_DISABLED (trans
, i
))
134 const state
*s1
= trans
->states
[i
];
135 const symbol_number sym
= s1
->accessing_symbol
;
137 /* Shifts are solid, gotos are dashed, and error is dotted. */
139 (TRANSITION_IS_ERROR (trans
, i
) ? "dotted"
140 : TRANSITION_IS_SHIFT (trans
, i
) ? "solid"
143 if (TRANSITION_IS_ERROR (trans
, i
)
144 && STRNEQ (symbols
[sym
]->tag
, "error"))
146 output_edge (s
->number
, s1
->number
,
147 TRANSITION_IS_ERROR (trans
, i
) ? NULL
: symbols
[sym
]->tag
,
150 /* Display reductions. */
151 output_red (s
, s
->reductions
, fgraph
);
155 /*-------------------------------------------------------------.
156 | Output in FGRAPH the current node specifications and exiting |
158 `-------------------------------------------------------------*/
161 print_state (state
*s
, FILE *fgraph
)
163 struct obstack node_obstack
;
165 /* A node's label contains its items. */
166 obstack_init (&node_obstack
);
167 print_core (&node_obstack
, s
);
168 output_node (s
->number
, obstack_finish0 (&node_obstack
), fgraph
);
169 obstack_free (&node_obstack
, 0);
171 /* Output the edges. */
172 print_actions (s
, fgraph
);
179 FILE *fgraph
= xfopen (spec_graph_file
, "w");
180 start_graph (fgraph
);
182 /* Output nodes and edges. */
183 for (int i
= 0; i
< nstates
; i
++)
184 print_state (states
[i
], fgraph
);
186 finish_graph (fgraph
);