]> git.saurik.com Git - bison.git/blame - src/LR0.c
* src/scan-gram.l (code_start): Always initialize it when entering
[bison.git] / src / LR0.c
CommitLineData
1dd15b6e 1/* Generate the nondeterministic finite state machine for Bison.
6fc82eaf
PE
2
3 Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002 Free Software
4 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;
1dd15b6e 109 short *symbol_count = CALLOC (symbol_count, nsyms + nuseless_nonterminals);
40675e7c 110
4b3d3a8e 111 for (r = 0; r < nrules; ++r)
b4c4ccc2 112 for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp)
c87d4863
AD
113 {
114 count++;
b4c4ccc2 115 symbol_count[*rhsp]++;
c87d4863 116 }
40675e7c 117
2fa6973e
AD
118 /* See comments before new_itemsets. All the vectors of items
119 live inside KERNEL_ITEMS. The number of active items after
add6614e
PE
120 some symbol S cannot be more than the number of times that S
121 appears as an item, which is SYMBOL_COUNT[S].
40675e7c
DM
122 We allocate that much space for each symbol. */
123
1dd15b6e 124 CALLOC (kernel_base, nsyms);
342b8b6e 125 if (count)
1dd15b6e 126 CALLOC (kernel_items, count);
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);
1dd15b6e 136 CALLOC (kernel_size, nsyms);
40675e7c
DM
137}
138
139
4a120d45 140static void
d2729d44 141allocate_storage (void)
40675e7c 142{
2fa6973e 143 allocate_itemsets ();
40675e7c 144
1dd15b6e
PE
145 CALLOC (shiftset, nsyms);
146 CALLOC (redset, nrules);
c7ca99d4 147 state_hash_new ();
1dd15b6e 148 CALLOC (shift_symbol, nsyms);
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);
6c5f863a 160 XFREE (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;
254 for (j = i; 0 < j && sym < shift_symbol [j - 1]; j--)
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{
1dd15b6e 299 CALLOC (states, nstates);
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{
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. */
339 kernel_base[0][0] = 0;
340 kernel_size[0] = 1;
341 state_list_append (0, kernel_size[0], kernel_base[0]);
342
32e1e0a4 343 list = first_state;
2fa6973e 344
32e1e0a4 345 while (list)
2fa6973e 346 {
add6614e 347 state *s = list->state;
273a74fa 348 if (trace_flag & trace_automaton)
427c0dda 349 fprintf (stderr, "Processing state %d (reached by %s)\n",
add6614e
PE
350 s->number,
351 symbols[s->accessing_symbol]->tag);
2fa6973e
AD
352 /* Set up ruleset and itemset for the transitions out of this
353 state. ruleset gets a 1 bit for each rule that could reduce
354 now. itemset gets a vector of all the items that could be
355 accepted next. */
add6614e 356 closure (s->items, s->nitems);
32e1e0a4 357 /* Record the reductions allowed out of this state. */
add6614e 358 save_reductions (s);
32e1e0a4 359 /* Find the itemsets of the states that shifts can reach. */
add6614e 360 new_itemsets (s);
32e1e0a4 361 /* Find or create the core structures for those states. */
add6614e 362 append_states (s);
32e1e0a4
AD
363
364 /* Create the shifts structures for the shifts to those states,
365 now that the state numbers transitioning to are known. */
add6614e 366 state_transitions_set (s, nshifts, shiftset);
32e1e0a4 367
add6614e 368 /* states are queued when they are created; process them all.
32e1e0a4
AD
369 */
370 list = list->next;
2fa6973e
AD
371 }
372
373 /* discard various storage */
374 free_closure ();
375 free_storage ();
376
29e88316
AD
377 /* Set up STATES. */
378 set_states ();
40675e7c 379}