]> git.saurik.com Git - bison.git/blame - src/closure.c
* src/files.c (skeleton_find) [MSDOS]: Fix cp definition.
[bison.git] / src / closure.c
CommitLineData
d0fb370f 1/* Subroutines for bison
2c5f66ed 2 Copyright 1984, 1989, 2000, 2001 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"
9bfe901c 22#include "getargs.h"
ad949da9 23#include "symtab.h"
d0fb370f 24#include "gram.h"
2c5f66ed 25#include "reader.h"
2fa6973e 26#include "closure.h"
340ef489 27#include "derives.h"
d7913476 28#include "warshall.h"
d0fb370f 29
b2872512 30/* NITEMSET is the size of the array ITEMSET. */
d0fb370f 31short *itemset;
b2872512 32int nitemset;
fb908786 33
d0fb370f
RS
34static unsigned *ruleset;
35
36/* internal data. See comments before set_fderives and set_firsts. */
37static unsigned *fderives;
38static unsigned *firsts;
39
03ec521c
AD
40/* Retrieve the FDERIVES/FIRSTS sets of the nonterminals numbered Var. */
41#define FDERIVES(Var) (fderives + ((Var) - ntokens) * rulesetsize)
42#define FIRSTS(Var) (firsts + ((Var) - ntokens) * varsetsize)
c87d4863 43
d0fb370f
RS
44/* number of words required to hold a bit for each rule */
45static int rulesetsize;
46
47/* number of words required to hold a bit for each variable */
48static int varsetsize;
2fa6973e 49\f
d0fb370f 50
2fa6973e
AD
51/*-----------------.
52| Debugging code. |
53`-----------------*/
d0fb370f 54
2fa6973e 55static void
23cbcc6c 56print_closure (const char *title, short *array, size_t size)
2fa6973e 57{
23cbcc6c
AD
58 size_t i;
59 fprintf (stderr, "Closure: %s\n", title);
60 for (i = 0; i < size; ++i)
61 {
62 short *rp;
63 fprintf (stderr, " %2d: .", array[i]);
75142d45 64 for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
ad949da9 65 fprintf (stderr, " %s", symbols[*rp]->tag);
29d29c8f 66 fprintf (stderr, " (rule %d)\n", -*rp - 1);
23cbcc6c
AD
67 }
68 fputs ("\n\n", stderr);
2fa6973e
AD
69}
70
71
72static void
73print_firsts (void)
d0fb370f 74{
84182270 75 int i, j;
2fa6973e 76
c87d4863 77 fprintf (stderr, "FIRSTS\n");
2fa6973e
AD
78 for (i = ntokens; i < nsyms; i++)
79 {
ad949da9 80 fprintf (stderr, "\t%s firsts\n", symbols[i]->tag);
2fa6973e 81 for (j = 0; j < nvars; j++)
03ec521c 82 if (BITISSET (FIRSTS (i), j))
ad949da9
AD
83 fprintf (stderr, "\t\t%d (%s)\n",
84 j + ntokens, symbols[j + ntokens]->tag);
2fa6973e 85 }
c87d4863 86 fprintf (stderr, "\n\n");
d0fb370f
RS
87}
88
89
2fa6973e
AD
90static void
91print_fderives (void)
92{
93 int i;
94 int j;
2fa6973e 95
c87d4863 96 fprintf (stderr, "FDERIVES\n");
2fa6973e
AD
97
98 for (i = ntokens; i < nsyms; i++)
99 {
ad949da9 100 fprintf (stderr, "\t%s derives\n", symbols[i]->tag);
2fa6973e 101 for (j = 0; j <= nrules; j++)
84182270 102 if (BITISSET (FDERIVES (i), j))
720e5c1b
AD
103 {
104 short *rhsp;
29d29c8f 105 fprintf (stderr, "\t\t%d:", j - 1);
1a2b5d37 106 for (rhsp = &ritem[rules[j].rhs]; *rhsp >= 0; ++rhsp)
ad949da9 107 fprintf (stderr, " %s", symbols[*rhsp]->tag);
720e5c1b
AD
108 fputc ('\n', stderr);
109 }
2fa6973e 110 }
c87d4863 111 fprintf (stderr, "\n\n");
2fa6973e 112}
2fa6973e
AD
113\f
114/*-------------------------------------------------------------------.
115| Set FIRSTS to be an NVARS by NVARS bit matrix indicating which |
116| items can represent the beginning of the input corresponding to |
117| which other items. |
118| |
119| For example, if some rule expands symbol 5 into the sequence of |
120| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
121| symbol 5, so the bit [8 - ntokens, 5 - ntokens] in firsts is set. |
122`-------------------------------------------------------------------*/
123
124static void
125set_firsts (void)
126{
3f6f053c 127 int i, j;
2fa6973e 128
03ec521c 129 varsetsize = WORDSIZE (nvars);
2fa6973e 130
03ec521c 131 firsts = XCALLOC (unsigned, nvars * varsetsize);
2fa6973e 132
2fa6973e 133 for (i = ntokens; i < nsyms; i++)
3f6f053c
AD
134 for (j = 0; derives[i][j] >= 0; ++j)
135 {
1a2b5d37 136 int symbol = ritem[rules[derives[i][j]].rhs];
3f6f053c 137 if (ISVAR (symbol))
03ec521c 138 SETBIT (FIRSTS (i), symbol - ntokens);
3f6f053c 139 }
2fa6973e
AD
140
141 RTC (firsts, nvars);
142
9bfe901c
AD
143 if (trace_flag)
144 print_firsts ();
2fa6973e
AD
145}
146
147/*-------------------------------------------------------------------.
148| Set FDERIVES to an NVARS by NRULES matrix of bits indicating which |
149| rules can help derive the beginning of the data for each |
150| nonterminal. |
151| |
152| For example, if symbol 5 can be derived as the sequence of symbols |
153| 8 3 20, and one of the rules for deriving symbol 8 is rule 4, then |
154| the [5 - NTOKENS, 4] bit in FDERIVES is set. |
155`-------------------------------------------------------------------*/
d0fb370f 156
4a120d45 157static void
d2729d44 158set_fderives (void)
d0fb370f 159{
1cbcf2e7 160 int i, j, k;
d0fb370f 161
03ec521c 162 fderives = XCALLOC (unsigned, nvars * rulesetsize);
d0fb370f 163
2fa6973e 164 set_firsts ();
d0fb370f 165
1cbcf2e7
AD
166 for (i = ntokens; i < nsyms; ++i)
167 for (j = ntokens; j < nsyms; ++j)
03ec521c 168 if (BITISSET (FIRSTS (i), j - ntokens))
1cbcf2e7
AD
169 for (k = 0; derives[j][k] > 0; ++k)
170 SETBIT (FDERIVES (i), derives[j][k]);
d0fb370f 171
9bfe901c
AD
172 if (trace_flag)
173 print_fderives ();
d0fb370f 174
d7913476 175 XFREE (firsts);
d0fb370f 176}
2fa6973e 177\f
d0fb370f 178
2fa6973e
AD
179void
180new_closure (int n)
d0fb370f 181{
d7913476 182 itemset = XCALLOC (short, n);
d0fb370f 183
2fa6973e 184 rulesetsize = WORDSIZE (nrules + 1);
d7913476 185 ruleset = XCALLOC (unsigned, rulesetsize);
d0fb370f 186
2fa6973e 187 set_fderives ();
d0fb370f
RS
188}
189
190
2fa6973e 191
d0fb370f 192void
d2729d44 193closure (short *core, int n)
d0fb370f 194{
576890b7
AD
195 /* Index over CORE. */
196 int c;
197
198 /* Index over RULESET. */
199 int r;
d0fb370f 200
d2b04478 201 /* A bit index over RULESET. */
4b35e1c1 202 int ruleno;
d0fb370f 203
c87d4863 204 if (trace_flag)
23cbcc6c 205 print_closure ("input", core, n);
c87d4863 206
d0fb370f
RS
207 if (n == 0)
208 {
576890b7
AD
209 for (r = 0; r < rulesetsize; ++r)
210 ruleset[r] = FDERIVES (start_symbol)[r];
d0fb370f
RS
211 }
212 else
213 {
576890b7
AD
214 for (r = 0; r < rulesetsize; ++r)
215 ruleset[r] = 0;
d0fb370f 216
576890b7
AD
217 for (c = 0; c < n; ++c)
218 if (ISVAR (ritem[core[c]]))
219 for (r = 0; r < rulesetsize; ++r)
220 ruleset[r] |= FDERIVES (ritem[core[c]])[r];
d0fb370f
RS
221 }
222
b2872512 223 nitemset = 0;
576890b7 224 c = 0;
cb581495 225 for (ruleno = 0; ruleno < nrules + 1; ++ruleno)
4b35e1c1
AD
226 if (BITISSET (ruleset, ruleno))
227 {
1a2b5d37 228 int itemno = rules[ruleno].rhs;
4b35e1c1
AD
229 while (c < n && core[c] < itemno)
230 {
b2872512
AD
231 itemset[nitemset] = core[c];
232 nitemset++;
4b35e1c1
AD
233 c++;
234 }
b2872512
AD
235 itemset[nitemset] = itemno;
236 nitemset++;
4b35e1c1 237 }
d0fb370f 238
576890b7
AD
239 while (c < n)
240 {
b2872512
AD
241 itemset[nitemset] = core[c];
242 nitemset++;
576890b7
AD
243 c++;
244 }
d0fb370f 245
9bfe901c 246 if (trace_flag)
b2872512 247 print_closure ("output", itemset, nitemset);
d0fb370f
RS
248}
249
250
251void
2fa6973e 252free_closure (void)
d0fb370f 253{
d7913476
AD
254 XFREE (itemset);
255 XFREE (ruleset);
03ec521c 256 XFREE (fderives);
d0fb370f 257}