]> git.saurik.com Git - bison.git/blame - src/LR0.c
More.
[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"
9bfe901c 29#include "getargs.h"
c87d4863 30#include "reader.h"
40675e7c
DM
31#include "gram.h"
32#include "state.h"
a0f6b076 33#include "complain.h"
2fa6973e 34#include "closure.h"
403b315b 35#include "LR0.h"
49701457 36#include "lalr.h"
630e182b 37#include "reduce.h"
40675e7c 38
643a5994 39unsigned int nstates = 0;
610ab194
AD
40/* Initialize the final state to -1, otherwise, it might be set to 0
41 by default, and since we don't compute the reductions of the final
42 state, we end up not computing the reductions of the initial state,
43 which is of course needed.
44
45 FINAL_STATE is properly set by new_state when it recognizes the
46 accessing symbol: EOF. */
47int final_state = -1;
6a164e0c 48static state_t *first_state = NULL;
40675e7c 49
f693ad14
AD
50static state_t *this_state = NULL;
51static state_t *last_state = NULL;
40675e7c
DM
52
53static int nshifts;
342b8b6e 54static short *shift_symbol = NULL;
40675e7c 55
342b8b6e
AD
56static short *redset = NULL;
57static short *shiftset = NULL;
40675e7c 58
62a3e4f0 59static item_number_t **kernel_base = NULL;
6255b435 60static int *kernel_size = NULL;
62a3e4f0 61static item_number_t *kernel_items = NULL;
40675e7c
DM
62
63/* hash table for states, to recognize equivalent ones. */
64
f693ad14
AD
65#define STATE_HASH_SIZE 1009
66static state_t **state_hash = NULL;
40675e7c 67
2fa6973e 68\f
4a120d45 69static void
d2729d44 70allocate_itemsets (void)
40675e7c 71{
b4c4ccc2 72 int i, r;
62a3e4f0 73 item_number_t *rhsp;
40675e7c 74
630e182b
AD
75 /* Count the number of occurrences of all the symbols in RITEMS.
76 Note that useless productions (hence useless nonterminals) are
77 browsed too, hence we need to allocate room for _all_ the
78 symbols. */
79 int count = 0;
80 short *symbol_count = XCALLOC (short, nsyms + nuseless_nonterminals);
40675e7c 81
b4c4ccc2
AD
82 for (r = 1; r < nrules + 1; ++r)
83 for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
c87d4863
AD
84 {
85 count++;
b4c4ccc2 86 symbol_count[*rhsp]++;
c87d4863 87 }
40675e7c 88
2fa6973e
AD
89 /* See comments before new_itemsets. All the vectors of items
90 live inside KERNEL_ITEMS. The number of active items after
40675e7c
DM
91 some symbol cannot be more than the number of times that symbol
92 appears as an item, which is symbol_count[symbol].
93 We allocate that much space for each symbol. */
94
62a3e4f0 95 kernel_base = XCALLOC (item_number_t *, nsyms);
342b8b6e 96 if (count)
62a3e4f0 97 kernel_items = XCALLOC (item_number_t, count);
40675e7c
DM
98
99 count = 0;
100 for (i = 0; i < nsyms; i++)
101 {
102 kernel_base[i] = kernel_items + count;
103 count += symbol_count[i];
104 }
105
630e182b 106 free (symbol_count);
0e41b407 107 kernel_size = XCALLOC (int, nsyms);
40675e7c
DM
108}
109
110
4a120d45 111static void
d2729d44 112allocate_storage (void)
40675e7c 113{
2fa6973e 114 allocate_itemsets ();
40675e7c 115
d7913476
AD
116 shiftset = XCALLOC (short, nsyms);
117 redset = XCALLOC (short, nrules + 1);
f693ad14 118 state_hash = XCALLOC (state_t *, STATE_HASH_SIZE);
375d5806 119 shift_symbol = XCALLOC (short, nsyms);
40675e7c
DM
120}
121
122
4a120d45 123static void
d2729d44 124free_storage (void)
40675e7c 125{
630e182b
AD
126 free (shift_symbol);
127 free (redset);
128 free (shiftset);
129 free (kernel_base);
130 free (kernel_size);
d7913476 131 XFREE (kernel_items);
f693ad14 132 free (state_hash);
40675e7c
DM
133}
134
135
136
40675e7c 137
2fa6973e
AD
138/*----------------------------------------------------------------.
139| Find which symbols can be shifted in the current state, and for |
140| each one record which items would be active after that shift. |
141| Uses the contents of itemset. |
142| |
143| shift_symbol is set to a vector of the symbols that can be |
144| shifted. For each symbol in the grammar, kernel_base[symbol] |
145| points to a vector of item numbers activated if that symbol is |
125ecb56 146| shifted, and kernel_size[symbol] is their numbers. |
2fa6973e 147`----------------------------------------------------------------*/
40675e7c 148
4a120d45 149static void
d2729d44 150new_itemsets (void)
40675e7c 151{
2fa6973e 152 int i;
2fa6973e 153
9bfe901c 154 if (trace_flag)
c87d4863
AD
155 fprintf (stderr, "Entering new_itemsets, state = %d\n",
156 this_state->number);
40675e7c
DM
157
158 for (i = 0; i < nsyms; i++)
125ecb56 159 kernel_size[i] = 0;
40675e7c 160
b2872512 161 nshifts = 0;
40675e7c 162
5123689b 163 for (i = 0; i < nritemset; ++i)
40675e7c 164 {
97db7bd4 165 int symbol = ritem[itemset[i]];
75142d45 166 if (symbol >= 0)
40675e7c 167 {
125ecb56 168 if (!kernel_size[symbol])
40675e7c 169 {
b2872512
AD
170 shift_symbol[nshifts] = symbol;
171 nshifts++;
40675e7c
DM
172 }
173
125ecb56
AD
174 kernel_base[symbol][kernel_size[symbol]] = itemset[i] + 1;
175 kernel_size[symbol]++;
40675e7c
DM
176 }
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 *
2fa6973e 188new_state (int symbol)
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
f693ad14 200 p = STATE_ALLOC (kernel_size[symbol]);
2fa6973e
AD
201 p->accessing_symbol = symbol;
202 p->number = nstates;
125ecb56 203 p->nitems = kernel_size[symbol];
2fa6973e 204
62a3e4f0
AD
205 memcpy (p->items, kernel_base[symbol],
206 kernel_size[symbol] * sizeof (kernel_base[symbol][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
d2729d44 232get_state (int symbol)
40675e7c 233{
2fa6973e 234 int key;
97db7bd4 235 int 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;
125ecb56 246 for (i = 0; i < kernel_size[symbol]; ++i)
97db7bd4 247 key += kernel_base[symbol][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 {
125ecb56 256 if (sp->nitems == kernel_size[symbol])
40675e7c
DM
257 {
258 found = 1;
125ecb56 259 for (i = 0; i < kernel_size[symbol]; ++i)
97db7bd4
AD
260 if (kernel_base[symbol][i] != sp->items[i])
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 {
2fa6973e 272 sp = sp->link = new_state (symbol);
40675e7c
DM
273 found = 1;
274 }
275 }
276 }
277 }
2fa6973e 278 else /* bucket is empty */
40675e7c 279 {
f693ad14 280 state_hash[key] = sp = new_state (symbol);
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;
301 int 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++)
97db7bd4 322 shiftset[i] = get_state (shift_symbol[i]);
40675e7c
DM
323}
324
325
4a120d45 326static void
2fa6973e 327new_states (void)
40675e7c 328{
643a5994
AD
329 /* The 0 at the lhs is the index of the item of this initial rule. */
330 kernel_base[0][0] = 0;
331 kernel_size[0] = 1;
332 this_state = new_state (0);
40675e7c
DM
333}
334
335
4a38e613
AD
336/*------------------------------------------------------------.
337| Save the NSHIFTS of SHIFTSET into the current linked list. |
338`------------------------------------------------------------*/
339
4a120d45 340static void
d2729d44 341save_shifts (void)
40675e7c 342{
4a38e613 343 shifts *p = shifts_new (nshifts);
62a3e4f0 344 memcpy (p->shifts, shiftset, nshifts * sizeof (shiftset[0]));
80e25d4d 345 this_state->shifts = p;
40675e7c
DM
346}
347
348
2fa6973e
AD
349/*----------------------------------------------------------------.
350| Find which rules can be used for reduction transitions from the |
351| current state and make a reductions structure for the state to |
352| record their rule numbers. |
353`----------------------------------------------------------------*/
354
4a120d45 355static void
2fa6973e 356save_reductions (void)
40675e7c 357{
30171f79 358 int count = 0;
fb908786 359 int i;
40675e7c 360
30171f79
AD
361 /* If this is the final state, we want it to have no reductions at
362 all, although it has one for `START_SYMBOL EOF .'. */
363 if (this_state->number == final_state)
364 return;
40675e7c 365
30171f79 366 /* Find and count the active items that represent ends of rules. */
5123689b 367 for (i = 0; i < nritemset; ++i)
2fa6973e 368 {
fb908786 369 int item = ritem[itemset[i]];
2fa6973e
AD
370 if (item < 0)
371 redset[count++] = -item;
372 }
40675e7c 373
2fa6973e 374 /* Make a reductions structure and copy the data into it. */
80dac38c 375 this_state->reductions = reductions_new (count);
62a3e4f0 376 memcpy (this_state->reductions->rules, redset, count * sizeof (redset[0]));
2fa6973e
AD
377}
378
379\f
82841af7 380/*---------------.
29e88316 381| Build STATES. |
82841af7 382`---------------*/
6a164e0c
AD
383
384static void
29e88316 385set_states (void)
6a164e0c 386{
2cec70b9 387 state_t *sp;
29e88316 388 states = XCALLOC (state_t *, nstates);
6a164e0c 389
2cec70b9
AD
390 for (sp = first_state; sp; sp = sp->next)
391 {
392 /* Pessimization, but simplification of the code: make sure all
80dac38c
AD
393 the states have a shifts, errs, and reductions, even if
394 reduced to 0. */
2cec70b9
AD
395 if (!sp->shifts)
396 sp->shifts = shifts_new (0);
397 if (!sp->errs)
398 sp->errs = errs_new (0);
80dac38c
AD
399 if (!sp->reductions)
400 sp->reductions = reductions_new (0);
2cec70b9 401
29e88316 402 states[sp->number] = sp;
2cec70b9 403 }
6a164e0c
AD
404}
405
2fa6973e
AD
406/*-------------------------------------------------------------------.
407| Compute the nondeterministic finite state machine (see state.h for |
408| details) from the grammar. |
409`-------------------------------------------------------------------*/
410
411void
412generate_states (void)
413{
414 allocate_storage ();
9e7f6bbd 415 new_closure (nritems);
2fa6973e
AD
416 new_states ();
417
418 while (this_state)
419 {
23cbcc6c
AD
420 if (trace_flag)
421 fprintf (stderr, "Processing state %d (reached by %s)\n",
ad949da9 422 this_state->number,
8b3df748
AD
423 quotearg_style (escape_quoting_style,
424 symbols[this_state->accessing_symbol]->tag));
2fa6973e
AD
425 /* Set up ruleset and itemset for the transitions out of this
426 state. ruleset gets a 1 bit for each rule that could reduce
427 now. itemset gets a vector of all the items that could be
428 accepted next. */
429 closure (this_state->items, this_state->nitems);
430 /* record the reductions allowed out of this state */
431 save_reductions ();
432 /* find the itemsets of the states that shifts can reach */
433 new_itemsets ();
434 /* find or create the core structures for those states */
435 append_states ();
436
437 /* create the shifts structures for the shifts to those states,
438 now that the state numbers transitioning to are known */
d954473d 439 save_shifts ();
2fa6973e
AD
440
441 /* states are queued when they are created; process them all */
442 this_state = this_state->next;
443 }
444
445 /* discard various storage */
446 free_closure ();
447 free_storage ();
448
29e88316
AD
449 /* Set up STATES. */
450 set_states ();
40675e7c 451}