]> git.saurik.com Git - bison.git/blame - src/LR0.c
* data/lalr1.cc: Adjust the indentation of the labels.
[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{
1dd15b6e 62 state_list *node = MALLOC (node, 1);
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;
add6614e 87static symbol_number *shift_symbol = NULL;
40675e7c 88
add6614e
PE
89static rule **redset = NULL;
90static state **shiftset = NULL;
40675e7c 91
add6614e 92static item_number **kernel_base = NULL;
6255b435 93static int *kernel_size = NULL;
add6614e 94static item_number *kernel_items = NULL;
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;
779e7ceb
PE
109 short int *symbol_count = CALLOC (symbol_count,
110 nsyms + nuseless_nonterminals);
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
1dd15b6e 125 CALLOC (kernel_base, nsyms);
342b8b6e 126 if (count)
1dd15b6e 127 CALLOC (kernel_items, count);
40675e7c
DM
128
129 count = 0;
130 for (i = 0; i < nsyms; i++)
131 {
132 kernel_base[i] = kernel_items + count;
133 count += symbol_count[i];
134 }
135
630e182b 136 free (symbol_count);
1dd15b6e 137 CALLOC (kernel_size, nsyms);
40675e7c
DM
138}
139
140
4a120d45 141static void
d2729d44 142allocate_storage (void)
40675e7c 143{
2fa6973e 144 allocate_itemsets ();
40675e7c 145
1dd15b6e
PE
146 CALLOC (shiftset, nsyms);
147 CALLOC (redset, nrules);
c7ca99d4 148 state_hash_new ();
1dd15b6e 149 CALLOC (shift_symbol, nsyms);
40675e7c
DM
150}
151
152
4a120d45 153static void
d2729d44 154free_storage (void)
40675e7c 155{
630e182b
AD
156 free (shift_symbol);
157 free (redset);
158 free (shiftset);
159 free (kernel_base);
160 free (kernel_size);
6c5f863a 161 XFREE (kernel_items);
c7ca99d4 162 state_hash_free ();
40675e7c
DM
163}
164
165
166
40675e7c 167
32e1e0a4 168/*---------------------------------------------------------------.
add6614e 169| Find which symbols can be shifted in S, and for each one |
32e1e0a4
AD
170| record which items would be active after that shift. Uses the |
171| contents of itemset. |
172| |
173| shift_symbol is set to a vector of the symbols that can be |
174| shifted. For each symbol in the grammar, kernel_base[symbol] |
175| points to a vector of item numbers activated if that symbol is |
176| shifted, and kernel_size[symbol] is their numbers. |
177`---------------------------------------------------------------*/
40675e7c 178
4a120d45 179static void
add6614e 180new_itemsets (state *s)
40675e7c 181{
2fa6973e 182 int i;
2fa6973e 183
273a74fa 184 if (trace_flag & trace_automaton)
add6614e 185 fprintf (stderr, "Entering new_itemsets, state = %d\n", s->number);
40675e7c
DM
186
187 for (i = 0; i < nsyms; i++)
125ecb56 188 kernel_size[i] = 0;
40675e7c 189
b2872512 190 nshifts = 0;
40675e7c 191
5123689b 192 for (i = 0; i < nritemset; ++i)
5fbb0954
AD
193 if (ritem[itemset[i]] >= 0)
194 {
add6614e
PE
195 symbol_number sym = item_number_as_symbol_number (ritem[itemset[i]]);
196 if (!kernel_size[sym])
5fbb0954 197 {
add6614e 198 shift_symbol[nshifts] = sym;
5fbb0954
AD
199 nshifts++;
200 }
201
add6614e
PE
202 kernel_base[sym][kernel_size[sym]] = itemset[i] + 1;
203 kernel_size[sym]++;
5fbb0954 204 }
40675e7c
DM
205}
206
207
208
add6614e
PE
209/*--------------------------------------------------------------.
210| Find the state we would get to (from the current state) by |
211| shifting SYM. Create a new state if no equivalent one exists |
212| already. Used by append_states. |
213`--------------------------------------------------------------*/
40675e7c 214
add6614e
PE
215static state *
216get_state (symbol_number sym, size_t core_size, item_number *core)
40675e7c 217{
add6614e 218 state *sp;
40675e7c 219
273a74fa 220 if (trace_flag & trace_automaton)
427c0dda 221 fprintf (stderr, "Entering get_state, symbol = %d (%s)\n",
add6614e 222 sym, symbols[sym]->tag);
40675e7c 223
c7ca99d4
AD
224 sp = state_hash_lookup (core_size, core);
225 if (!sp)
add6614e 226 sp = state_list_append (sym, core_size, core);
40675e7c 227
273a74fa 228 if (trace_flag & trace_automaton)
427c0dda 229 fprintf (stderr, "Exiting get_state => %d\n", sp->number);
c87d4863 230
640748ee 231 return sp;
40675e7c
DM
232}
233
640748ee
AD
234/*---------------------------------------------------------------.
235| Use the information computed by new_itemsets to find the state |
add6614e 236| numbers reached by each shift transition from S. |
640748ee
AD
237| |
238| SHIFTSET is set up as a vector of those states. |
239`---------------------------------------------------------------*/
40675e7c 240
2fa6973e 241static void
add6614e 242append_states (state *s)
40675e7c 243{
2fa6973e 244 int i;
40675e7c 245
273a74fa 246 if (trace_flag & trace_automaton)
add6614e 247 fprintf (stderr, "Entering append_states, state = %d\n", s->number);
40675e7c 248
add6614e 249 /* First sort shift_symbol into increasing order. */
40675e7c 250
2fa6973e
AD
251 for (i = 1; i < nshifts; i++)
252 {
add6614e
PE
253 symbol_number sym = shift_symbol[i];
254 int j;
255 for (j = i; 0 < j && sym < shift_symbol [j - 1]; j--)
256 shift_symbol[j] = shift_symbol[j - 1];
257 shift_symbol[j] = sym;
2fa6973e 258 }
40675e7c 259
2fa6973e 260 for (i = 0; i < nshifts; i++)
458be8e0 261 {
add6614e
PE
262 symbol_number sym = shift_symbol[i];
263 shiftset[i] = get_state (sym, kernel_size[sym], kernel_base[sym]);
458be8e0 264 }
40675e7c
DM
265}
266
267
2fa6973e
AD
268/*----------------------------------------------------------------.
269| Find which rules can be used for reduction transitions from the |
270| current state and make a reductions structure for the state to |
271| record their rule numbers. |
272`----------------------------------------------------------------*/
273
4a120d45 274static void
add6614e 275save_reductions (state *s)
40675e7c 276{
30171f79 277 int count = 0;
fb908786 278 int i;
40675e7c 279
30171f79 280 /* Find and count the active items that represent ends of rules. */
5123689b 281 for (i = 0; i < nritemset; ++i)
2fa6973e 282 {
fb908786 283 int item = ritem[itemset[i]];
2fa6973e 284 if (item < 0)
640748ee 285 redset[count++] = &rules[item_number_as_rule_number (item)];
2fa6973e 286 }
40675e7c 287
2fa6973e 288 /* Make a reductions structure and copy the data into it. */
add6614e 289 state_reductions_set (s, count, redset);
2fa6973e
AD
290}
291
292\f
82841af7 293/*---------------.
29e88316 294| Build STATES. |
82841af7 295`---------------*/
6a164e0c
AD
296
297static void
29e88316 298set_states (void)
6a164e0c 299{
1dd15b6e 300 CALLOC (states, nstates);
6a164e0c 301
32e1e0a4 302 while (first_state)
2cec70b9 303 {
add6614e 304 state_list *this = first_state;
32e1e0a4 305
2cec70b9 306 /* Pessimization, but simplification of the code: make sure all
8b752b00
AD
307 the states have valid transitions and reductions members,
308 even if reduced to 0. It is too soon for errs, which are
309 computed later, but set_conflicts. */
add6614e
PE
310 state *s = this->state;
311 if (!s->transitions)
312 state_transitions_set (s, 0, 0);
313 if (!s->reductions)
314 state_reductions_set (s, 0, 0);
32e1e0a4 315
add6614e 316 states[s->number] = s;
32e1e0a4
AD
317
318 first_state = this->next;
319 free (this);
2cec70b9 320 }
32e1e0a4
AD
321 first_state = NULL;
322 last_state = NULL;
6a164e0c
AD
323}
324
c7ca99d4 325
2fa6973e
AD
326/*-------------------------------------------------------------------.
327| Compute the nondeterministic finite state machine (see state.h for |
328| details) from the grammar. |
329`-------------------------------------------------------------------*/
330
331void
332generate_states (void)
333{
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. */
340 kernel_base[0][0] = 0;
341 kernel_size[0] = 1;
342 state_list_append (0, kernel_size[0], kernel_base[0]);
343
32e1e0a4 344 list = first_state;
2fa6973e 345
32e1e0a4 346 while (list)
2fa6973e 347 {
add6614e 348 state *s = list->state;
273a74fa 349 if (trace_flag & trace_automaton)
427c0dda 350 fprintf (stderr, "Processing state %d (reached by %s)\n",
add6614e
PE
351 s->number,
352 symbols[s->accessing_symbol]->tag);
2fa6973e
AD
353 /* Set up ruleset and itemset for the transitions out of this
354 state. ruleset gets a 1 bit for each rule that could reduce
355 now. itemset gets a vector of all the items that could be
356 accepted next. */
add6614e 357 closure (s->items, s->nitems);
32e1e0a4 358 /* Record the reductions allowed out of this state. */
add6614e 359 save_reductions (s);
32e1e0a4 360 /* Find the itemsets of the states that shifts can reach. */
add6614e 361 new_itemsets (s);
32e1e0a4 362 /* Find or create the core structures for those states. */
add6614e 363 append_states (s);
32e1e0a4
AD
364
365 /* Create the shifts structures for the shifts to those states,
366 now that the state numbers transitioning to are known. */
add6614e 367 state_transitions_set (s, nshifts, shiftset);
32e1e0a4 368
add6614e 369 /* states are queued when they are created; process them all.
32e1e0a4
AD
370 */
371 list = list->next;
2fa6973e
AD
372 }
373
374 /* discard various storage */
375 free_closure ();
376 free_storage ();
377
29e88316
AD
378 /* Set up STATES. */
379 set_states ();
40675e7c 380}