]> git.saurik.com Git - bison.git/blame - src/closure.c
cpp: simplify the Flex version checking macro
[bison.git] / src / closure.c
CommitLineData
c7bd07f7
PE
1/* Closures for Bison
2
c932d613 3 Copyright (C) 1984, 1989, 2000-2002, 2004-2005, 2007, 2009-2012 Free
ea0a7676 4 Software Foundation, Inc.
d0fb370f 5
8dc26b76 6 This file is part of Bison, the GNU Compiler Compiler.
d0fb370f 7
f16b0819
PE
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.
d0fb370f 12
f16b0819
PE
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.
d0fb370f 17
8dc26b76 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/>. */
d0fb370f 20
2cec9080 21#include <config.h>
d0fb370f 22#include "system.h"
c7bd07f7
PE
23
24#include <bitset.h>
25#include <bitsetv-print.h>
26#include <bitsetv.h>
c7bd07f7
PE
27
28#include "closure.h"
29#include "derives.h"
9bfe901c 30#include "getargs.h"
d0fb370f 31#include "gram.h"
2c5f66ed 32#include "reader.h"
c7bd07f7 33#include "symtab.h"
d0fb370f 34
b2872512 35/* NITEMSET is the size of the array ITEMSET. */
c7bd07f7 36item_number *itemset;
b09f4f48 37size_t nitemset;
fb908786 38
dfdb1797 39static bitset ruleset;
d0fb370f
RS
40
41/* internal data. See comments before set_fderives and set_firsts. */
914feea9
AD
42static bitsetv fderives = NULL;
43static bitsetv firsts = NULL;
d0fb370f 44
03ec521c 45/* Retrieve the FDERIVES/FIRSTS sets of the nonterminals numbered Var. */
7086e707 46#define FDERIVES(Var) fderives[(Var) - ntokens]
d8a0245c 47#define FIRSTS(Var) firsts[(Var) - ntokens]
2fa6973e 48\f
d0fb370f 49
2fa6973e
AD
50/*-----------------.
51| Debugging code. |
52`-----------------*/
d0fb370f 53
2fa6973e 54static void
c7bd07f7 55print_closure (char const *title, item_number *array, size_t size)
2fa6973e 56{
23cbcc6c 57 size_t i;
427c0dda 58 fprintf (stderr, "Closure: %s\n", title);
23cbcc6c
AD
59 for (i = 0; i < size; ++i)
60 {
c7bd07f7 61 item_number *rp;
23cbcc6c 62 fprintf (stderr, " %2d: .", array[i]);
75142d45 63 for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
97650f4e 64 fprintf (stderr, " %s", symbols[*rp]->tag);
427c0dda 65 fprintf (stderr, " (rule %d)\n", -*rp - 1);
23cbcc6c
AD
66 }
67 fputs ("\n\n", stderr);
2fa6973e
AD
68}
69
70
71static void
72print_firsts (void)
d0fb370f 73{
c7bd07f7 74 symbol_number i, j;
2fa6973e 75
2f4f028d 76 fprintf (stderr, "FIRSTS\n");
2fa6973e
AD
77 for (i = ntokens; i < nsyms; i++)
78 {
613f5e1a 79 bitset_iterator iter;
97650f4e 80 fprintf (stderr, "\t%s firsts\n", symbols[i]->tag);
613f5e1a
AD
81 BITSET_FOR_EACH (iter, FIRSTS (i), j, 0)
82 {
83 fprintf (stderr, "\t\t%s\n",
84 symbols[j + ntokens]->tag);
85 }
2fa6973e 86 }
2f4f028d 87 fprintf (stderr, "\n\n");
d0fb370f
RS
88}
89
90
2fa6973e
AD
91static void
92print_fderives (void)
93{
9222837b 94 int i;
c7bd07f7 95 rule_number r;
2fa6973e 96
2f4f028d 97 fprintf (stderr, "FDERIVES\n");
2fa6973e
AD
98 for (i = ntokens; i < nsyms; i++)
99 {
613f5e1a 100 bitset_iterator iter;
97650f4e 101 fprintf (stderr, "\t%s derives\n", symbols[i]->tag);
613f5e1a
AD
102 BITSET_FOR_EACH (iter, FDERIVES (i), r, 0)
103 {
e1a4f3a4
AD
104 fprintf (stderr, "\t\t%3d ", r);
105 rule_rhs_print (&rules[r], stderr);
613f5e1a 106 }
2fa6973e 107 }
2f4f028d 108 fprintf (stderr, "\n\n");
2fa6973e 109}
2fa6973e 110\f
d8a0245c
AD
111/*------------------------------------------------------------------.
112| Set FIRSTS to be an NVARS array of NVARS bitsets indicating which |
113| items can represent the beginning of the input corresponding to |
114| which other items. |
115| |
116| For example, if some rule expands symbol 5 into the sequence of |
117| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
118| symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
119| (5)) is set. |
120`------------------------------------------------------------------*/
2fa6973e
AD
121
122static void
123set_firsts (void)
124{
c7bd07f7 125 symbol_number i, j;
2fa6973e 126
914feea9
AD
127 firsts = bitsetv_create (nvars, nvars, BITSET_FIXED);
128
2fa6973e 129 for (i = ntokens; i < nsyms; i++)
bb7c2bc6 130 for (j = 0; derives[i - ntokens][j]; ++j)
914feea9 131 {
bb7c2bc6 132 item_number sym = derives[i - ntokens][j]->rhs[0];
c7bd07f7
PE
133 if (ISVAR (sym))
134 bitset_set (FIRSTS (i), sym - ntokens);
914feea9 135 }
2fa6973e 136
273a74fa 137 if (trace_flag & trace_sets)
427c0dda 138 bitsetv_matrix_dump (stderr, "RTC: Firsts Input", firsts);
65ccf9fc 139 bitsetv_reflexive_transitive_closure (firsts);
273a74fa 140 if (trace_flag & trace_sets)
427c0dda 141 bitsetv_matrix_dump (stderr, "RTC: Firsts Output", firsts);
2fa6973e 142
273a74fa 143 if (trace_flag & trace_sets)
9bfe901c 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{
c7bd07f7
PE
160 symbol_number i, j;
161 rule_number k;
d0fb370f 162
4b3d3a8e 163 fderives = bitsetv_create (nvars, nrules, BITSET_FIXED);
d0fb370f 164
2fa6973e 165 set_firsts ();
d0fb370f 166
1cbcf2e7
AD
167 for (i = ntokens; i < nsyms; ++i)
168 for (j = ntokens; j < nsyms; ++j)
d8a0245c 169 if (bitset_test (FIRSTS (i), j - ntokens))
bb7c2bc6
PE
170 for (k = 0; derives[j - ntokens][k]; ++k)
171 bitset_set (FDERIVES (i), derives[j - ntokens][k]->number);
d0fb370f 172
273a74fa 173 if (trace_flag & trace_sets)
9bfe901c 174 print_fderives ();
d0fb370f 175
914feea9 176 bitsetv_free (firsts);
d0fb370f 177}
1565b720 178
2fa6973e 179\f
d0fb370f 180
2fa6973e 181void
da2a7671 182new_closure (unsigned int n)
d0fb370f 183{
da2a7671 184 itemset = xnmalloc (n, sizeof *itemset);
d0fb370f 185
4b3d3a8e 186 ruleset = bitset_create (nrules, BITSET_FIXED);
d0fb370f 187
2fa6973e 188 set_fderives ();
d0fb370f
RS
189}
190
191
2fa6973e 192
d0fb370f 193void
f6fbd3da 194closure (item_number *core, size_t n)
d0fb370f 195{
576890b7 196 /* Index over CORE. */
f6fbd3da 197 size_t c;
576890b7 198
d2b04478 199 /* A bit index over RULESET. */
c7bd07f7 200 rule_number ruleno;
d0fb370f 201
613f5e1a
AD
202 bitset_iterator iter;
203
273a74fa 204 if (trace_flag & trace_sets)
427c0dda 205 print_closure ("input", core, n);
c87d4863 206
643a5994 207 bitset_zero (ruleset);
d0fb370f 208
643a5994
AD
209 for (c = 0; c < n; ++c)
210 if (ISVAR (ritem[core[c]]))
211 bitset_or (ruleset, ruleset, FDERIVES (ritem[core[c]]));
d0fb370f 212
6ce2d93a 213 /* core is sorted on item index in ritem, which is sorted on rule number.
71b61d4d 214 Compute itemset with the same sort. */
b09f4f48 215 nitemset = 0;
576890b7 216 c = 0;
613f5e1a
AD
217 BITSET_FOR_EACH (iter, ruleset, ruleno, 0)
218 {
c7bd07f7 219 item_number itemno = rules[ruleno].rhs - ritem;
613f5e1a
AD
220 while (c < n && core[c] < itemno)
221 {
b09f4f48
JD
222 itemset[nitemset] = core[c];
223 nitemset++;
613f5e1a
AD
224 c++;
225 }
b09f4f48
JD
226 itemset[nitemset] = itemno;
227 nitemset++;
613f5e1a 228 };
d0fb370f 229
576890b7
AD
230 while (c < n)
231 {
b09f4f48
JD
232 itemset[nitemset] = core[c];
233 nitemset++;
576890b7
AD
234 c++;
235 }
d0fb370f 236
273a74fa 237 if (trace_flag & trace_sets)
b09f4f48 238 print_closure ("output", itemset, nitemset);
d0fb370f
RS
239}
240
241
242void
2fa6973e 243free_closure (void)
d0fb370f 244{
afbb696d 245 free (itemset);
dfdb1797 246 bitset_free (ruleset);
914feea9 247 bitsetv_free (fderives);
d0fb370f 248}