]> git.saurik.com Git - bison.git/blame - src/LR0.c
(new_itemsets): Use memset rather than zeroing by hand. This avoids a
[bison.git] / src / LR0.c
CommitLineData
1dd15b6e 1/* Generate the nondeterministic finite state machine for Bison.
6fc82eaf 2
779e7ceb
PE
3 Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2004 Free
4 Software Foundation, Inc.
40675e7c 5
2fa6973e 6 This file is part of Bison, the GNU Compiler Compiler.
40675e7c 7
2fa6973e
AD
8 Bison 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 2, or (at your option)
11 any later version.
40675e7c 12
2fa6973e
AD
13 Bison 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.
40675e7c 17
2fa6973e
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
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
40675e7c
DM
22
23
24/* See comments in state.h for the data structures that represent it.
25 The entry point is generate_states. */
26
40675e7c 27#include "system.h"
add6614e
PE
28
29#include <bitset.h>
30#include <quotearg.h>
31
32#include "LR0.h"
33#include "closure.h"
34#include "complain.h"
9bfe901c 35#include "getargs.h"
40675e7c 36#include "gram.h"
add6614e 37#include "gram.h"
49701457 38#include "lalr.h"
add6614e 39#include "reader.h"
630e182b 40#include "reduce.h"
add6614e
PE
41#include "state.h"
42#include "symtab.h"
40675e7c 43
add6614e 44typedef struct state_list
32e1e0a4 45{
add6614e
PE
46 struct state_list *next;
47 state *state;
48} state_list;
32e1e0a4 49
add6614e
PE
50static state_list *first_state = NULL;
51static state_list *last_state = NULL;
32e1e0a4 52
8b752b00
AD
53
54/*------------------------------------------------------------------.
55| A state was just discovered from another state. Queue it for |
56| later examination, in order to find its transitions. Return it. |
57`------------------------------------------------------------------*/
58
add6614e
PE
59static state *
60state_list_append (symbol_number sym, size_t core_size, item_number *core)
32e1e0a4 61{
86a54ab1 62 state_list *node = xmalloc (sizeof *node);
add6614e 63 state *s = state_new (sym, core_size, core);
8b752b00 64
273a74fa 65 if (trace_flag & trace_automaton)
427c0dda 66 fprintf (stderr, "state_list_append (state = %d, symbol = %d (%s))\n",
add6614e 67 nstates, sym, symbols[sym]->tag);
8b752b00 68
88bce5a2 69 /* If this is the endtoken, and this is not the initial state, then
8b752b00 70 this is the final state. */
add6614e
PE
71 if (sym == 0 && first_state)
72 final_state = s;
8b752b00 73
32e1e0a4 74 node->next = NULL;
add6614e 75 node->state = s;
40675e7c 76
32e1e0a4
AD
77 if (!first_state)
78 first_state = node;
79 if (last_state)
80 last_state->next = node;
81 last_state = node;
8b752b00 82
add6614e 83 return s;
32e1e0a4 84}
40675e7c
DM
85
86static int nshifts;
86a54ab1 87static symbol_number *shift_symbol;
40675e7c 88
86a54ab1
PE
89static rule **redset;
90static state **shiftset;
40675e7c 91
86a54ab1
PE
92static item_number **kernel_base;
93static int *kernel_size;
94static item_number *kernel_items;
40675e7c 95
2fa6973e 96\f
4a120d45 97static void
d2729d44 98allocate_itemsets (void)
40675e7c 99{
add6614e
PE
100 symbol_number i;
101 rule_number r;
102 item_number *rhsp;
40675e7c 103
630e182b
AD
104 /* Count the number of occurrences of all the symbols in RITEMS.
105 Note that useless productions (hence useless nonterminals) are
106 browsed too, hence we need to allocate room for _all_ the
107 symbols. */
f6fbd3da
PE
108 size_t count = 0;
109 size_t *symbol_count = xcalloc (nsyms + nuseless_nonterminals,
110 sizeof *symbol_count);
40675e7c 111
4b3d3a8e 112 for (r = 0; r < nrules; ++r)
b4c4ccc2 113 for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
c87d4863
AD
114 {
115 count++;
b4c4ccc2 116 symbol_count[*rhsp]++;
c87d4863 117 }
40675e7c 118
2fa6973e
AD
119 /* See comments before new_itemsets. All the vectors of items
120 live inside KERNEL_ITEMS. The number of active items after
add6614e
PE
121 some symbol S cannot be more than the number of times that S
122 appears as an item, which is SYMBOL_COUNT[S].
40675e7c
DM
123 We allocate that much space for each symbol. */
124
86a54ab1
PE
125 kernel_base = xnmalloc (nsyms, sizeof *kernel_base);
126 kernel_items = xnmalloc (count, sizeof *kernel_items);
40675e7c
DM
127
128 count = 0;
129 for (i = 0; i < nsyms; i++)
130 {
131 kernel_base[i] = kernel_items + count;
132 count += symbol_count[i];
133 }
134
630e182b 135 free (symbol_count);
86a54ab1 136 kernel_size = xnmalloc (nsyms, sizeof *kernel_size);
40675e7c
DM
137}
138
139
4a120d45 140static void
d2729d44 141allocate_storage (void)
40675e7c 142{
2fa6973e 143 allocate_itemsets ();
40675e7c 144
86a54ab1
PE
145 shiftset = xnmalloc (nsyms, sizeof *shiftset);
146 redset = xnmalloc (nrules, sizeof *redset);
c7ca99d4 147 state_hash_new ();
86a54ab1 148 shift_symbol = xnmalloc (nsyms, sizeof *shift_symbol);
40675e7c
DM
149}
150
151
4a120d45 152static void
d2729d44 153free_storage (void)
40675e7c 154{
630e182b
AD
155 free (shift_symbol);
156 free (redset);
157 free (shiftset);
158 free (kernel_base);
159 free (kernel_size);
afbb696d 160 free (kernel_items);
c7ca99d4 161 state_hash_free ();
40675e7c
DM
162}
163
164
165
40675e7c 166
32e1e0a4 167/*---------------------------------------------------------------.
add6614e 168| Find which symbols can be shifted in S, and for each one |
32e1e0a4
AD
169| record which items would be active after that shift. Uses the |
170| contents of itemset. |
171| |
172| shift_symbol is set to a vector of the symbols that can be |
173| shifted. For each symbol in the grammar, kernel_base[symbol] |
174| points to a vector of item numbers activated if that symbol is |
175| shifted, and kernel_size[symbol] is their numbers. |
176`---------------------------------------------------------------*/
40675e7c 177
4a120d45 178static void
add6614e 179new_itemsets (state *s)
40675e7c 180{
f6fbd3da 181 size_t i;
2fa6973e 182
273a74fa 183 if (trace_flag & trace_automaton)
add6614e 184 fprintf (stderr, "Entering new_itemsets, state = %d\n", s->number);
40675e7c 185
55a91a82 186 memset (kernel_size, 0, nsyms * sizeof *kernel_size);
40675e7c 187
b2872512 188 nshifts = 0;
40675e7c 189
5123689b 190 for (i = 0; i < nritemset; ++i)
5fbb0954
AD
191 if (ritem[itemset[i]] >= 0)
192 {
add6614e
PE
193 symbol_number sym = item_number_as_symbol_number (ritem[itemset[i]]);
194 if (!kernel_size[sym])
5fbb0954 195 {
add6614e 196 shift_symbol[nshifts] = sym;
5fbb0954
AD
197 nshifts++;
198 }
199
add6614e
PE
200 kernel_base[sym][kernel_size[sym]] = itemset[i] + 1;
201 kernel_size[sym]++;
5fbb0954 202 }
40675e7c
DM
203}
204
205
206
add6614e
PE
207/*--------------------------------------------------------------.
208| Find the state we would get to (from the current state) by |
209| shifting SYM. Create a new state if no equivalent one exists |
210| already. Used by append_states. |
211`--------------------------------------------------------------*/
40675e7c 212
add6614e
PE
213static state *
214get_state (symbol_number sym, size_t core_size, item_number *core)
40675e7c 215{
add6614e 216 state *sp;
40675e7c 217
273a74fa 218 if (trace_flag & trace_automaton)
427c0dda 219 fprintf (stderr, "Entering get_state, symbol = %d (%s)\n",
add6614e 220 sym, symbols[sym]->tag);
40675e7c 221
c7ca99d4
AD
222 sp = state_hash_lookup (core_size, core);
223 if (!sp)
add6614e 224 sp = state_list_append (sym, core_size, core);
40675e7c 225
273a74fa 226 if (trace_flag & trace_automaton)
427c0dda 227 fprintf (stderr, "Exiting get_state => %d\n", sp->number);
c87d4863 228
640748ee 229 return sp;
40675e7c
DM
230}
231
640748ee
AD
232/*---------------------------------------------------------------.
233| Use the information computed by new_itemsets to find the state |
add6614e 234| numbers reached by each shift transition from S. |
640748ee
AD
235| |
236| SHIFTSET is set up as a vector of those states. |
237`---------------------------------------------------------------*/
40675e7c 238
2fa6973e 239static void
add6614e 240append_states (state *s)
40675e7c 241{
2fa6973e 242 int i;
40675e7c 243
273a74fa 244 if (trace_flag & trace_automaton)
add6614e 245 fprintf (stderr, "Entering append_states, state = %d\n", s->number);
40675e7c 246
add6614e 247 /* First sort shift_symbol into increasing order. */
40675e7c 248
2fa6973e
AD
249 for (i = 1; i < nshifts; i++)
250 {
add6614e
PE
251 symbol_number sym = shift_symbol[i];
252 int j;
86a54ab1 253 for (j = i; 0 < j && sym < shift_symbol[j - 1]; j--)
add6614e
PE
254 shift_symbol[j] = shift_symbol[j - 1];
255 shift_symbol[j] = sym;
2fa6973e 256 }
40675e7c 257
2fa6973e 258 for (i = 0; i < nshifts; i++)
458be8e0 259 {
add6614e
PE
260 symbol_number sym = shift_symbol[i];
261 shiftset[i] = get_state (sym, kernel_size[sym], kernel_base[sym]);
458be8e0 262 }
40675e7c
DM
263}
264
265
2fa6973e
AD
266/*----------------------------------------------------------------.
267| Find which rules can be used for reduction transitions from the |
268| current state and make a reductions structure for the state to |
269| record their rule numbers. |
270`----------------------------------------------------------------*/
271
4a120d45 272static void
add6614e 273save_reductions (state *s)
40675e7c 274{
30171f79 275 int count = 0;
f6fbd3da 276 size_t i;
40675e7c 277
30171f79 278 /* Find and count the active items that represent ends of rules. */
5123689b 279 for (i = 0; i < nritemset; ++i)
2fa6973e 280 {
fb908786 281 int item = ritem[itemset[i]];
2fa6973e 282 if (item < 0)
640748ee 283 redset[count++] = &rules[item_number_as_rule_number (item)];
2fa6973e 284 }
40675e7c 285
2fa6973e 286 /* Make a reductions structure and copy the data into it. */
add6614e 287 state_reductions_set (s, count, redset);
2fa6973e
AD
288}
289
290\f
82841af7 291/*---------------.
29e88316 292| Build STATES. |
82841af7 293`---------------*/
6a164e0c
AD
294
295static void
29e88316 296set_states (void)
6a164e0c 297{
86a54ab1 298 states = xcalloc (nstates, sizeof *states);
6a164e0c 299
32e1e0a4 300 while (first_state)
2cec70b9 301 {
add6614e 302 state_list *this = first_state;
32e1e0a4 303
2cec70b9 304 /* Pessimization, but simplification of the code: make sure all
8b752b00
AD
305 the states have valid transitions and reductions members,
306 even if reduced to 0. It is too soon for errs, which are
307 computed later, but set_conflicts. */
add6614e
PE
308 state *s = this->state;
309 if (!s->transitions)
310 state_transitions_set (s, 0, 0);
311 if (!s->reductions)
312 state_reductions_set (s, 0, 0);
32e1e0a4 313
add6614e 314 states[s->number] = s;
32e1e0a4
AD
315
316 first_state = this->next;
317 free (this);
2cec70b9 318 }
32e1e0a4
AD
319 first_state = NULL;
320 last_state = NULL;
6a164e0c
AD
321}
322
c7ca99d4 323
2fa6973e
AD
324/*-------------------------------------------------------------------.
325| Compute the nondeterministic finite state machine (see state.h for |
326| details) from the grammar. |
327`-------------------------------------------------------------------*/
328
329void
330generate_states (void)
331{
86a54ab1 332 item_number initial_core = 0;
add6614e 333 state_list *list = NULL;
2fa6973e 334 allocate_storage ();
9e7f6bbd 335 new_closure (nritems);
8b752b00
AD
336
337 /* Create the initial state. The 0 at the lhs is the index of the
338 item of this initial rule. */
86a54ab1 339 state_list_append (0, 1, &initial_core);
8b752b00 340
32e1e0a4 341 list = first_state;
2fa6973e 342
32e1e0a4 343 while (list)
2fa6973e 344 {
add6614e 345 state *s = list->state;
273a74fa 346 if (trace_flag & trace_automaton)
427c0dda 347 fprintf (stderr, "Processing state %d (reached by %s)\n",
add6614e
PE
348 s->number,
349 symbols[s->accessing_symbol]->tag);
2fa6973e
AD
350 /* Set up ruleset and itemset for the transitions out of this
351 state. ruleset gets a 1 bit for each rule that could reduce
352 now. itemset gets a vector of all the items that could be
353 accepted next. */
add6614e 354 closure (s->items, s->nitems);
32e1e0a4 355 /* Record the reductions allowed out of this state. */
add6614e 356 save_reductions (s);
32e1e0a4 357 /* Find the itemsets of the states that shifts can reach. */
add6614e 358 new_itemsets (s);
32e1e0a4 359 /* Find or create the core structures for those states. */
add6614e 360 append_states (s);
32e1e0a4
AD
361
362 /* Create the shifts structures for the shifts to those states,
363 now that the state numbers transitioning to are known. */
add6614e 364 state_transitions_set (s, nshifts, shiftset);
32e1e0a4 365
add6614e 366 /* states are queued when they are created; process them all.
32e1e0a4
AD
367 */
368 list = list->next;
2fa6973e
AD
369 }
370
371 /* discard various storage */
372 free_closure ();
373 free_storage ();
374
29e88316
AD
375 /* Set up STATES. */
376 set_states ();
40675e7c 377}