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