]> git.saurik.com Git - bison.git/blame - src/state.c
Spell "boolean" as "Boolean". Reported by Akim Demaille.
[bison.git] / src / state.c
CommitLineData
ec14f0c8 1/* Type definitions for nondeterministic finite state machine for Bison.
03b9e273 2
75ad86ee 3 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software
c21493b8 4 Foundation, Inc.
5e893e1c
AD
5
6 This file is part of Bison, the GNU Compiler Compiler.
7
f16b0819 8 This program is free software: you can redistribute it and/or modify
5e893e1c 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.
5e893e1c 12
f16b0819 13 This program is distributed in the hope that it will be useful,
5e893e1c
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.
17
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/>. */
5e893e1c 20
2cec9080 21#include <config.h>
5e893e1c 22#include "system.h"
17ee7397
PE
23
24#include <hash.h>
25
df0e7316 26#include "complain.h"
62a3e4f0 27#include "gram.h"
5e893e1c
AD
28#include "state.h"
29
df0e7316
AD
30
31 /*-------------------.
32 | Shifts and Gotos. |
33 `-------------------*/
34
35
03b9e273
PE
36/*-----------------------------------------.
37| Create a new array of NUM shifts/gotos. |
38`-----------------------------------------*/
2cec70b9 39
17ee7397
PE
40static transitions *
41transitions_new (int num, state **the_states)
5e893e1c 42{
03b9e273
PE
43 size_t states_size = num * sizeof *the_states;
44 transitions *res = xmalloc (offsetof (transitions, states) + states_size);
ccaf65bc 45 res->num = num;
03b9e273 46 memcpy (res->states, the_states, states_size);
5e893e1c
AD
47 return res;
48}
2cec70b9
AD
49
50
a737b216
PE
51/*-------------------------------------------------------.
52| Return the state such that SHIFTS contain a shift/goto |
53| to it on SYM. Abort if none found. |
54`-------------------------------------------------------*/
24c7d800 55
17ee7397 56state *
a737b216 57transitions_to (transitions *shifts, symbol_number sym)
24c7d800
AD
58{
59 int j;
c21493b8
PE
60 for (j = 0; ; j++)
61 {
4f82b42a 62 aver (j < shifts->num);
c21493b8
PE
63 if (TRANSITION_SYMBOL (shifts, j) == sym)
64 return shifts->states[j];
65 }
24c7d800 66}
df0e7316
AD
67
68
69 /*--------------------.
70 | Error transitions. |
71 `--------------------*/
72
73
03b9e273
PE
74/*---------------------------------.
75| Create a new array of NUM errs. |
76`---------------------------------*/
2cec70b9 77
17ee7397
PE
78errs *
79errs_new (int num, symbol **tokens)
2cec70b9 80{
03b9e273
PE
81 size_t symbols_size = num * sizeof *tokens;
82 errs *res = xmalloc (offsetof (errs, symbols) + symbols_size);
8b752b00 83 res->num = num;
03b9e273 84 memcpy (res->symbols, tokens, symbols_size);
2cec70b9
AD
85 return res;
86}
80dac38c 87
df0e7316
AD
88
89
90
91 /*-------------.
92 | Reductions. |
93 `-------------*/
94
95
03b9e273
PE
96/*---------------------------------------.
97| Create a new array of NUM reductions. |
98`---------------------------------------*/
80dac38c 99
17ee7397
PE
100static reductions *
101reductions_new (int num, rule **reds)
80dac38c 102{
03b9e273
PE
103 size_t rules_size = num * sizeof *reds;
104 reductions *res = xmalloc (offsetof (reductions, rules) + rules_size);
8b752b00 105 res->num = num;
742e4900 106 res->lookahead_tokens = NULL;
03b9e273 107 memcpy (res->rules, reds, rules_size);
80dac38c
AD
108 return res;
109}
10e5b8bd
AD
110
111
df0e7316
AD
112
113 /*---------.
114 | States. |
115 `---------*/
116
117
17ee7397 118state_number nstates = 0;
df0e7316 119/* FINAL_STATE is properly set by new_state when it recognizes its
88bce5a2 120 accessing symbol: $end. */
17ee7397 121state *final_state = NULL;
df0e7316 122
c7ca99d4 123
8b752b00
AD
124/*------------------------------------------------------------------.
125| Create a new state with ACCESSING_SYMBOL, for those items. Store |
126| it in the state hash table. |
127`------------------------------------------------------------------*/
df0e7316 128
17ee7397
PE
129state *
130state_new (symbol_number accessing_symbol,
03b9e273 131 size_t nitems, item_number *core)
df0e7316 132{
17ee7397 133 state *res;
03b9e273 134 size_t items_size = nitems * sizeof *core;
df0e7316 135
4f82b42a 136 aver (nstates < STATE_NUMBER_MAXIMUM);
df0e7316 137
03b9e273
PE
138 res = xmalloc (offsetof (state, items) + items_size);
139 res->number = nstates++;
df0e7316 140 res->accessing_symbol = accessing_symbol;
03b9e273
PE
141 res->transitions = NULL;
142 res->reductions = NULL;
143 res->errs = NULL;
144 res->consistent = 0;
df0e7316
AD
145 res->solved_conflicts = NULL;
146
03b9e273
PE
147 res->nitems = nitems;
148 memcpy (res->items, core, items_size);
df0e7316 149
8b752b00
AD
150 state_hash_insert (res);
151
df0e7316
AD
152 return res;
153}
154
155
17ee7397
PE
156/*---------.
157| Free S. |
158`---------*/
8b752b00
AD
159
160static void
17ee7397 161state_free (state *s)
8b752b00 162{
17ee7397
PE
163 free (s->transitions);
164 free (s->reductions);
165 free (s->errs);
166 free (s);
8b752b00
AD
167}
168
169
17ee7397
PE
170/*---------------------------.
171| Set the transitions of S. |
172`---------------------------*/
32e1e0a4
AD
173
174void
17ee7397 175state_transitions_set (state *s, int num, state **trans)
32e1e0a4 176{
4f82b42a 177 aver (!s->transitions);
17ee7397 178 s->transitions = transitions_new (num, trans);
32e1e0a4
AD
179}
180
181
17ee7397
PE
182/*--------------------------.
183| Set the reductions of S. |
184`--------------------------*/
8a731ca8
AD
185
186void
17ee7397 187state_reductions_set (state *s, int num, rule **reds)
8a731ca8 188{
4f82b42a 189 aver (!s->reductions);
17ee7397 190 s->reductions = reductions_new (num, reds);
8b752b00
AD
191}
192
193
cd08e51e 194int
17ee7397 195state_reduction_find (state *s, rule *r)
cd08e51e
AD
196{
197 int i;
17ee7397 198 reductions *reds = s->reductions;
cd08e51e 199 for (i = 0; i < reds->num; ++i)
17ee7397 200 if (reds->rules[i] == r)
cd08e51e
AD
201 return i;
202 return -1;
203}
204
205
17ee7397
PE
206/*--------------------.
207| Set the errs of S. |
208`--------------------*/
8b752b00
AD
209
210void
17ee7397 211state_errs_set (state *s, int num, symbol **tokens)
8b752b00 212{
4f82b42a 213 aver (!s->errs);
17ee7397 214 s->errs = errs_new (num, tokens);
8a731ca8
AD
215}
216
217
32e1e0a4 218
742e4900
JD
219/*--------------------------------------------------.
220| Print on OUT all the lookahead tokens such that S |
221| wants to reduce R. |
222`--------------------------------------------------*/
10e5b8bd
AD
223
224void
742e4900 225state_rule_lookahead_tokens_print (state *s, rule *r, FILE *out)
10e5b8bd 226{
cd08e51e 227 /* Find the reduction we are handling. */
17ee7397
PE
228 reductions *reds = s->reductions;
229 int red = state_reduction_find (s, r);
10e5b8bd
AD
230
231 /* Print them if there are. */
742e4900 232 if (reds->lookahead_tokens && red != -1)
10e5b8bd 233 {
cd08e51e
AD
234 bitset_iterator biter;
235 int k;
d0829076 236 char const *sep = "";
2f4f028d 237 fprintf (out, " [");
742e4900 238 BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0)
d0829076
PE
239 {
240 fprintf (out, "%s%s", sep, symbols[k]->tag);
241 sep = ", ";
242 }
2f4f028d 243 fprintf (out, "]");
10e5b8bd
AD
244 }
245}
c7ca99d4
AD
246
247
36b5e963 248/*---------------------.
c7ca99d4 249| A state hash table. |
36b5e963 250`---------------------*/
c7ca99d4
AD
251
252/* Initial capacity of states hash table. */
253#define HT_INITIAL_CAPACITY 257
254
255static struct hash_table *state_table = NULL;
256
257/* Two states are equal if they have the same core items. */
03b9e273 258static inline bool
17ee7397 259state_compare (state const *s1, state const *s2)
c7ca99d4 260{
f6fbd3da 261 size_t i;
c7ca99d4
AD
262
263 if (s1->nitems != s2->nitems)
8307162d 264 return false;
c7ca99d4
AD
265
266 for (i = 0; i < s1->nitems; ++i)
267 if (s1->items[i] != s2->items[i])
8307162d 268 return false;
c7ca99d4 269
8307162d 270 return true;
c7ca99d4
AD
271}
272
03b9e273
PE
273static bool
274state_comparator (void const *s1, void const *s2)
275{
276 return state_compare (s1, s2);
277}
278
233a88ad
PE
279static inline size_t
280state_hash (state const *s, size_t tablesize)
c7ca99d4
AD
281{
282 /* Add up the state's item numbers to get a hash key. */
233a88ad 283 size_t key = 0;
f6fbd3da 284 size_t i;
17ee7397
PE
285 for (i = 0; i < s->nitems; ++i)
286 key += s->items[i];
c7ca99d4
AD
287 return key % tablesize;
288}
289
233a88ad
PE
290static size_t
291state_hasher (void const *s, size_t tablesize)
03b9e273
PE
292{
293 return state_hash (s, tablesize);
294}
295
c7ca99d4
AD
296
297/*-------------------------------.
298| Create the states hash table. |
299`-------------------------------*/
300
301void
302state_hash_new (void)
303{
304 state_table = hash_initialize (HT_INITIAL_CAPACITY,
305 NULL,
03b9e273
PE
306 state_hasher,
307 state_comparator,
308 NULL);
c7ca99d4
AD
309}
310
311
312/*---------------------------------------------.
313| Free the states hash table, not the states. |
314`---------------------------------------------*/
315
316void
317state_hash_free (void)
318{
319 hash_free (state_table);
320}
321
322
17ee7397
PE
323/*-----------------------------------.
324| Insert S in the state hash table. |
325`-----------------------------------*/
c7ca99d4
AD
326
327void
17ee7397 328state_hash_insert (state *s)
c7ca99d4 329{
17ee7397 330 hash_insert (state_table, s);
c7ca99d4
AD
331}
332
333
334/*------------------------------------------------------------------.
335| Find the state associated to the CORE, and return it. If it does |
336| not exist yet, return NULL. |
337`------------------------------------------------------------------*/
338
17ee7397 339state *
03b9e273 340state_hash_lookup (size_t nitems, item_number *core)
c7ca99d4 341{
03b9e273
PE
342 size_t items_size = nitems * sizeof *core;
343 state *probe = xmalloc (offsetof (state, items) + items_size);
17ee7397 344 state *entry;
c7ca99d4 345
03b9e273
PE
346 probe->nitems = nitems;
347 memcpy (probe->items, core, items_size);
c7ca99d4
AD
348 entry = hash_lookup (state_table, probe);
349 free (probe);
350 return entry;
351}
352
5967f0cf 353
14462c2b
JD
354/*--------------------------------------------------------.
355| Record S and all states reachable from S in REACHABLE. |
356`--------------------------------------------------------*/
5967f0cf
JD
357
358static void
14462c2b 359state_record_reachable_states (state *s, bitset reachable)
5967f0cf 360{
14462c2b 361 if (bitset_test (reachable, s->number))
5967f0cf 362 return;
14462c2b
JD
363 bitset_set (reachable, s->number);
364 {
365 int i;
366 for (i = 0; i < s->transitions->num; ++i)
367 if (!TRANSITION_IS_DISABLED (s->transitions, i))
368 state_record_reachable_states (s->transitions->states[i], reachable);
369 }
5967f0cf
JD
370}
371
372void
373state_remove_unreachable_states (state_number old_to_new[])
374{
375 state_number nstates_reachable = 0;
14462c2b
JD
376 bitset reachable = bitset_create (nstates, BITSET_FIXED);
377 state_record_reachable_states (states[0], reachable);
378 {
379 state_number i;
380 for (i = 0; i < nstates; ++i)
381 {
382 if (bitset_test (reachable, states[i]->number))
383 {
384 states[nstates_reachable] = states[i];
385 states[nstates_reachable]->number = nstates_reachable;
386 old_to_new[i] = nstates_reachable++;
387 }
388 else
389 {
390 state_free (states[i]);
391 old_to_new[i] = nstates;
392 }
393 }
394 }
5967f0cf 395 nstates = nstates_reachable;
14462c2b 396 bitset_free (reachable);
5967f0cf
JD
397}
398
c7ca99d4 399/* All the decorated states, indexed by the state number. */
17ee7397 400state **states = NULL;
c7ca99d4
AD
401
402
403/*----------------------.
404| Free all the states. |
405`----------------------*/
406
407void
408states_free (void)
409{
17ee7397 410 state_number i;
c7ca99d4 411 for (i = 0; i < nstates; ++i)
8b752b00
AD
412 state_free (states[i]);
413 free (states);
c7ca99d4 414}