]> git.saurik.com Git - bison.git/blame - src/closure.c
Use unlocked I/O for a minor performance improvement on hosts like
[bison.git] / src / closure.c
CommitLineData
c7bd07f7
PE
1/* Closures for Bison
2
da2a7671
PE
3 Copyright (C) 1984, 1989, 2000, 2001, 2002, 2004 Free Software
4 Foundation, Inc.
d0fb370f 5
8dc26b76 6 This file is part of Bison, the GNU Compiler Compiler.
d0fb370f 7
8dc26b76
AD
8 Bison is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
d0fb370f 12
8dc26b76
AD
13 Bison is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
d0fb370f 17
8dc26b76
AD
18 You should have received a copy of the GNU General Public License
19 along with Bison; see the file COPYING. If not, write to the Free
0fb669f9
PE
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
d0fb370f 22
d0fb370f 23#include "system.h"
c7bd07f7
PE
24
25#include <bitset.h>
26#include <bitsetv-print.h>
27#include <bitsetv.h>
28#include <quotearg.h>
29
30#include "closure.h"
31#include "derives.h"
9bfe901c 32#include "getargs.h"
d0fb370f 33#include "gram.h"
2c5f66ed 34#include "reader.h"
c7bd07f7 35#include "symtab.h"
d0fb370f 36
b2872512 37/* NITEMSET is the size of the array ITEMSET. */
c7bd07f7 38item_number *itemset;
f6fbd3da 39size_t nritemset;
fb908786 40
dfdb1797 41static bitset ruleset;
d0fb370f
RS
42
43/* internal data. See comments before set_fderives and set_firsts. */
914feea9
AD
44static bitsetv fderives = NULL;
45static bitsetv firsts = NULL;
d0fb370f 46
03ec521c 47/* Retrieve the FDERIVES/FIRSTS sets of the nonterminals numbered Var. */
7086e707 48#define FDERIVES(Var) fderives[(Var) - ntokens]
d8a0245c 49#define FIRSTS(Var) firsts[(Var) - ntokens]
2fa6973e 50\f
d0fb370f 51
2fa6973e
AD
52/*-----------------.
53| Debugging code. |
54`-----------------*/
d0fb370f 55
2fa6973e 56static void
c7bd07f7 57print_closure (char const *title, item_number *array, size_t size)
2fa6973e 58{
23cbcc6c 59 size_t i;
427c0dda 60 fprintf (stderr, "Closure: %s\n", title);
23cbcc6c
AD
61 for (i = 0; i < size; ++i)
62 {
c7bd07f7 63 item_number *rp;
23cbcc6c 64 fprintf (stderr, " %2d: .", array[i]);
75142d45 65 for (rp = &ritem[array[i]]; *rp >= 0; ++rp)
97650f4e 66 fprintf (stderr, " %s", symbols[*rp]->tag);
427c0dda 67 fprintf (stderr, " (rule %d)\n", -*rp - 1);
23cbcc6c
AD
68 }
69 fputs ("\n\n", stderr);
2fa6973e
AD
70}
71
72
73static void
74print_firsts (void)
d0fb370f 75{
c7bd07f7 76 symbol_number i, j;
2fa6973e 77
fb9c0b33 78 fputs ("FIRSTS\n", stderr);
2fa6973e
AD
79 for (i = ntokens; i < nsyms; i++)
80 {
613f5e1a 81 bitset_iterator iter;
97650f4e 82 fprintf (stderr, "\t%s firsts\n", symbols[i]->tag);
613f5e1a
AD
83 BITSET_FOR_EACH (iter, FIRSTS (i), j, 0)
84 {
85 fprintf (stderr, "\t\t%s\n",
86 symbols[j + ntokens]->tag);
87 }
2fa6973e 88 }
fb9c0b33 89 fputs ("\n\n", stderr);
d0fb370f
RS
90}
91
92
2fa6973e
AD
93static void
94print_fderives (void)
95{
9222837b 96 int i;
c7bd07f7 97 rule_number r;
2fa6973e 98
fb9c0b33 99 fputs ("FDERIVES\n", stderr);
2fa6973e
AD
100 for (i = ntokens; i < nsyms; i++)
101 {
613f5e1a 102 bitset_iterator iter;
97650f4e 103 fprintf (stderr, "\t%s derives\n", symbols[i]->tag);
613f5e1a
AD
104 BITSET_FOR_EACH (iter, FDERIVES (i), r, 0)
105 {
e1a4f3a4
AD
106 fprintf (stderr, "\t\t%3d ", r);
107 rule_rhs_print (&rules[r], stderr);
613f5e1a 108 }
2fa6973e 109 }
fb9c0b33 110 fputs ("\n\n", stderr);
2fa6973e 111}
2fa6973e 112\f
d8a0245c
AD
113/*------------------------------------------------------------------.
114| Set FIRSTS to be an NVARS array of NVARS bitsets indicating which |
115| items can represent the beginning of the input corresponding to |
116| which other items. |
117| |
118| For example, if some rule expands symbol 5 into the sequence of |
119| symbols 8 3 20, the symbol 8 can be the beginning of the data for |
120| symbol 5, so the bit [8 - ntokens] in first[5 - ntokens] (= FIRST |
121| (5)) is set. |
122`------------------------------------------------------------------*/
2fa6973e
AD
123
124static void
125set_firsts (void)
126{
c7bd07f7 127 symbol_number i, j;
2fa6973e 128
914feea9
AD
129 firsts = bitsetv_create (nvars, nvars, BITSET_FIXED);
130
2fa6973e 131 for (i = ntokens; i < nsyms; i++)
bb7c2bc6 132 for (j = 0; derives[i - ntokens][j]; ++j)
914feea9 133 {
bb7c2bc6 134 item_number sym = derives[i - ntokens][j]->rhs[0];
c7bd07f7
PE
135 if (ISVAR (sym))
136 bitset_set (FIRSTS (i), sym - ntokens);
914feea9 137 }
2fa6973e 138
273a74fa 139 if (trace_flag & trace_sets)
427c0dda 140 bitsetv_matrix_dump (stderr, "RTC: Firsts Input", firsts);
65ccf9fc 141 bitsetv_reflexive_transitive_closure (firsts);
273a74fa 142 if (trace_flag & trace_sets)
427c0dda 143 bitsetv_matrix_dump (stderr, "RTC: Firsts Output", firsts);
2fa6973e 144
273a74fa 145 if (trace_flag & trace_sets)
9bfe901c 146 print_firsts ();
2fa6973e
AD
147}
148
149/*-------------------------------------------------------------------.
150| Set FDERIVES to an NVARS by NRULES matrix of bits indicating which |
151| rules can help derive the beginning of the data for each |
152| nonterminal. |
153| |
154| For example, if symbol 5 can be derived as the sequence of symbols |
155| 8 3 20, and one of the rules for deriving symbol 8 is rule 4, then |
156| the [5 - NTOKENS, 4] bit in FDERIVES is set. |
157`-------------------------------------------------------------------*/
d0fb370f 158
4a120d45 159static void
d2729d44 160set_fderives (void)
d0fb370f 161{
c7bd07f7
PE
162 symbol_number i, j;
163 rule_number k;
d0fb370f 164
4b3d3a8e 165 fderives = bitsetv_create (nvars, nrules, BITSET_FIXED);
d0fb370f 166
2fa6973e 167 set_firsts ();
d0fb370f 168
1cbcf2e7
AD
169 for (i = ntokens; i < nsyms; ++i)
170 for (j = ntokens; j < nsyms; ++j)
d8a0245c 171 if (bitset_test (FIRSTS (i), j - ntokens))
bb7c2bc6
PE
172 for (k = 0; derives[j - ntokens][k]; ++k)
173 bitset_set (FDERIVES (i), derives[j - ntokens][k]->number);
d0fb370f 174
273a74fa 175 if (trace_flag & trace_sets)
9bfe901c 176 print_fderives ();
d0fb370f 177
914feea9 178 bitsetv_free (firsts);
d0fb370f 179}
1565b720 180
2fa6973e 181\f
d0fb370f 182
2fa6973e 183void
da2a7671 184new_closure (unsigned int n)
d0fb370f 185{
da2a7671 186 itemset = xnmalloc (n, sizeof *itemset);
d0fb370f 187
4b3d3a8e 188 ruleset = bitset_create (nrules, BITSET_FIXED);
d0fb370f 189
2fa6973e 190 set_fderives ();
d0fb370f
RS
191}
192
193
2fa6973e 194
d0fb370f 195void
f6fbd3da 196closure (item_number *core, size_t n)
d0fb370f 197{
576890b7 198 /* Index over CORE. */
f6fbd3da 199 size_t c;
576890b7 200
d2b04478 201 /* A bit index over RULESET. */
c7bd07f7 202 rule_number ruleno;
d0fb370f 203
613f5e1a
AD
204 bitset_iterator iter;
205
273a74fa 206 if (trace_flag & trace_sets)
427c0dda 207 print_closure ("input", core, n);
c87d4863 208
643a5994 209 bitset_zero (ruleset);
d0fb370f 210
643a5994
AD
211 for (c = 0; c < n; ++c)
212 if (ISVAR (ritem[core[c]]))
213 bitset_or (ruleset, ruleset, FDERIVES (ritem[core[c]]));
d0fb370f 214
5123689b 215 nritemset = 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 {
222 itemset[nritemset] = core[c];
223 nritemset++;
224 c++;
225 }
226 itemset[nritemset] = itemno;
227 nritemset++;
228 };
d0fb370f 229
576890b7
AD
230 while (c < n)
231 {
5123689b
AD
232 itemset[nritemset] = core[c];
233 nritemset++;
576890b7
AD
234 c++;
235 }
d0fb370f 236
273a74fa 237 if (trace_flag & trace_sets)
427c0dda 238 print_closure ("output", itemset, nritemset);
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}