]> git.saurik.com Git - bison.git/blame - src/closure.c
* src/closure.c, src/print.c, src/reader.c, src/reduce.c:
[bison.git] / src / closure.c
CommitLineData
d0fb370f 1/* Subroutines for bison
914feea9 2 Copyright (C) 1984, 1989, 2000, 2001, 2002 Free Software Foundation, Inc.
d0fb370f 3
8dc26b76 4 This file is part of Bison, the GNU Compiler Compiler.
d0fb370f 5
8dc26b76
AD
6 Bison is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
d0fb370f 10
8dc26b76
AD
11 Bison is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
d0fb370f 15
8dc26b76
AD
16 You should have received a copy of the GNU General Public License
17 along with Bison; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
d0fb370f 20
d0fb370f 21#include "system.h"
914feea9
AD
22#include "bitset.h"
23#include "bitsetv.h"
9bfe901c 24#include "getargs.h"
ad949da9 25#include "symtab.h"
d0fb370f 26#include "gram.h"
2c5f66ed 27#include "reader.h"
2fa6973e 28#include "closure.h"
340ef489 29#include "derives.h"
d0fb370f 30
b2872512 31/* NITEMSET is the size of the array ITEMSET. */
d0fb370f 32short *itemset;
b2872512 33int nitemset;
fb908786 34
dfdb1797 35static bitset ruleset;
d0fb370f
RS
36
37/* internal data. See comments before set_fderives and set_firsts. */
914feea9
AD
38static bitsetv fderives = NULL;
39static bitsetv firsts = NULL;
d0fb370f 40
03ec521c 41/* Retrieve the FDERIVES/FIRSTS sets of the nonterminals numbered Var. */
7086e707 42#define FDERIVES(Var) fderives[(Var) - ntokens]
d8a0245c 43#define FIRSTS(Var) firsts[(Var) - ntokens]
2fa6973e 44\f
d0fb370f 45
2fa6973e
AD
46/*-----------------.
47| Debugging code. |
48`-----------------*/
d0fb370f 49
2fa6973e 50static void
23cbcc6c 51print_closure (const char *title, short *array, size_t size)
2fa6973e 52{
23cbcc6c
AD
53 size_t i;
54 fprintf (stderr, "Closure: %s\n", title);
55 for (i = 0; i < size; ++i)
56 {
57 short *rp;
58 fprintf (stderr, " %2d: .", array[i]);
75142d45 59 for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
ad949da9 60 fprintf (stderr, " %s", symbols[*rp]->tag);
29d29c8f 61 fprintf (stderr, " (rule %d)\n", -*rp - 1);
23cbcc6c
AD
62 }
63 fputs ("\n\n", stderr);
2fa6973e
AD
64}
65
66
67static void
68print_firsts (void)
d0fb370f 69{
84182270 70 int i, j;
2fa6973e 71
c87d4863 72 fprintf (stderr, "FIRSTS\n");
2fa6973e
AD
73 for (i = ntokens; i < nsyms; i++)
74 {
ad949da9 75 fprintf (stderr, "\t%s firsts\n", symbols[i]->tag);
2fa6973e 76 for (j = 0; j < nvars; j++)
d8a0245c 77 if (bitset_test (FIRSTS (i), j))
ad949da9
AD
78 fprintf (stderr, "\t\t%d (%s)\n",
79 j + ntokens, symbols[j + ntokens]->tag);
2fa6973e 80 }
c87d4863 81 fprintf (stderr, "\n\n");
d0fb370f
RS
82}
83
84
2fa6973e
AD
85static void
86print_fderives (void)
87{
d8a0245c 88 int i, j;
2fa6973e 89
c87d4863 90 fprintf (stderr, "FDERIVES\n");
2fa6973e
AD
91 for (i = ntokens; i < nsyms; i++)
92 {
ad949da9 93 fprintf (stderr, "\t%s derives\n", symbols[i]->tag);
18bcecb0 94 for (j = 0; j < nrules + 1; j++)
7086e707 95 if (bitset_test (FDERIVES (i), j))
720e5c1b
AD
96 {
97 short *rhsp;
29d29c8f 98 fprintf (stderr, "\t\t%d:", j - 1);
99013900 99 for (rhsp = rules[j].rhs; *rhsp >= 0; ++rhsp)
ad949da9 100 fprintf (stderr, " %s", symbols[*rhsp]->tag);
720e5c1b
AD
101 fputc ('\n', stderr);
102 }
2fa6973e 103 }
c87d4863 104 fprintf (stderr, "\n\n");
2fa6973e 105}
65ccf9fc
AD
106
107/*--------------------------------------------------------.
108| Display the MATRIX array of SIZE bitsets of size SIZE. |
109`--------------------------------------------------------*/
110
111static void
112bitmatrix_print (const char *title, bitsetv matrix)
113{
114 size_t i, j;
115 size_t size = bitset_size (matrix[0]);
116
117 /* Title. */
118 fprintf (stderr, "%s BEGIN\n", title);
119
120 /* Column numbers. */
121 fputs (" ", stderr);
122 for (i = 0; i < size; ++i)
123 putc (i / 10 ? '0' + i / 10 : ' ', stderr);
124 putc ('\n', stderr);
125 fputs (" ", stderr);
126 for (i = 0; i < size; ++i)
127 fprintf (stderr, "%d", i % 10);
128 putc ('\n', stderr);
129
130 /* Bar. */
131 fputs (" .", stderr);
132 for (i = 0; i < size; ++i)
133 putc ('-', stderr);
134 fputs (".\n", stderr);
135
136 /* Contents. */
137 for (i = 0; i < size; ++i)
138 {
139 fprintf (stderr, "%2d|", i);
140 for (j = 0; j < size; ++j)
141 fputs (bitset_test (matrix[i], j) ? "1" : " ", stderr);
142 fputs ("|\n", stderr);
143 }
144
145 /* Bar. */
146 fputs (" `", stderr);
147 for (i = 0; i < size; ++i)
148 putc ('-', stderr);
149 fputs ("'\n", stderr);
150
151 /* End title. */
152 fprintf (stderr, "%s END\n\n", title);
153}
2fa6973e 154\f
d8a0245c
AD
155/*------------------------------------------------------------------.
156| Set FIRSTS to be an NVARS array of NVARS bitsets indicating which |
157| items can represent the beginning of the input corresponding to |
158| which other items. |
159| |
160| For example, if some rule expands symbol 5 into the sequence of |
161| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
162| symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
163| (5)) is set. |
164`------------------------------------------------------------------*/
2fa6973e
AD
165
166static void
167set_firsts (void)
168{
3f6f053c 169 int i, j;
2fa6973e 170
914feea9
AD
171 firsts = bitsetv_create (nvars, nvars, BITSET_FIXED);
172
2fa6973e 173 for (i = ntokens; i < nsyms; i++)
914feea9
AD
174 for (j = 0; derives[i][j] >= 0; ++j)
175 {
99013900 176 int symbol = rules[derives[i][j]].rhs[0];
914feea9
AD
177 if (ISVAR (symbol))
178 bitset_set (FIRSTS (i), symbol - ntokens);
179 }
2fa6973e 180
65ccf9fc
AD
181 if (trace_flag)
182 bitmatrix_print ("RTC: Input", firsts);
183 bitsetv_reflexive_transitive_closure (firsts);
184 if (trace_flag)
185 bitmatrix_print ("RTC: Output", firsts);
2fa6973e 186
9bfe901c
AD
187 if (trace_flag)
188 print_firsts ();
2fa6973e
AD
189}
190
191/*-------------------------------------------------------------------.
192| Set FDERIVES to an NVARS by NRULES matrix of bits indicating which |
193| rules can help derive the beginning of the data for each |
194| nonterminal. |
195| |
196| For example, if symbol 5 can be derived as the sequence of symbols |
197| 8 3 20, and one of the rules for deriving symbol 8 is rule 4, then |
198| the [5 - NTOKENS, 4] bit in FDERIVES is set. |
199`-------------------------------------------------------------------*/
d0fb370f 200
4a120d45 201static void
d2729d44 202set_fderives (void)
d0fb370f 203{
1cbcf2e7 204 int i, j, k;
d0fb370f 205
914feea9 206 fderives = bitsetv_create (nvars, nrules + 1, BITSET_FIXED);
d0fb370f 207
2fa6973e 208 set_firsts ();
d0fb370f 209
1cbcf2e7
AD
210 for (i = ntokens; i < nsyms; ++i)
211 for (j = ntokens; j < nsyms; ++j)
d8a0245c 212 if (bitset_test (FIRSTS (i), j - ntokens))
1cbcf2e7 213 for (k = 0; derives[j][k] > 0; ++k)
7086e707 214 bitset_set (FDERIVES (i), derives[j][k]);
d0fb370f 215
9bfe901c
AD
216 if (trace_flag)
217 print_fderives ();
d0fb370f 218
914feea9 219 bitsetv_free (firsts);
d0fb370f 220}
2fa6973e 221\f
d0fb370f 222
2fa6973e
AD
223void
224new_closure (int n)
d0fb370f 225{
d7913476 226 itemset = XCALLOC (short, n);
d0fb370f 227
dfdb1797 228 ruleset = bitset_create (nrules + 1, BITSET_FIXED);
d0fb370f 229
2fa6973e 230 set_fderives ();
d0fb370f
RS
231}
232
233
2fa6973e 234
d0fb370f 235void
d2729d44 236closure (short *core, int n)
d0fb370f 237{
576890b7
AD
238 /* Index over CORE. */
239 int c;
240
d2b04478 241 /* A bit index over RULESET. */
4b35e1c1 242 int ruleno;
d0fb370f 243
c87d4863 244 if (trace_flag)
23cbcc6c 245 print_closure ("input", core, n);
c87d4863 246
d0fb370f
RS
247 if (n == 0)
248 {
dfdb1797 249 bitset_copy (ruleset, FDERIVES (start_symbol));
d0fb370f
RS
250 }
251 else
252 {
dfdb1797 253 bitset_zero (ruleset);
d0fb370f 254
576890b7
AD
255 for (c = 0; c < n; ++c)
256 if (ISVAR (ritem[core[c]]))
dfdb1797 257 bitset_or (ruleset, ruleset, FDERIVES (ritem[core[c]]));
d0fb370f
RS
258 }
259
b2872512 260 nitemset = 0;
576890b7 261 c = 0;
cb581495 262 for (ruleno = 0; ruleno < nrules + 1; ++ruleno)
dfdb1797 263 if (bitset_test (ruleset, ruleno))
4b35e1c1 264 {
99013900 265 int itemno = rules[ruleno].rhs - ritem;
4b35e1c1
AD
266 while (c < n && core[c] < itemno)
267 {
b2872512
AD
268 itemset[nitemset] = core[c];
269 nitemset++;
4b35e1c1
AD
270 c++;
271 }
b2872512
AD
272 itemset[nitemset] = itemno;
273 nitemset++;
4b35e1c1 274 }
d0fb370f 275
576890b7
AD
276 while (c < n)
277 {
b2872512
AD
278 itemset[nitemset] = core[c];
279 nitemset++;
576890b7
AD
280 c++;
281 }
d0fb370f 282
9bfe901c 283 if (trace_flag)
b2872512 284 print_closure ("output", itemset, nitemset);
d0fb370f
RS
285}
286
287
288void
2fa6973e 289free_closure (void)
d0fb370f 290{
d7913476 291 XFREE (itemset);
dfdb1797 292 bitset_free (ruleset);
914feea9 293 bitsetv_free (fderives);
d0fb370f 294}