1 /* Output a graph of the generated parser, for Bison.
3 Copyright (C) 2001-2007, 2009-2015, 2018-2021 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 <https://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_index
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
), "");
76 obstack_backslash (oout
, r
->lhs
->symbol
->tag
);
77 obstack_printf (oout
, ": ");
79 previous_lhs
= r
->lhs
;
81 for (item_number
const *sp
= r
->rhs
; sp
< sp1
; sp
++)
83 obstack_backslash (oout
, symbols
[*sp
]->tag
);
84 obstack_1grow (oout
, ' ');
87 obstack_sgrow (oout
, "•");
90 for (item_number
const *sp
= sp1
; 0 <= *sp
; ++sp
)
92 obstack_1grow (oout
, ' ');
93 obstack_backslash (oout
, symbols
[*sp
]->tag
);
96 obstack_sgrow (oout
, " %empty");
98 /* Experimental feature: display the lookahead tokens. */
99 if (report_flag
& report_lookaheads
100 && item_number_is_rule_number (*sp1
))
102 /* Find the reduction we are handling. */
103 reductions
*reds
= s
->reductions
;
104 int redno
= state_reduction_find (s
, r
);
106 /* Print them if there are. */
107 if (reds
->lookaheads
&& redno
!= -1)
109 bitset_iterator biter
;
111 char const *sep
= "";
112 obstack_sgrow (oout
, " [");
113 BITSET_FOR_EACH (biter
, reds
->lookaheads
[redno
], k
, 0)
115 obstack_sgrow (oout
, sep
);
116 obstack_backslash (oout
, symbols
[k
]->tag
);
119 obstack_1grow (oout
, ']');
122 obstack_sgrow (oout
, "\\l");
127 /*---------------------------------------------------------------.
128 | Output in graph_obstack edges specifications in incidence with |
130 `---------------------------------------------------------------*/
133 print_actions (state
const *s
, FILE *fgraph
)
135 transitions
const *trans
= s
->transitions
;
137 if (!trans
->num
&& !s
->reductions
)
140 for (int i
= 0; i
< trans
->num
; i
++)
141 if (!TRANSITION_IS_DISABLED (trans
, i
))
143 const state
*s1
= trans
->states
[i
];
144 const symbol_number sym
= s1
->accessing_symbol
;
146 /* Shifts are solid, gotos are dashed, and error is dotted. */
148 (TRANSITION_IS_ERROR (trans
, i
) ? "dotted"
149 : TRANSITION_IS_SHIFT (trans
, i
) ? "solid"
152 if (TRANSITION_IS_ERROR (trans
, i
)
153 && STRNEQ (symbols
[sym
]->tag
, "error"))
155 output_edge (s
->number
, s1
->number
,
156 TRANSITION_IS_ERROR (trans
, i
) ? NULL
: symbols
[sym
]->tag
,
159 /* Display reductions. */
160 output_red (s
, s
->reductions
, fgraph
);
164 /*-------------------------------------------------------------.
165 | Output in FGRAPH the current node specifications and exiting |
167 `-------------------------------------------------------------*/
170 print_state (state
*s
, FILE *fgraph
)
172 struct obstack node_obstack
;
174 /* A node's label contains its items. */
175 obstack_init (&node_obstack
);
176 print_core (&node_obstack
, s
);
177 output_node (s
->number
, obstack_finish0 (&node_obstack
), fgraph
);
178 obstack_free (&node_obstack
, 0);
180 /* Output the edges. */
181 print_actions (s
, fgraph
);
188 FILE *fgraph
= xfopen (spec_graph_file
, "w");
189 start_graph (fgraph
);
191 /* Output nodes and edges. */
192 for (int i
= 0; i
< nstates
; i
++)
193 print_state (states
[i
], fgraph
);
195 finish_graph (fgraph
);