1 |
/* Type definitions for nondeterministic finite state machine for Bison. |
/* Type definitions for nondeterministic finite state machine for Bison. |
2 |
|
|
3 |
Copyright (C) 2001, 2002 Free Software Foundation, Inc. |
Copyright (C) 2001, 2002 Free Software Foundation, Inc. |
4 |
|
|
5 |
This file is part of Bison, the GNU Compiler Compiler. |
This file is part of Bison, the GNU Compiler Compiler. |
34 |
`-------------------*/ |
`-------------------*/ |
35 |
|
|
36 |
|
|
37 |
/*---------------------------------------. |
/*-----------------------------------------. |
38 |
| Create a new array of N shifts/gotos. | |
| Create a new array of NUM shifts/gotos. | |
39 |
`---------------------------------------*/ |
`-----------------------------------------*/ |
|
|
|
|
#define TRANSITIONS_ALLOC(Num) \ |
|
|
(transitions *) xcalloc ((sizeof (transitions) \ |
|
|
+ (Num - 1) * sizeof (state *)), \ |
|
|
1) |
|
40 |
|
|
41 |
static transitions * |
static transitions * |
42 |
transitions_new (int num, state **the_states) |
transitions_new (int num, state **the_states) |
43 |
{ |
{ |
44 |
transitions *res = TRANSITIONS_ALLOC (num); |
size_t states_size = num * sizeof *the_states; |
45 |
|
transitions *res = xmalloc (offsetof (transitions, states) + states_size); |
46 |
res->num = num; |
res->num = num; |
47 |
memcpy (res->states, the_states, num * sizeof (the_states[0])); |
memcpy (res->states, the_states, states_size); |
48 |
return res; |
return res; |
49 |
} |
} |
50 |
|
|
70 |
`--------------------*/ |
`--------------------*/ |
71 |
|
|
72 |
|
|
73 |
/*-------------------------------. |
/*---------------------------------. |
74 |
| Create a new array of N errs. | |
| Create a new array of NUM errs. | |
75 |
`-------------------------------*/ |
`---------------------------------*/ |
|
|
|
|
#define ERRS_ALLOC(Nerrs) \ |
|
|
((errs *) xcalloc ((sizeof (errs) + (Nerrs - 1) * sizeof (symbol *)), 1)) |
|
|
|
|
76 |
|
|
77 |
errs * |
errs * |
78 |
errs_new (int num, symbol **tokens) |
errs_new (int num, symbol **tokens) |
79 |
{ |
{ |
80 |
errs *res = ERRS_ALLOC (num); |
size_t symbols_size = num * sizeof *tokens; |
81 |
|
errs *res = xmalloc (offsetof (errs, symbols) + symbols_size); |
82 |
res->num = num; |
res->num = num; |
83 |
memcpy (res->symbols, tokens, num * sizeof (tokens[0])); |
memcpy (res->symbols, tokens, symbols_size); |
84 |
return res; |
return res; |
85 |
} |
} |
86 |
|
|
92 |
`-------------*/ |
`-------------*/ |
93 |
|
|
94 |
|
|
95 |
/*-------------------------------------. |
/*---------------------------------------. |
96 |
| Create a new array of N reductions. | |
| Create a new array of NUM reductions. | |
97 |
`-------------------------------------*/ |
`---------------------------------------*/ |
|
|
|
|
#define REDUCTIONS_ALLOC(Nreductions) \ |
|
|
(reductions *) xcalloc ((sizeof (reductions) \ |
|
|
+ (Nreductions - 1) * sizeof (rule *)), 1) |
|
98 |
|
|
99 |
static reductions * |
static reductions * |
100 |
reductions_new (int num, rule **reds) |
reductions_new (int num, rule **reds) |
101 |
{ |
{ |
102 |
reductions *res = REDUCTIONS_ALLOC (num); |
size_t rules_size = num * sizeof *reds; |
103 |
|
reductions *res = xmalloc (offsetof (reductions, rules) + rules_size); |
104 |
res->num = num; |
res->num = num; |
|
memcpy (res->rules, reds, num * sizeof (reds[0])); |
|
105 |
res->lookaheads = NULL; |
res->lookaheads = NULL; |
106 |
|
memcpy (res->rules, reds, rules_size); |
107 |
return res; |
return res; |
108 |
} |
} |
109 |
|
|
119 |
accessing symbol: $end. */ |
accessing symbol: $end. */ |
120 |
state *final_state = NULL; |
state *final_state = NULL; |
121 |
|
|
|
#define STATE_ALLOC(Nitems) \ |
|
|
(state *) xcalloc ((sizeof (state) \ |
|
|
+ (Nitems - 1) * sizeof (item_number)), \ |
|
|
1) |
|
122 |
|
|
123 |
/*------------------------------------------------------------------. |
/*------------------------------------------------------------------. |
124 |
| Create a new state with ACCESSING_SYMBOL, for those items. Store | |
| Create a new state with ACCESSING_SYMBOL, for those items. Store | |
127 |
|
|
128 |
state * |
state * |
129 |
state_new (symbol_number accessing_symbol, |
state_new (symbol_number accessing_symbol, |
130 |
size_t core_size, item_number *core) |
size_t nitems, item_number *core) |
131 |
{ |
{ |
132 |
state *res; |
state *res; |
133 |
|
size_t items_size = nitems * sizeof *core; |
134 |
|
|
135 |
if (STATE_NUMBER_MAXIMUM <= nstates) |
if (STATE_NUMBER_MAXIMUM <= nstates) |
136 |
abort (); |
abort (); |
137 |
|
|
138 |
res = STATE_ALLOC (core_size); |
res = xmalloc (offsetof (state, items) + items_size); |
139 |
|
res->number = nstates++; |
140 |
res->accessing_symbol = accessing_symbol; |
res->accessing_symbol = accessing_symbol; |
141 |
res->number = nstates; |
res->transitions = NULL; |
142 |
++nstates; |
res->reductions = NULL; |
143 |
|
res->errs = NULL; |
144 |
|
res->consistent = 0; |
145 |
res->solved_conflicts = NULL; |
res->solved_conflicts = NULL; |
146 |
|
|
147 |
res->nitems = core_size; |
res->nitems = nitems; |
148 |
memcpy (res->items, core, core_size * sizeof (core[0])); |
memcpy (res->items, core, items_size); |
149 |
|
|
150 |
state_hash_insert (res); |
state_hash_insert (res); |
151 |
|
|
257 |
static struct hash_table *state_table = NULL; |
static struct hash_table *state_table = NULL; |
258 |
|
|
259 |
/* Two states are equal if they have the same core items. */ |
/* Two states are equal if they have the same core items. */ |
260 |
static bool |
static inline bool |
261 |
state_compare (state const *s1, state const *s2) |
state_compare (state const *s1, state const *s2) |
262 |
{ |
{ |
263 |
int i; |
int i; |
272 |
return true; |
return true; |
273 |
} |
} |
274 |
|
|
275 |
static unsigned int |
static bool |
276 |
|
state_comparator (void const *s1, void const *s2) |
277 |
|
{ |
278 |
|
return state_compare (s1, s2); |
279 |
|
} |
280 |
|
|
281 |
|
static inline unsigned int |
282 |
state_hash (state const *s, unsigned int tablesize) |
state_hash (state const *s, unsigned int tablesize) |
283 |
{ |
{ |
284 |
/* Add up the state's item numbers to get a hash key. */ |
/* Add up the state's item numbers to get a hash key. */ |
285 |
int key = 0; |
unsigned int key = 0; |
286 |
int i; |
int i; |
287 |
for (i = 0; i < s->nitems; ++i) |
for (i = 0; i < s->nitems; ++i) |
288 |
key += s->items[i]; |
key += s->items[i]; |
289 |
return key % tablesize; |
return key % tablesize; |
290 |
} |
} |
291 |
|
|
292 |
|
static unsigned int |
293 |
|
state_hasher (void const *s, unsigned int tablesize) |
294 |
|
{ |
295 |
|
return state_hash (s, tablesize); |
296 |
|
} |
297 |
|
|
298 |
|
|
299 |
/*-------------------------------. |
/*-------------------------------. |
300 |
| Create the states hash table. | |
| Create the states hash table. | |
305 |
{ |
{ |
306 |
state_table = hash_initialize (HT_INITIAL_CAPACITY, |
state_table = hash_initialize (HT_INITIAL_CAPACITY, |
307 |
NULL, |
NULL, |
308 |
(Hash_hasher) state_hash, |
state_hasher, |
309 |
(Hash_comparator) state_compare, |
state_comparator, |
310 |
(Hash_data_freer) NULL); |
NULL); |
311 |
} |
} |
312 |
|
|
313 |
|
|
339 |
`------------------------------------------------------------------*/ |
`------------------------------------------------------------------*/ |
340 |
|
|
341 |
state * |
state * |
342 |
state_hash_lookup (size_t core_size, item_number *core) |
state_hash_lookup (size_t nitems, item_number *core) |
343 |
{ |
{ |
344 |
state *probe = STATE_ALLOC (core_size); |
size_t items_size = nitems * sizeof *core; |
345 |
|
state *probe = xmalloc (offsetof (state, items) + items_size); |
346 |
state *entry; |
state *entry; |
347 |
|
|
348 |
probe->nitems = core_size; |
probe->nitems = nitems; |
349 |
memcpy (probe->items, core, core_size * sizeof (core[0])); |
memcpy (probe->items, core, items_size); |
350 |
entry = hash_lookup (state_table, probe); |
entry = hash_lookup (state_table, probe); |
351 |
free (probe); |
free (probe); |
352 |
return entry; |
return entry; |