]> git.saurik.com Git - bison.git/blame - src/state.c
lalr1.cc: check (and fix) %initial-action exception safety
[bison.git] / src / state.c
CommitLineData
1c4ad777 1/* Type definitions for the finite state machine for Bison.
03b9e273 2
c932d613 3 Copyright (C) 2001-2007, 2009-2012 Free Software Foundation, Inc.
5e893e1c
AD
4
5 This file is part of Bison, the GNU Compiler Compiler.
6
f16b0819 7 This program is free software: you can redistribute it and/or modify
5e893e1c 8 it under the terms of the GNU General Public License as published by
f16b0819
PE
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
5e893e1c 11
f16b0819 12 This program is distributed in the hope that it will be useful,
5e893e1c
AD
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
f16b0819 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
5e893e1c 19
2cec9080 20#include <config.h>
5e893e1c 21#include "system.h"
17ee7397
PE
22
23#include <hash.h>
24
df0e7316 25#include "complain.h"
62a3e4f0 26#include "gram.h"
5e893e1c 27#include "state.h"
41d7a5f2 28#include "print-xml.h"
5e893e1c 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;
f805dfcb 144 res->state_list = NULL;
03b9e273 145 res->consistent = 0;
df0e7316 146 res->solved_conflicts = NULL;
41d7a5f2 147 res->solved_conflicts_xml = NULL;
df0e7316 148
03b9e273
PE
149 res->nitems = nitems;
150 memcpy (res->items, core, items_size);
df0e7316 151
8b752b00
AD
152 state_hash_insert (res);
153
df0e7316
AD
154 return res;
155}
156
f805dfcb
JD
157state *
158state_new_isocore (state const *s)
159{
160 state *res;
161 size_t items_size = s->nitems * sizeof *s->items;
162
163 aver (nstates < STATE_NUMBER_MAXIMUM);
164
165 res = xmalloc (offsetof (state, items) + items_size);
166 res->number = nstates++;
167 res->accessing_symbol = s->accessing_symbol;
168 res->transitions =
169 transitions_new (s->transitions->num, s->transitions->states);
170 res->reductions = reductions_new (s->reductions->num, s->reductions->rules);
171 res->errs = NULL;
172 res->state_list = NULL;
173 res->consistent = s->consistent;
174 res->solved_conflicts = NULL;
175 res->solved_conflicts_xml = NULL;
176
177 res->nitems = s->nitems;
178 memcpy (res->items, s->items, items_size);
179
180 return res;
181}
182
df0e7316 183
17ee7397
PE
184/*---------.
185| Free S. |
186`---------*/
8b752b00
AD
187
188static void
17ee7397 189state_free (state *s)
8b752b00 190{
17ee7397
PE
191 free (s->transitions);
192 free (s->reductions);
193 free (s->errs);
194 free (s);
8b752b00
AD
195}
196
197
17ee7397
PE
198/*---------------------------.
199| Set the transitions of S. |
200`---------------------------*/
32e1e0a4
AD
201
202void
17ee7397 203state_transitions_set (state *s, int num, state **trans)
32e1e0a4 204{
4f82b42a 205 aver (!s->transitions);
17ee7397 206 s->transitions = transitions_new (num, trans);
32e1e0a4
AD
207}
208
209
17ee7397
PE
210/*--------------------------.
211| Set the reductions of S. |
212`--------------------------*/
8a731ca8
AD
213
214void
17ee7397 215state_reductions_set (state *s, int num, rule **reds)
8a731ca8 216{
4f82b42a 217 aver (!s->reductions);
17ee7397 218 s->reductions = reductions_new (num, reds);
8b752b00
AD
219}
220
221
cd08e51e 222int
17ee7397 223state_reduction_find (state *s, rule *r)
cd08e51e
AD
224{
225 int i;
17ee7397 226 reductions *reds = s->reductions;
cd08e51e 227 for (i = 0; i < reds->num; ++i)
17ee7397 228 if (reds->rules[i] == r)
cd08e51e
AD
229 return i;
230 return -1;
231}
232
233
17ee7397
PE
234/*--------------------.
235| Set the errs of S. |
236`--------------------*/
8b752b00
AD
237
238void
17ee7397 239state_errs_set (state *s, int num, symbol **tokens)
8b752b00 240{
4f82b42a 241 aver (!s->errs);
17ee7397 242 s->errs = errs_new (num, tokens);
8a731ca8
AD
243}
244
245
32e1e0a4 246
742e4900
JD
247/*--------------------------------------------------.
248| Print on OUT all the lookahead tokens such that S |
249| wants to reduce R. |
250`--------------------------------------------------*/
10e5b8bd
AD
251
252void
742e4900 253state_rule_lookahead_tokens_print (state *s, rule *r, FILE *out)
10e5b8bd 254{
cd08e51e 255 /* Find the reduction we are handling. */
17ee7397
PE
256 reductions *reds = s->reductions;
257 int red = state_reduction_find (s, r);
10e5b8bd
AD
258
259 /* Print them if there are. */
742e4900 260 if (reds->lookahead_tokens && red != -1)
10e5b8bd 261 {
cd08e51e
AD
262 bitset_iterator biter;
263 int k;
d0829076 264 char const *sep = "";
2f4f028d 265 fprintf (out, " [");
742e4900 266 BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0)
d0829076
PE
267 {
268 fprintf (out, "%s%s", sep, symbols[k]->tag);
269 sep = ", ";
270 }
2f4f028d 271 fprintf (out, "]");
10e5b8bd
AD
272 }
273}
c7ca99d4 274
41d7a5f2
PE
275void
276state_rule_lookahead_tokens_print_xml (state *s, rule *r,
277 FILE *out, int level)
278{
279 /* Find the reduction we are handling. */
280 reductions *reds = s->reductions;
281 int red = state_reduction_find (s, r);
282
283 /* Print them if there are. */
284 if (reds->lookahead_tokens && red != -1)
285 {
286 bitset_iterator biter;
287 int k;
41d7a5f2
PE
288 xml_puts (out, level, "<lookaheads>");
289 BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0)
290 {
408476bc 291 xml_printf (out, level + 1, "<symbol>%s</symbol>",
41d7a5f2
PE
292 xml_escape (symbols[k]->tag));
293 }
294 xml_puts (out, level, "</lookaheads>");
295 }
296}
297
c7ca99d4 298
36b5e963 299/*---------------------.
c7ca99d4 300| A state hash table. |
36b5e963 301`---------------------*/
c7ca99d4
AD
302
303/* Initial capacity of states hash table. */
304#define HT_INITIAL_CAPACITY 257
305
306static struct hash_table *state_table = NULL;
307
308/* Two states are equal if they have the same core items. */
03b9e273 309static inline bool
17ee7397 310state_compare (state const *s1, state const *s2)
c7ca99d4 311{
f6fbd3da 312 size_t i;
c7ca99d4
AD
313
314 if (s1->nitems != s2->nitems)
8307162d 315 return false;
c7ca99d4
AD
316
317 for (i = 0; i < s1->nitems; ++i)
318 if (s1->items[i] != s2->items[i])
8307162d 319 return false;
c7ca99d4 320
8307162d 321 return true;
c7ca99d4
AD
322}
323
03b9e273
PE
324static bool
325state_comparator (void const *s1, void const *s2)
326{
327 return state_compare (s1, s2);
328}
329
233a88ad
PE
330static inline size_t
331state_hash (state const *s, size_t tablesize)
c7ca99d4
AD
332{
333 /* Add up the state's item numbers to get a hash key. */
233a88ad 334 size_t key = 0;
f6fbd3da 335 size_t i;
17ee7397
PE
336 for (i = 0; i < s->nitems; ++i)
337 key += s->items[i];
c7ca99d4
AD
338 return key % tablesize;
339}
340
233a88ad
PE
341static size_t
342state_hasher (void const *s, size_t tablesize)
03b9e273
PE
343{
344 return state_hash (s, tablesize);
345}
346
c7ca99d4
AD
347
348/*-------------------------------.
349| Create the states hash table. |
350`-------------------------------*/
351
352void
353state_hash_new (void)
354{
355 state_table = hash_initialize (HT_INITIAL_CAPACITY,
356 NULL,
03b9e273
PE
357 state_hasher,
358 state_comparator,
359 NULL);
c7ca99d4
AD
360}
361
362
363/*---------------------------------------------.
364| Free the states hash table, not the states. |
365`---------------------------------------------*/
366
367void
368state_hash_free (void)
369{
370 hash_free (state_table);
371}
372
373
17ee7397
PE
374/*-----------------------------------.
375| Insert S in the state hash table. |
376`-----------------------------------*/
c7ca99d4
AD
377
378void
17ee7397 379state_hash_insert (state *s)
c7ca99d4 380{
75c7a52a
AD
381 if (!hash_insert (state_table, s))
382 xalloc_die ();
c7ca99d4
AD
383}
384
385
386/*------------------------------------------------------------------.
387| Find the state associated to the CORE, and return it. If it does |
388| not exist yet, return NULL. |
389`------------------------------------------------------------------*/
390
17ee7397 391state *
03b9e273 392state_hash_lookup (size_t nitems, item_number *core)
c7ca99d4 393{
03b9e273
PE
394 size_t items_size = nitems * sizeof *core;
395 state *probe = xmalloc (offsetof (state, items) + items_size);
17ee7397 396 state *entry;
c7ca99d4 397
03b9e273
PE
398 probe->nitems = nitems;
399 memcpy (probe->items, core, items_size);
c7ca99d4
AD
400 entry = hash_lookup (state_table, probe);
401 free (probe);
402 return entry;
403}
404
5967f0cf 405
14462c2b
JD
406/*--------------------------------------------------------.
407| Record S and all states reachable from S in REACHABLE. |
408`--------------------------------------------------------*/
5967f0cf
JD
409
410static void
14462c2b 411state_record_reachable_states (state *s, bitset reachable)
5967f0cf 412{
14462c2b 413 if (bitset_test (reachable, s->number))
5967f0cf 414 return;
14462c2b
JD
415 bitset_set (reachable, s->number);
416 {
417 int i;
418 for (i = 0; i < s->transitions->num; ++i)
419 if (!TRANSITION_IS_DISABLED (s->transitions, i))
420 state_record_reachable_states (s->transitions->states[i], reachable);
421 }
5967f0cf
JD
422}
423
424void
425state_remove_unreachable_states (state_number old_to_new[])
426{
427 state_number nstates_reachable = 0;
14462c2b
JD
428 bitset reachable = bitset_create (nstates, BITSET_FIXED);
429 state_record_reachable_states (states[0], reachable);
430 {
431 state_number i;
432 for (i = 0; i < nstates; ++i)
433 {
434 if (bitset_test (reachable, states[i]->number))
435 {
436 states[nstates_reachable] = states[i];
437 states[nstates_reachable]->number = nstates_reachable;
438 old_to_new[i] = nstates_reachable++;
439 }
440 else
441 {
442 state_free (states[i]);
443 old_to_new[i] = nstates;
444 }
445 }
446 }
5967f0cf 447 nstates = nstates_reachable;
14462c2b 448 bitset_free (reachable);
5967f0cf
JD
449}
450
c7ca99d4 451/* All the decorated states, indexed by the state number. */
17ee7397 452state **states = NULL;
c7ca99d4
AD
453
454
455/*----------------------.
456| Free all the states. |
457`----------------------*/
458
459void
460states_free (void)
461{
17ee7397 462 state_number i;
c7ca99d4 463 for (i = 0; i < nstates; ++i)
8b752b00
AD
464 state_free (states[i]);
465 free (states);
c7ca99d4 466}