]> git.saurik.com Git - bison.git/blame - src/LR0.c
Remove the so called hairy (semantic) parsers.
[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;
5fbb0954 55static token_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);
5fbb0954 120 shift_symbol = XCALLOC (token_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 {
167 token_number_t symbol
168 = item_number_as_token_number (ritem[itemset[i]]);
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 *
5fbb0954 188new_state (token_number_t 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
5fbb0954 232get_state (token_number_t 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;
5fbb0954 301 token_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++)
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}