]> git.saurik.com Git - bison.git/blame - src/graphviz.c
tests: check %no-lines
[bison.git] / src / graphviz.c
CommitLineData
35fe0834
PE
1/* Output Graphviz specification of a state machine generated by Bison.
2
c932d613 3 Copyright (C) 2006-2007, 2009-2012 Free Software Foundation, Inc.
35fe0834
PE
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
35fe0834 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.
35fe0834 11
f16b0819 12 This program is distributed in the hope that it will be useful,
35fe0834
PE
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/>. */
35fe0834
PE
19
20/* Written by Paul Eggert and Satya Kiran Popuri. */
21
22#include <config.h>
23#include "system.h"
24
25#include <quotearg.h>
26
a0279765 27#include "files.h"
83bae26d 28#include "gram.h"
35fe0834 29#include "graphviz.h"
83bae26d 30#include "tables.h"
35fe0834
PE
31
32/* Return an unambiguous printable representation for NAME, suitable
33 for C strings. Use slot 2 since the user may use slots 0 and 1. */
34
a13121f7 35static char *
35fe0834
PE
36quote (char const *name)
37{
38 return quotearg_n_style (2, c_quoting_style, name);
39}
40
41void
42start_graph (FILE *fout)
43{
a0279765 44 fprintf (fout,
ad6f84e5
JD
45 _("// Generated by %s.\n"
46 "// Report bugs to <%s>.\n"
47 "// Home page: <%s>.\n"
a0279765
AD
48 "\n"),
49 PACKAGE_STRING,
50 PACKAGE_BUGREPORT,
51 PACKAGE_URL);
52 fprintf (fout,
53 "digraph %s\n"
54 "{\n",
55 quote (grammar_file));
2be37f19 56 fprintf (fout, "node [shape=box]\n");
35fe0834
PE
57}
58
59void
60output_node (int id, char const *label, FILE *fout)
61{
a13121f7 62 fprintf (fout, " %d [label=\"%s\"]\n", id, label);
35fe0834
PE
63}
64
65void
66output_edge (int source, int destination, char const *label,
a13121f7 67 char const *style, FILE *fout)
35fe0834 68{
21f1b063 69 fprintf (fout, " %d -> %d [style=%s", source, destination, style);
35fe0834
PE
70 if (label)
71 fprintf (fout, " label=%s", quote (label));
72 fputs ("]\n", fout);
73}
74
a13121f7
TR
75char const *
76escape (char const *name)
77{
78 char *q = quote (name);
79 q[strlen (q) - 1] = '\0';
80 return q + 1;
81}
82
83bae26d
TR
83static void
84no_reduce_bitset_init (state const *s, bitset *no_reduce_set)
85{
86 int n;
87 *no_reduce_set = bitset_create (ntokens, BITSET_FIXED);
88 bitset_zero (*no_reduce_set);
89 FOR_EACH_SHIFT (s->transitions, n)
90 bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n));
91 for (n = 0; n < s->errs->num; ++n)
92 if (s->errs->symbols[n])
93 bitset_set (*no_reduce_set, s->errs->symbols[n]->number);
94}
95
96static bool
97print_token (struct obstack *out, bool first, char const *tok)
98{
99 char const *q = escape (tok);
100
101 if (! first)
102 obstack_sgrow (out, ",");
103 obstack_sgrow (out, q);
104 return false;
105}
106
107void
108output_red (state const *s, reductions const *reds, FILE *fout)
109{
83bae26d 110 bitset no_reduce_set;
d79683fa
TR
111 int j;
112 int source = s->number;
83bae26d 113 struct obstack oout;
d79683fa
TR
114
115 no_reduce_bitset_init (s, &no_reduce_set);
83bae26d
TR
116 obstack_init (&oout);
117
118 for (j = 0; j < reds->num; ++j)
119 {
83bae26d 120 bool disabled = false;
d79683fa 121 bool first = true;
83bae26d
TR
122 int ruleno = reds->rules[j]->user_number;
123 rule *default_reduction = NULL;
d79683fa 124
83bae26d
TR
125 if (yydefact[s->number] != 0)
126 default_reduction = &rules[yydefact[s->number] - 1];
127
128 /* First, print the edges that represent each possible reduction for
129 the given state. */
130 obstack_printf (&oout, " %1$d -> \"%1$dR%2$d\" [label=\"",
131 source, ruleno);
132 if (default_reduction && default_reduction == reds->rules[j])
133 first = print_token (&oout, true, "$default");
134 else
d79683fa
TR
135 {
136 int i;
137 for (i = 0; i < ntokens; i++)
83bae26d
TR
138 if (bitset_test (reds->lookahead_tokens[j], i))
139 {
140 first = print_token (&oout, first, symbols[i]->tag);
141 if (bitset_test (no_reduce_set, i))
142 disabled = true;
143 }
d79683fa 144 }
83bae26d
TR
145 obstack_sgrow (&oout, "\" style=solid]\n");
146
43eb7674
AD
147 /* Then, print the reduction's representation. Done later since
148 we need to know whether this reduction is disabled. */
149 obstack_printf (&oout,
150 " \"%dR%d\" "
151 "[style=filled shape=diamond fillcolor=%s "
152 "label=\"R%d\"]\n",
83bae26d
TR
153 source, ruleno,
154 disabled ? "firebrick1" : "yellowgreen",
155 ruleno);
156
157 /* If no lookahead tokens were valid transitions, this reduction is
158 actually disabled, so don't print it. */
159 if (first)
160 (void) obstack_finish0 (&oout);
161 else
162 fprintf (fout, obstack_finish0 (&oout));
163 }
164 obstack_free (&oout, 0);
165}
166
35fe0834
PE
167void
168finish_graph (FILE *fout)
169{
170 fputs ("}\n", fout);
171}