]> git.saurik.com Git - bison.git/blame - src/state.c
ChangeLog (2006-09-15): add Odd Arild Olsen's role for push.c.
[bison.git] / src / state.c
CommitLineData
ec14f0c8 1/* Type definitions for nondeterministic finite state machine for Bison.
03b9e273 2
219c26ea 3 Copyright (C) 2001-2007, 2009-2010 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;
144 res->consistent = 0;
df0e7316 145 res->solved_conflicts = NULL;
41d7a5f2 146 res->solved_conflicts_xml = NULL;
df0e7316 147
03b9e273
PE
148 res->nitems = nitems;
149 memcpy (res->items, core, items_size);
df0e7316 150
8b752b00
AD
151 state_hash_insert (res);
152
df0e7316
AD
153 return res;
154}
155
156
17ee7397
PE
157/*---------.
158| Free S. |
159`---------*/
8b752b00
AD
160
161static void
17ee7397 162state_free (state *s)
8b752b00 163{
17ee7397
PE
164 free (s->transitions);
165 free (s->reductions);
166 free (s->errs);
167 free (s);
8b752b00
AD
168}
169
170
17ee7397
PE
171/*---------------------------.
172| Set the transitions of S. |
173`---------------------------*/
32e1e0a4
AD
174
175void
17ee7397 176state_transitions_set (state *s, int num, state **trans)
32e1e0a4 177{
4f82b42a 178 aver (!s->transitions);
17ee7397 179 s->transitions = transitions_new (num, trans);
32e1e0a4
AD
180}
181
182
17ee7397
PE
183/*--------------------------.
184| Set the reductions of S. |
185`--------------------------*/
8a731ca8
AD
186
187void
17ee7397 188state_reductions_set (state *s, int num, rule **reds)
8a731ca8 189{
4f82b42a 190 aver (!s->reductions);
17ee7397 191 s->reductions = reductions_new (num, reds);
8b752b00
AD
192}
193
194
cd08e51e 195int
17ee7397 196state_reduction_find (state *s, rule *r)
cd08e51e
AD
197{
198 int i;
17ee7397 199 reductions *reds = s->reductions;
cd08e51e 200 for (i = 0; i < reds->num; ++i)
17ee7397 201 if (reds->rules[i] == r)
cd08e51e
AD
202 return i;
203 return -1;
204}
205
206
17ee7397
PE
207/*--------------------.
208| Set the errs of S. |
209`--------------------*/
8b752b00
AD
210
211void
17ee7397 212state_errs_set (state *s, int num, symbol **tokens)
8b752b00 213{
4f82b42a 214 aver (!s->errs);
17ee7397 215 s->errs = errs_new (num, tokens);
8a731ca8
AD
216}
217
218
32e1e0a4 219
742e4900
JD
220/*--------------------------------------------------.
221| Print on OUT all the lookahead tokens such that S |
222| wants to reduce R. |
223`--------------------------------------------------*/
10e5b8bd
AD
224
225void
742e4900 226state_rule_lookahead_tokens_print (state *s, rule *r, FILE *out)
10e5b8bd 227{
cd08e51e 228 /* Find the reduction we are handling. */
17ee7397
PE
229 reductions *reds = s->reductions;
230 int red = state_reduction_find (s, r);
10e5b8bd
AD
231
232 /* Print them if there are. */
742e4900 233 if (reds->lookahead_tokens && red != -1)
10e5b8bd 234 {
cd08e51e
AD
235 bitset_iterator biter;
236 int k;
d0829076 237 char const *sep = "";
2f4f028d 238 fprintf (out, " [");
742e4900 239 BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0)
d0829076
PE
240 {
241 fprintf (out, "%s%s", sep, symbols[k]->tag);
242 sep = ", ";
243 }
2f4f028d 244 fprintf (out, "]");
10e5b8bd
AD
245 }
246}
c7ca99d4 247
41d7a5f2
PE
248void
249state_rule_lookahead_tokens_print_xml (state *s, rule *r,
250 FILE *out, int level)
251{
252 /* Find the reduction we are handling. */
253 reductions *reds = s->reductions;
254 int red = state_reduction_find (s, r);
255
256 /* Print them if there are. */
257 if (reds->lookahead_tokens && red != -1)
258 {
259 bitset_iterator biter;
260 int k;
41d7a5f2
PE
261 xml_puts (out, level, "<lookaheads>");
262 BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0)
263 {
408476bc 264 xml_printf (out, level + 1, "<symbol>%s</symbol>",
41d7a5f2
PE
265 xml_escape (symbols[k]->tag));
266 }
267 xml_puts (out, level, "</lookaheads>");
268 }
269}
270
c7ca99d4 271
36b5e963 272/*---------------------.
c7ca99d4 273| A state hash table. |
36b5e963 274`---------------------*/
c7ca99d4
AD
275
276/* Initial capacity of states hash table. */
277#define HT_INITIAL_CAPACITY 257
278
279static struct hash_table *state_table = NULL;
280
281/* Two states are equal if they have the same core items. */
03b9e273 282static inline bool
17ee7397 283state_compare (state const *s1, state const *s2)
c7ca99d4 284{
f6fbd3da 285 size_t i;
c7ca99d4
AD
286
287 if (s1->nitems != s2->nitems)
8307162d 288 return false;
c7ca99d4
AD
289
290 for (i = 0; i < s1->nitems; ++i)
291 if (s1->items[i] != s2->items[i])
8307162d 292 return false;
c7ca99d4 293
8307162d 294 return true;
c7ca99d4
AD
295}
296
03b9e273
PE
297static bool
298state_comparator (void const *s1, void const *s2)
299{
300 return state_compare (s1, s2);
301}
302
233a88ad
PE
303static inline size_t
304state_hash (state const *s, size_t tablesize)
c7ca99d4
AD
305{
306 /* Add up the state's item numbers to get a hash key. */
233a88ad 307 size_t key = 0;
f6fbd3da 308 size_t i;
17ee7397
PE
309 for (i = 0; i < s->nitems; ++i)
310 key += s->items[i];
c7ca99d4
AD
311 return key % tablesize;
312}
313
233a88ad
PE
314static size_t
315state_hasher (void const *s, size_t tablesize)
03b9e273
PE
316{
317 return state_hash (s, tablesize);
318}
319
c7ca99d4
AD
320
321/*-------------------------------.
322| Create the states hash table. |
323`-------------------------------*/
324
325void
326state_hash_new (void)
327{
328 state_table = hash_initialize (HT_INITIAL_CAPACITY,
329 NULL,
03b9e273
PE
330 state_hasher,
331 state_comparator,
332 NULL);
c7ca99d4
AD
333}
334
335
336/*---------------------------------------------.
337| Free the states hash table, not the states. |
338`---------------------------------------------*/
339
340void
341state_hash_free (void)
342{
343 hash_free (state_table);
344}
345
346
17ee7397
PE
347/*-----------------------------------.
348| Insert S in the state hash table. |
349`-----------------------------------*/
c7ca99d4
AD
350
351void
17ee7397 352state_hash_insert (state *s)
c7ca99d4 353{
914e713d
AD
354 if (!hash_insert (state_table, s))
355 xalloc_die ();
c7ca99d4
AD
356}
357
358
359/*------------------------------------------------------------------.
360| Find the state associated to the CORE, and return it. If it does |
361| not exist yet, return NULL. |
362`------------------------------------------------------------------*/
363
17ee7397 364state *
03b9e273 365state_hash_lookup (size_t nitems, item_number *core)
c7ca99d4 366{
03b9e273
PE
367 size_t items_size = nitems * sizeof *core;
368 state *probe = xmalloc (offsetof (state, items) + items_size);
17ee7397 369 state *entry;
c7ca99d4 370
03b9e273
PE
371 probe->nitems = nitems;
372 memcpy (probe->items, core, items_size);
c7ca99d4
AD
373 entry = hash_lookup (state_table, probe);
374 free (probe);
375 return entry;
376}
377
5967f0cf 378
14462c2b
JD
379/*--------------------------------------------------------.
380| Record S and all states reachable from S in REACHABLE. |
381`--------------------------------------------------------*/
5967f0cf
JD
382
383static void
14462c2b 384state_record_reachable_states (state *s, bitset reachable)
5967f0cf 385{
14462c2b 386 if (bitset_test (reachable, s->number))
5967f0cf 387 return;
14462c2b
JD
388 bitset_set (reachable, s->number);
389 {
390 int i;
391 for (i = 0; i < s->transitions->num; ++i)
392 if (!TRANSITION_IS_DISABLED (s->transitions, i))
393 state_record_reachable_states (s->transitions->states[i], reachable);
394 }
5967f0cf
JD
395}
396
397void
398state_remove_unreachable_states (state_number old_to_new[])
399{
400 state_number nstates_reachable = 0;
14462c2b
JD
401 bitset reachable = bitset_create (nstates, BITSET_FIXED);
402 state_record_reachable_states (states[0], reachable);
403 {
404 state_number i;
405 for (i = 0; i < nstates; ++i)
406 {
407 if (bitset_test (reachable, states[i]->number))
408 {
409 states[nstates_reachable] = states[i];
410 states[nstates_reachable]->number = nstates_reachable;
411 old_to_new[i] = nstates_reachable++;
412 }
413 else
414 {
415 state_free (states[i]);
416 old_to_new[i] = nstates;
417 }
418 }
419 }
5967f0cf 420 nstates = nstates_reachable;
14462c2b 421 bitset_free (reachable);
5967f0cf
JD
422}
423
c7ca99d4 424/* All the decorated states, indexed by the state number. */
17ee7397 425state **states = NULL;
c7ca99d4
AD
426
427
428/*----------------------.
429| Free all the states. |
430`----------------------*/
431
432void
433states_free (void)
434{
17ee7397 435 state_number i;
c7ca99d4 436 for (i = 0; i < nstates; ++i)
8b752b00
AD
437 state_free (states[i]);
438 free (states);
c7ca99d4 439}