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