]> git.saurik.com Git - bison.git/blame - src/relation.c
gnulib: update.
[bison.git] / src / relation.c
CommitLineData
0e4d5753 1/* Binary relations.
6e30ede8 2
c932d613 3 Copyright (C) 2002, 2004-2005, 2009-2012 Free Software Foundation,
ea0a7676 4 Inc.
0e4d5753
AD
5
6 This file is part of Bison, the GNU Compiler Compiler.
7
f16b0819 8 This program is free software: you can redistribute it and/or modify
0e4d5753 9 it under the terms of the GNU General Public License as published by
f16b0819
PE
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
0e4d5753 12
f16b0819 13 This program is distributed in the hope that it will be useful,
0e4d5753
AD
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.
17
18 You should have received a copy of the GNU General Public License
f16b0819 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0e4d5753 20
2cec9080 21#include <config.h>
0e4d5753 22#include "system.h"
17ee7397
PE
23
24#include <bitsetv.h>
25
0e4d5753 26#include "getargs.h"
17ee7397 27#include "relation.h"
0e4d5753
AD
28
29void
7b21ee09 30relation_print (relation r, relation_node size, FILE *out)
0e4d5753 31{
7b21ee09
PE
32 relation_node i;
33 relation_node j;
0e4d5753
AD
34
35 for (i = 0; i < size; ++i)
36 {
7b21ee09 37 fprintf (out, "%3lu: ", (unsigned long int) i);
17ee7397 38 if (r[i])
0859e438 39 for (j = 0; r[i][j] != END_NODE; ++j)
7b21ee09 40 fprintf (out, "%3lu ", (unsigned long int) r[i][j]);
0e4d5753
AD
41 fputc ('\n', out);
42 }
43 fputc ('\n', out);
44}
45
46
47/*---------------------------------------------------------------.
48| digraph & traverse. |
49| |
50| The following variables are used as common storage between the |
51| two. |
52`---------------------------------------------------------------*/
53
17ee7397
PE
54static relation R;
55static relation_nodes INDEX;
56static relation_nodes VERTICES;
7b21ee09
PE
57static relation_node top;
58static relation_node infinity;
0e4d5753
AD
59static bitsetv F;
60
61static void
7b21ee09 62traverse (relation_node i)
0e4d5753 63{
7b21ee09
PE
64 relation_node j;
65 relation_node height;
0e4d5753
AD
66
67 VERTICES[++top] = i;
68 INDEX[i] = height = top;
69
70 if (R[i])
0859e438 71 for (j = 0; R[i][j] != END_NODE; ++j)
0e4d5753
AD
72 {
73 if (INDEX[R[i][j]] == 0)
74 traverse (R[i][j]);
75
76 if (INDEX[i] > INDEX[R[i][j]])
77 INDEX[i] = INDEX[R[i][j]];
78
79 bitset_or (F[i], F[i], F[R[i][j]]);
80 }
81
82 if (INDEX[i] == height)
83 for (;;)
84 {
85 j = VERTICES[top--];
86 INDEX[j] = infinity;
87
88 if (i == j)
89 break;
90
91 bitset_copy (F[j], F[i]);
92 }
93}
94
95
96void
7b21ee09 97relation_digraph (relation r, relation_node size, bitsetv *function)
0e4d5753 98{
7b21ee09 99 relation_node i;
0e4d5753
AD
100
101 infinity = size + 2;
da2a7671
PE
102 INDEX = xcalloc (size + 1, sizeof *INDEX);
103 VERTICES = xnmalloc (size + 1, sizeof *VERTICES);
0e4d5753
AD
104 top = 0;
105
17ee7397 106 R = r;
0e4d5753
AD
107 F = *function;
108
0e4d5753
AD
109 for (i = 0; i < size; i++)
110 if (INDEX[i] == 0 && R[i])
111 traverse (i);
112
afbb696d
PE
113 free (INDEX);
114 free (VERTICES);
0e4d5753
AD
115
116 *function = F;
117}
118
119
120/*-------------------------------------------.
121| Destructively transpose R_ARG, of size N. |
122`-------------------------------------------*/
123
124void
7b21ee09 125relation_transpose (relation *R_arg, relation_node n)
0e4d5753 126{
26a69b31 127 relation r = *R_arg;
0e4d5753 128 /* The result. */
da2a7671 129 relation new_R = xnmalloc (n, sizeof *new_R);
0e4d5753 130 /* END_R[I] -- next entry of NEW_R[I]. */
da2a7671 131 relation end_R = xnmalloc (n, sizeof *end_R);
0e4d5753 132 /* NEDGES[I] -- total size of NEW_R[I]. */
7b21ee09
PE
133 size_t *nedges = xcalloc (n, sizeof *nedges);
134 relation_node i;
135 relation_node j;
0e4d5753 136
273a74fa 137 if (trace_flag & trace_sets)
0e4d5753 138 {
427c0dda 139 fputs ("relation_transpose: input\n", stderr);
26a69b31 140 relation_print (r, n, stderr);
0e4d5753
AD
141 }
142
143 /* Count. */
144 for (i = 0; i < n; i++)
26a69b31
PE
145 if (r[i])
146 for (j = 0; r[i][j] != END_NODE; ++j)
147 ++nedges[r[i][j]];
0e4d5753
AD
148
149 /* Allocate. */
150 for (i = 0; i < n; i++)
da2a7671
PE
151 {
152 relation_node *sp = NULL;
153 if (nedges[i] > 0)
154 {
155 sp = xnmalloc (nedges[i] + 1, sizeof *sp);
156 sp[nedges[i]] = END_NODE;
157 }
158 new_R[i] = sp;
159 end_R[i] = sp;
160 }
0e4d5753
AD
161
162 /* Store. */
163 for (i = 0; i < n; i++)
26a69b31
PE
164 if (r[i])
165 for (j = 0; r[i][j] != END_NODE; ++j)
166 *end_R[r[i][j]]++ = i;
0e4d5753
AD
167
168 free (nedges);
169 free (end_R);
170
171 /* Free the input: it is replaced with the result. */
172 for (i = 0; i < n; i++)
26a69b31
PE
173 free (r[i]);
174 free (r);
0e4d5753 175
273a74fa 176 if (trace_flag & trace_sets)
0e4d5753 177 {
427c0dda 178 fputs ("relation_transpose: output\n", stderr);
0e4d5753
AD
179 relation_print (new_R, n, stderr);
180 }
181
182 *R_arg = new_R;
183}