]> git.saurik.com Git - bison.git/blame - src/LR0.c
* src/state.h (state_t): `solved_conflicts' is a new member.
[bison.git] / src / LR0.c
CommitLineData
40675e7c 1/* Generate the nondeterministic finite state machine for bison,
602bbf31 2 Copyright 1984, 1986, 1989, 2000, 2001, 2002 Free Software Foundation, Inc.
40675e7c 3
2fa6973e 4 This file is part of Bison, the GNU Compiler Compiler.
40675e7c 5
2fa6973e
AD
6 Bison is free software; you can redistribute it and/or modify
7 it 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.
40675e7c 10
2fa6973e
AD
11 Bison is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
40675e7c 15
2fa6973e
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
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
40675e7c
DM
20
21
22/* See comments in state.h for the data structures that represent it.
23 The entry point is generate_states. */
24
40675e7c 25#include "system.h"
602bbf31 26#include "bitset.h"
8b3df748 27#include "quotearg.h"
0e78e603 28#include "symtab.h"
5fbb0954 29#include "gram.h"
9bfe901c 30#include "getargs.h"
c87d4863 31#include "reader.h"
40675e7c
DM
32#include "gram.h"
33#include "state.h"
a0f6b076 34#include "complain.h"
2fa6973e 35#include "closure.h"
403b315b 36#include "LR0.h"
49701457 37#include "lalr.h"
630e182b 38#include "reduce.h"
40675e7c 39
643a5994 40unsigned int nstates = 0;
610ab194
AD
41/* Initialize the final state to -1, otherwise, it might be set to 0
42 by default, and since we don't compute the reductions of the final
43 state, we end up not computing the reductions of the initial state,
44 which is of course needed.
45
46 FINAL_STATE is properly set by new_state when it recognizes the
47 accessing symbol: EOF. */
48int final_state = -1;
6a164e0c 49static state_t *first_state = NULL;
40675e7c 50
f693ad14
AD
51static state_t *this_state = NULL;
52static state_t *last_state = NULL;
40675e7c
DM
53
54static int nshifts;
a49aecd5 55static symbol_number_t *shift_symbol = NULL;
40675e7c 56
342b8b6e
AD
57static short *redset = NULL;
58static short *shiftset = NULL;
40675e7c 59
62a3e4f0 60static item_number_t **kernel_base = NULL;
6255b435 61static int *kernel_size = NULL;
62a3e4f0 62static item_number_t *kernel_items = NULL;
40675e7c
DM
63
64/* hash table for states, to recognize equivalent ones. */
65
f693ad14
AD
66#define STATE_HASH_SIZE 1009
67static state_t **state_hash = NULL;
40675e7c 68
2fa6973e 69\f
4a120d45 70static void
d2729d44 71allocate_itemsets (void)
40675e7c 72{
b4c4ccc2 73 int i, r;
62a3e4f0 74 item_number_t *rhsp;
40675e7c 75
630e182b
AD
76 /* Count the number of occurrences of all the symbols in RITEMS.
77 Note that useless productions (hence useless nonterminals) are
78 browsed too, hence we need to allocate room for _all_ the
79 symbols. */
80 int count = 0;
81 short *symbol_count = XCALLOC (short, nsyms + nuseless_nonterminals);
40675e7c 82
b4c4ccc2
AD
83 for (r = 1; r < nrules + 1; ++r)
84 for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
c87d4863
AD
85 {
86 count++;
b4c4ccc2 87 symbol_count[*rhsp]++;
c87d4863 88 }
40675e7c 89
2fa6973e
AD
90 /* See comments before new_itemsets. All the vectors of items
91 live inside KERNEL_ITEMS. The number of active items after
40675e7c
DM
92 some symbol cannot be more than the number of times that symbol
93 appears as an item, which is symbol_count[symbol].
94 We allocate that much space for each symbol. */
95
62a3e4f0 96 kernel_base = XCALLOC (item_number_t *, nsyms);
342b8b6e 97 if (count)
62a3e4f0 98 kernel_items = XCALLOC (item_number_t, count);
40675e7c
DM
99
100 count = 0;
101 for (i = 0; i < nsyms; i++)
102 {
103 kernel_base[i] = kernel_items + count;
104 count += symbol_count[i];
105 }
106
630e182b 107 free (symbol_count);
0e41b407 108 kernel_size = XCALLOC (int, nsyms);
40675e7c
DM
109}
110
111
4a120d45 112static void
d2729d44 113allocate_storage (void)
40675e7c 114{
2fa6973e 115 allocate_itemsets ();
40675e7c 116
d7913476
AD
117 shiftset = XCALLOC (short, nsyms);
118 redset = XCALLOC (short, nrules + 1);
f693ad14 119 state_hash = XCALLOC (state_t *, STATE_HASH_SIZE);
a49aecd5 120 shift_symbol = XCALLOC (symbol_number_t, nsyms);
40675e7c
DM
121}
122
123
4a120d45 124static void
d2729d44 125free_storage (void)
40675e7c 126{
630e182b
AD
127 free (shift_symbol);
128 free (redset);
129 free (shiftset);
130 free (kernel_base);
131 free (kernel_size);
d7913476 132 XFREE (kernel_items);
f693ad14 133 free (state_hash);
40675e7c
DM
134}
135
136
137
40675e7c 138
2fa6973e
AD
139/*----------------------------------------------------------------.
140| Find which symbols can be shifted in the current state, and for |
141| each one record which items would be active after that shift. |
142| Uses the contents of itemset. |
143| |
144| shift_symbol is set to a vector of the symbols that can be |
145| shifted. For each symbol in the grammar, kernel_base[symbol] |
146| points to a vector of item numbers activated if that symbol is |
125ecb56 147| shifted, and kernel_size[symbol] is their numbers. |
2fa6973e 148`----------------------------------------------------------------*/
40675e7c 149
4a120d45 150static void
d2729d44 151new_itemsets (void)
40675e7c 152{
2fa6973e 153 int i;
2fa6973e 154
9bfe901c 155 if (trace_flag)
c87d4863
AD
156 fprintf (stderr, "Entering new_itemsets, state = %d\n",
157 this_state->number);
40675e7c
DM
158
159 for (i = 0; i < nsyms; i++)
125ecb56 160 kernel_size[i] = 0;
40675e7c 161
b2872512 162 nshifts = 0;
40675e7c 163
5123689b 164 for (i = 0; i < nritemset; ++i)
5fbb0954
AD
165 if (ritem[itemset[i]] >= 0)
166 {
a49aecd5
AD
167 symbol_number_t symbol
168 = item_number_as_symbol_number (ritem[itemset[i]]);
5fbb0954
AD
169 if (!kernel_size[symbol])
170 {
171 shift_symbol[nshifts] = symbol;
172 nshifts++;
173 }
174
175 kernel_base[symbol][kernel_size[symbol]] = itemset[i] + 1;
176 kernel_size[symbol]++;
177 }
40675e7c
DM
178}
179
180
181
2fa6973e
AD
182/*-----------------------------------------------------------------.
183| Subroutine of get_state. Create a new state for those items, if |
184| necessary. |
185`-----------------------------------------------------------------*/
40675e7c 186
f693ad14 187static state_t *
a49aecd5 188new_state (symbol_number_t symbol, size_t core_size, item_number_t *core)
40675e7c 189{
f693ad14 190 state_t *p;
40675e7c 191
9bfe901c 192 if (trace_flag)
c87d4863 193 fprintf (stderr, "Entering new_state, state = %d, symbol = %d (%s)\n",
8b3df748
AD
194 nstates, symbol, quotearg_style (escape_quoting_style,
195 symbols[symbol]->tag));
40675e7c 196
62a3e4f0
AD
197 if (nstates >= SHRT_MAX)
198 fatal (_("too many states (max %d)"), SHRT_MAX);
40675e7c 199
458be8e0 200 p = STATE_ALLOC (core_size);
2fa6973e
AD
201 p->accessing_symbol = symbol;
202 p->number = nstates;
b408954b 203 p->solved_conflicts = NULL;
2fa6973e 204
b408954b 205 p->nitems = core_size;
458be8e0 206 memcpy (p->items, core, core_size * sizeof (core[0]));
2fa6973e 207
643a5994
AD
208 /* If this is the eoftoken, and this is not the initial state, then
209 this is the final state. */
210 if (symbol == 0 && first_state)
211 final_state = p->number;
212
213 if (!first_state)
214 first_state = p;
215 if (last_state)
216 last_state->next = p;
2fa6973e 217 last_state = p;
40675e7c 218
643a5994 219 nstates++;
30171f79 220
2fa6973e
AD
221 return p;
222}
40675e7c 223
2fa6973e
AD
224
225/*--------------------------------------------------------------.
226| Find the state number for the state we would get to (from the |
227| current state) by shifting symbol. Create a new state if no |
97db7bd4 228| equivalent one exists already. Used by append_states. |
2fa6973e 229`--------------------------------------------------------------*/
40675e7c 230
4a120d45 231static int
a49aecd5 232get_state (symbol_number_t symbol, size_t core_size, item_number_t *core)
40675e7c 233{
2fa6973e 234 int key;
0c2d3f4c 235 size_t i;
f693ad14 236 state_t *sp;
40675e7c 237
9bfe901c 238 if (trace_flag)
c87d4863 239 fprintf (stderr, "Entering get_state, state = %d, symbol = %d (%s)\n",
8b3df748
AD
240 this_state->number, symbol, quotearg_style (escape_quoting_style,
241 symbols[symbol]->tag));
40675e7c 242
97db7bd4
AD
243 /* Add up the target state's active item numbers to get a hash key.
244 */
40675e7c 245 key = 0;
458be8e0
AD
246 for (i = 0; i < core_size; ++i)
247 key += core[i];
f693ad14
AD
248 key = key % STATE_HASH_SIZE;
249 sp = state_hash[key];
40675e7c
DM
250
251 if (sp)
252 {
97db7bd4 253 int found = 0;
40675e7c
DM
254 while (!found)
255 {
458be8e0 256 if (sp->nitems == core_size)
40675e7c
DM
257 {
258 found = 1;
458be8e0
AD
259 for (i = 0; i < core_size; ++i)
260 if (core[i] != sp->items[i])
97db7bd4 261 found = 0;
40675e7c
DM
262 }
263
264 if (!found)
265 {
266 if (sp->link)
267 {
268 sp = sp->link;
269 }
2fa6973e 270 else /* bucket exhausted and no match */
40675e7c 271 {
458be8e0 272 sp = sp->link = new_state (symbol, core_size, core);
40675e7c
DM
273 found = 1;
274 }
275 }
276 }
277 }
2fa6973e 278 else /* bucket is empty */
40675e7c 279 {
458be8e0 280 state_hash[key] = sp = new_state (symbol, core_size, core);
40675e7c
DM
281 }
282
c87d4863
AD
283 if (trace_flag)
284 fprintf (stderr, "Exiting get_state => %d\n", sp->number);
285
36281465 286 return sp->number;
40675e7c
DM
287}
288
2fa6973e
AD
289/*------------------------------------------------------------------.
290| Use the information computed by new_itemsets to find the state |
291| numbers reached by each shift transition from the current state. |
292| |
293| shiftset is set up as a vector of state numbers of those states. |
294`------------------------------------------------------------------*/
40675e7c 295
2fa6973e
AD
296static void
297append_states (void)
40675e7c 298{
2fa6973e
AD
299 int i;
300 int j;
a49aecd5 301 symbol_number_t symbol;
40675e7c 302
9bfe901c 303 if (trace_flag)
c87d4863
AD
304 fprintf (stderr, "Entering append_states, state = %d\n",
305 this_state->number);
40675e7c 306
2fa6973e 307 /* first sort shift_symbol into increasing order */
40675e7c 308
2fa6973e
AD
309 for (i = 1; i < nshifts; i++)
310 {
311 symbol = shift_symbol[i];
312 j = i;
313 while (j > 0 && shift_symbol[j - 1] > symbol)
314 {
315 shift_symbol[j] = shift_symbol[j - 1];
316 j--;
317 }
318 shift_symbol[j] = symbol;
319 }
40675e7c 320
2fa6973e 321 for (i = 0; i < nshifts; i++)
458be8e0
AD
322 {
323 symbol = shift_symbol[i];
324 shiftset[i] = get_state (symbol,
325 kernel_size[symbol], kernel_base[symbol]);
326 }
40675e7c
DM
327}
328
329
4a120d45 330static void
2fa6973e 331new_states (void)
40675e7c 332{
643a5994
AD
333 /* The 0 at the lhs is the index of the item of this initial rule. */
334 kernel_base[0][0] = 0;
335 kernel_size[0] = 1;
458be8e0 336 this_state = new_state (0, kernel_size[0], kernel_base[0]);
40675e7c
DM
337}
338
339
4a38e613
AD
340/*------------------------------------------------------------.
341| Save the NSHIFTS of SHIFTSET into the current linked list. |
342`------------------------------------------------------------*/
343
4a120d45 344static void
d2729d44 345save_shifts (void)
40675e7c 346{
4a38e613 347 shifts *p = shifts_new (nshifts);
62a3e4f0 348 memcpy (p->shifts, shiftset, nshifts * sizeof (shiftset[0]));
80e25d4d 349 this_state->shifts = p;
40675e7c
DM
350}
351
352
2fa6973e
AD
353/*----------------------------------------------------------------.
354| Find which rules can be used for reduction transitions from the |
355| current state and make a reductions structure for the state to |
356| record their rule numbers. |
357`----------------------------------------------------------------*/
358
4a120d45 359static void
2fa6973e 360save_reductions (void)
40675e7c 361{
30171f79 362 int count = 0;
fb908786 363 int i;
40675e7c 364
30171f79
AD
365 /* If this is the final state, we want it to have no reductions at
366 all, although it has one for `START_SYMBOL EOF .'. */
367 if (this_state->number == final_state)
368 return;
40675e7c 369
30171f79 370 /* Find and count the active items that represent ends of rules. */
5123689b 371 for (i = 0; i < nritemset; ++i)
2fa6973e 372 {
fb908786 373 int item = ritem[itemset[i]];
2fa6973e
AD
374 if (item < 0)
375 redset[count++] = -item;
376 }
40675e7c 377
2fa6973e 378 /* Make a reductions structure and copy the data into it. */
80dac38c 379 this_state->reductions = reductions_new (count);
62a3e4f0 380 memcpy (this_state->reductions->rules, redset, count * sizeof (redset[0]));
2fa6973e
AD
381}
382
383\f
82841af7 384/*---------------.
29e88316 385| Build STATES. |
82841af7 386`---------------*/
6a164e0c
AD
387
388static void
29e88316 389set_states (void)
6a164e0c 390{
2cec70b9 391 state_t *sp;
29e88316 392 states = XCALLOC (state_t *, nstates);
6a164e0c 393
2cec70b9
AD
394 for (sp = first_state; sp; sp = sp->next)
395 {
396 /* Pessimization, but simplification of the code: make sure all
80dac38c
AD
397 the states have a shifts, errs, and reductions, even if
398 reduced to 0. */
2cec70b9
AD
399 if (!sp->shifts)
400 sp->shifts = shifts_new (0);
401 if (!sp->errs)
402 sp->errs = errs_new (0);
80dac38c
AD
403 if (!sp->reductions)
404 sp->reductions = reductions_new (0);
2cec70b9 405
29e88316 406 states[sp->number] = sp;
2cec70b9 407 }
6a164e0c
AD
408}
409
2fa6973e
AD
410/*-------------------------------------------------------------------.
411| Compute the nondeterministic finite state machine (see state.h for |
412| details) from the grammar. |
413`-------------------------------------------------------------------*/
414
415void
416generate_states (void)
417{
418 allocate_storage ();
9e7f6bbd 419 new_closure (nritems);
2fa6973e
AD
420 new_states ();
421
422 while (this_state)
423 {
23cbcc6c
AD
424 if (trace_flag)
425 fprintf (stderr, "Processing state %d (reached by %s)\n",
ad949da9 426 this_state->number,
8b3df748
AD
427 quotearg_style (escape_quoting_style,
428 symbols[this_state->accessing_symbol]->tag));
2fa6973e
AD
429 /* Set up ruleset and itemset for the transitions out of this
430 state. ruleset gets a 1 bit for each rule that could reduce
431 now. itemset gets a vector of all the items that could be
432 accepted next. */
433 closure (this_state->items, this_state->nitems);
434 /* record the reductions allowed out of this state */
435 save_reductions ();
436 /* find the itemsets of the states that shifts can reach */
437 new_itemsets ();
438 /* find or create the core structures for those states */
439 append_states ();
440
441 /* create the shifts structures for the shifts to those states,
442 now that the state numbers transitioning to are known */
d954473d 443 save_shifts ();
2fa6973e
AD
444
445 /* states are queued when they are created; process them all */
446 this_state = this_state->next;
447 }
448
449 /* discard various storage */
450 free_closure ();
451 free_storage ();
452
29e88316
AD
453 /* Set up STATES. */
454 set_states ();
40675e7c 455}