]> git.saurik.com Git - bison.git/blame - src/LR0.c
(allocate_itemsets): Use xnmalloc, not xcalloc,
[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. */
108 int count = 0;
86a54ab1
PE
109 short int *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{
2fa6973e 181 int i;
2fa6973e 182
273a74fa 183 if (trace_flag & trace_automaton)
add6614e 184 fprintf (stderr, "Entering new_itemsets, state = %d\n", s->number);
40675e7c
DM
185
186 for (i = 0; i < nsyms; i++)
125ecb56 187 kernel_size[i] = 0;
40675e7c 188
b2872512 189 nshifts = 0;
40675e7c 190
5123689b 191 for (i = 0; i < nritemset; ++i)
5fbb0954
AD
192 if (ritem[itemset[i]] >= 0)
193 {
add6614e
PE
194 symbol_number sym = item_number_as_symbol_number (ritem[itemset[i]]);
195 if (!kernel_size[sym])
5fbb0954 196 {
add6614e 197 shift_symbol[nshifts] = sym;
5fbb0954
AD
198 nshifts++;
199 }
200
add6614e
PE
201 kernel_base[sym][kernel_size[sym]] = itemset[i] + 1;
202 kernel_size[sym]++;
5fbb0954 203 }
40675e7c
DM
204}
205
206
207
add6614e
PE
208/*--------------------------------------------------------------.
209| Find the state we would get to (from the current state) by |
210| shifting SYM. Create a new state if no equivalent one exists |
211| already. Used by append_states. |
212`--------------------------------------------------------------*/
40675e7c 213
add6614e
PE
214static state *
215get_state (symbol_number sym, size_t core_size, item_number *core)
40675e7c 216{
add6614e 217 state *sp;
40675e7c 218
273a74fa 219 if (trace_flag & trace_automaton)
427c0dda 220 fprintf (stderr, "Entering get_state, symbol = %d (%s)\n",
add6614e 221 sym, symbols[sym]->tag);
40675e7c 222
c7ca99d4
AD
223 sp = state_hash_lookup (core_size, core);
224 if (!sp)
add6614e 225 sp = state_list_append (sym, core_size, core);
40675e7c 226
273a74fa 227 if (trace_flag & trace_automaton)
427c0dda 228 fprintf (stderr, "Exiting get_state => %d\n", sp->number);
c87d4863 229
640748ee 230 return sp;
40675e7c
DM
231}
232
640748ee
AD
233/*---------------------------------------------------------------.
234| Use the information computed by new_itemsets to find the state |
add6614e 235| numbers reached by each shift transition from S. |
640748ee
AD
236| |
237| SHIFTSET is set up as a vector of those states. |
238`---------------------------------------------------------------*/
40675e7c 239
2fa6973e 240static void
add6614e 241append_states (state *s)
40675e7c 242{
2fa6973e 243 int i;
40675e7c 244
273a74fa 245 if (trace_flag & trace_automaton)
add6614e 246 fprintf (stderr, "Entering append_states, state = %d\n", s->number);
40675e7c 247
add6614e 248 /* First sort shift_symbol into increasing order. */
40675e7c 249
2fa6973e
AD
250 for (i = 1; i < nshifts; i++)
251 {
add6614e
PE
252 symbol_number sym = shift_symbol[i];
253 int j;
86a54ab1 254 for (j = i; 0 < j && sym < shift_symbol[j - 1]; j--)
add6614e
PE
255 shift_symbol[j] = shift_symbol[j - 1];
256 shift_symbol[j] = sym;
2fa6973e 257 }
40675e7c 258
2fa6973e 259 for (i = 0; i < nshifts; i++)
458be8e0 260 {
add6614e
PE
261 symbol_number sym = shift_symbol[i];
262 shiftset[i] = get_state (sym, kernel_size[sym], kernel_base[sym]);
458be8e0 263 }
40675e7c
DM
264}
265
266
2fa6973e
AD
267/*----------------------------------------------------------------.
268| Find which rules can be used for reduction transitions from the |
269| current state and make a reductions structure for the state to |
270| record their rule numbers. |
271`----------------------------------------------------------------*/
272
4a120d45 273static void
add6614e 274save_reductions (state *s)
40675e7c 275{
30171f79 276 int count = 0;
fb908786 277 int i;
40675e7c 278
30171f79 279 /* Find and count the active items that represent ends of rules. */
5123689b 280 for (i = 0; i < nritemset; ++i)
2fa6973e 281 {
fb908786 282 int item = ritem[itemset[i]];
2fa6973e 283 if (item < 0)
640748ee 284 redset[count++] = &rules[item_number_as_rule_number (item)];
2fa6973e 285 }
40675e7c 286
2fa6973e 287 /* Make a reductions structure and copy the data into it. */
add6614e 288 state_reductions_set (s, count, redset);
2fa6973e
AD
289}
290
291\f
82841af7 292/*---------------.
29e88316 293| Build STATES. |
82841af7 294`---------------*/
6a164e0c
AD
295
296static void
29e88316 297set_states (void)
6a164e0c 298{
86a54ab1 299 states = xcalloc (nstates, sizeof *states);
6a164e0c 300
32e1e0a4 301 while (first_state)
2cec70b9 302 {
add6614e 303 state_list *this = first_state;
32e1e0a4 304
2cec70b9 305 /* Pessimization, but simplification of the code: make sure all
8b752b00
AD
306 the states have valid transitions and reductions members,
307 even if reduced to 0. It is too soon for errs, which are
308 computed later, but set_conflicts. */
add6614e
PE
309 state *s = this->state;
310 if (!s->transitions)
311 state_transitions_set (s, 0, 0);
312 if (!s->reductions)
313 state_reductions_set (s, 0, 0);
32e1e0a4 314
add6614e 315 states[s->number] = s;
32e1e0a4
AD
316
317 first_state = this->next;
318 free (this);
2cec70b9 319 }
32e1e0a4
AD
320 first_state = NULL;
321 last_state = NULL;
6a164e0c
AD
322}
323
c7ca99d4 324
2fa6973e
AD
325/*-------------------------------------------------------------------.
326| Compute the nondeterministic finite state machine (see state.h for |
327| details) from the grammar. |
328`-------------------------------------------------------------------*/
329
330void
331generate_states (void)
332{
86a54ab1 333 item_number initial_core = 0;
add6614e 334 state_list *list = NULL;
2fa6973e 335 allocate_storage ();
9e7f6bbd 336 new_closure (nritems);
8b752b00
AD
337
338 /* Create the initial state. The 0 at the lhs is the index of the
339 item of this initial rule. */
86a54ab1 340 state_list_append (0, 1, &initial_core);
8b752b00 341
32e1e0a4 342 list = first_state;
2fa6973e 343
32e1e0a4 344 while (list)
2fa6973e 345 {
add6614e 346 state *s = list->state;
273a74fa 347 if (trace_flag & trace_automaton)
427c0dda 348 fprintf (stderr, "Processing state %d (reached by %s)\n",
add6614e
PE
349 s->number,
350 symbols[s->accessing_symbol]->tag);
2fa6973e
AD
351 /* Set up ruleset and itemset for the transitions out of this
352 state. ruleset gets a 1 bit for each rule that could reduce
353 now. itemset gets a vector of all the items that could be
354 accepted next. */
add6614e 355 closure (s->items, s->nitems);
32e1e0a4 356 /* Record the reductions allowed out of this state. */
add6614e 357 save_reductions (s);
32e1e0a4 358 /* Find the itemsets of the states that shifts can reach. */
add6614e 359 new_itemsets (s);
32e1e0a4 360 /* Find or create the core structures for those states. */
add6614e 361 append_states (s);
32e1e0a4
AD
362
363 /* Create the shifts structures for the shifts to those states,
364 now that the state numbers transitioning to are known. */
add6614e 365 state_transitions_set (s, nshifts, shiftset);
32e1e0a4 366
add6614e 367 /* states are queued when they are created; process them all.
32e1e0a4
AD
368 */
369 list = list->next;
2fa6973e
AD
370 }
371
372 /* discard various storage */
373 free_closure ();
374 free_storage ();
375
29e88316
AD
376 /* Set up STATES. */
377 set_states ();
40675e7c 378}