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