25 |
The entry point is generate_states. */ |
The entry point is generate_states. */ |
26 |
|
|
27 |
#include "system.h" |
#include "system.h" |
28 |
#include "bitset.h" |
|
29 |
#include "quotearg.h" |
#include <bitset.h> |
30 |
#include "symtab.h" |
#include <quotearg.h> |
31 |
#include "gram.h" |
|
32 |
|
#include "LR0.h" |
33 |
|
#include "closure.h" |
34 |
|
#include "complain.h" |
35 |
#include "getargs.h" |
#include "getargs.h" |
|
#include "reader.h" |
|
36 |
#include "gram.h" |
#include "gram.h" |
37 |
#include "state.h" |
#include "gram.h" |
|
#include "complain.h" |
|
|
#include "closure.h" |
|
|
#include "LR0.h" |
|
38 |
#include "lalr.h" |
#include "lalr.h" |
39 |
|
#include "reader.h" |
40 |
#include "reduce.h" |
#include "reduce.h" |
41 |
|
#include "state.h" |
42 |
|
#include "symtab.h" |
43 |
|
|
44 |
typedef struct state_list_s |
typedef struct state_list |
45 |
{ |
{ |
46 |
struct state_list_s *next; |
struct state_list *next; |
47 |
state_t *state; |
state *state; |
48 |
} state_list_t; |
} state_list; |
49 |
|
|
50 |
static state_list_t *first_state = NULL; |
static state_list *first_state = NULL; |
51 |
static state_list_t *last_state = NULL; |
static state_list *last_state = NULL; |
52 |
|
|
53 |
|
|
54 |
/*------------------------------------------------------------------. |
/*------------------------------------------------------------------. |
56 |
| later examination, in order to find its transitions. Return it. | |
| later examination, in order to find its transitions. Return it. | |
57 |
`------------------------------------------------------------------*/ |
`------------------------------------------------------------------*/ |
58 |
|
|
59 |
static state_t * |
static state * |
60 |
state_list_append (symbol_number_t symbol, |
state_list_append (symbol_number sym, size_t core_size, item_number *core) |
|
size_t core_size, item_number_t *core) |
|
61 |
{ |
{ |
62 |
state_list_t *node = XMALLOC (state_list_t, 1); |
state_list *node = XMALLOC (state_list, 1); |
63 |
state_t *state = state_new (symbol, core_size, core); |
state *s = state_new (sym, core_size, core); |
64 |
|
|
65 |
if (trace_flag & trace_automaton) |
if (trace_flag & trace_automaton) |
66 |
fprintf (stderr, "state_list_append (state = %d, symbol = %d (%s))\n", |
fprintf (stderr, "state_list_append (state = %d, symbol = %d (%s))\n", |
67 |
nstates, symbol, symbols[symbol]->tag); |
nstates, sym, symbols[sym]->tag); |
68 |
|
|
69 |
/* If this is the endtoken, and this is not the initial state, then |
/* If this is the endtoken, and this is not the initial state, then |
70 |
this is the final state. */ |
this is the final state. */ |
71 |
if (symbol == 0 && first_state) |
if (sym == 0 && first_state) |
72 |
final_state = state; |
final_state = s; |
73 |
|
|
74 |
node->next = NULL; |
node->next = NULL; |
75 |
node->state = state; |
node->state = s; |
76 |
|
|
77 |
if (!first_state) |
if (!first_state) |
78 |
first_state = node; |
first_state = node; |
80 |
last_state->next = node; |
last_state->next = node; |
81 |
last_state = node; |
last_state = node; |
82 |
|
|
83 |
return state; |
return s; |
84 |
} |
} |
85 |
|
|
86 |
static int nshifts; |
static int nshifts; |
87 |
static symbol_number_t *shift_symbol = NULL; |
static symbol_number *shift_symbol = NULL; |
88 |
|
|
89 |
static rule_t **redset = NULL; |
static rule **redset = NULL; |
90 |
static state_t **shiftset = NULL; |
static state **shiftset = NULL; |
91 |
|
|
92 |
static item_number_t **kernel_base = NULL; |
static item_number **kernel_base = NULL; |
93 |
static int *kernel_size = NULL; |
static int *kernel_size = NULL; |
94 |
static item_number_t *kernel_items = NULL; |
static item_number *kernel_items = NULL; |
95 |
|
|
96 |
|
|
97 |
static void |
static void |
98 |
allocate_itemsets (void) |
allocate_itemsets (void) |
99 |
{ |
{ |
100 |
symbol_number_t i; |
symbol_number i; |
101 |
rule_number_t r; |
rule_number r; |
102 |
item_number_t *rhsp; |
item_number *rhsp; |
103 |
|
|
104 |
/* Count the number of occurrences of all the symbols in RITEMS. |
/* Count the number of occurrences of all the symbols in RITEMS. |
105 |
Note that useless productions (hence useless nonterminals) are |
Note that useless productions (hence useless nonterminals) are |
117 |
|
|
118 |
/* See comments before new_itemsets. All the vectors of items |
/* See comments before new_itemsets. All the vectors of items |
119 |
live inside KERNEL_ITEMS. The number of active items after |
live inside KERNEL_ITEMS. The number of active items after |
120 |
some symbol cannot be more than the number of times that symbol |
some symbol S cannot be more than the number of times that S |
121 |
appears as an item, which is SYMBOL_COUNT[SYMBOL]. |
appears as an item, which is SYMBOL_COUNT[S]. |
122 |
We allocate that much space for each symbol. */ |
We allocate that much space for each symbol. */ |
123 |
|
|
124 |
kernel_base = XCALLOC (item_number_t *, nsyms); |
kernel_base = XCALLOC (item_number *, nsyms); |
125 |
if (count) |
if (count) |
126 |
kernel_items = XCALLOC (item_number_t, count); |
kernel_items = XCALLOC (item_number, count); |
127 |
|
|
128 |
count = 0; |
count = 0; |
129 |
for (i = 0; i < nsyms; i++) |
for (i = 0; i < nsyms; i++) |
142 |
{ |
{ |
143 |
allocate_itemsets (); |
allocate_itemsets (); |
144 |
|
|
145 |
shiftset = XCALLOC (state_t *, nsyms); |
shiftset = XCALLOC (state *, nsyms); |
146 |
redset = XCALLOC (rule_t *, nrules); |
redset = XCALLOC (rule *, nrules); |
147 |
state_hash_new (); |
state_hash_new (); |
148 |
shift_symbol = XCALLOC (symbol_number_t, nsyms); |
shift_symbol = XCALLOC (symbol_number, nsyms); |
149 |
} |
} |
150 |
|
|
151 |
|
|
165 |
|
|
166 |
|
|
167 |
/*---------------------------------------------------------------. |
/*---------------------------------------------------------------. |
168 |
| Find which symbols can be shifted in STATE, and for each one | |
| Find which symbols can be shifted in S, and for each one | |
169 |
| record which items would be active after that shift. Uses the | |
| record which items would be active after that shift. Uses the | |
170 |
| contents of itemset. | |
| contents of itemset. | |
171 |
| | |
| | |
176 |
`---------------------------------------------------------------*/ |
`---------------------------------------------------------------*/ |
177 |
|
|
178 |
static void |
static void |
179 |
new_itemsets (state_t *state) |
new_itemsets (state *s) |
180 |
{ |
{ |
181 |
int i; |
int i; |
182 |
|
|
183 |
if (trace_flag & trace_automaton) |
if (trace_flag & trace_automaton) |
184 |
fprintf (stderr, "Entering new_itemsets, state = %d\n", |
fprintf (stderr, "Entering new_itemsets, state = %d\n", s->number); |
|
state->number); |
|
185 |
|
|
186 |
for (i = 0; i < nsyms; i++) |
for (i = 0; i < nsyms; i++) |
187 |
kernel_size[i] = 0; |
kernel_size[i] = 0; |
191 |
for (i = 0; i < nritemset; ++i) |
for (i = 0; i < nritemset; ++i) |
192 |
if (ritem[itemset[i]] >= 0) |
if (ritem[itemset[i]] >= 0) |
193 |
{ |
{ |
194 |
symbol_number_t symbol |
symbol_number sym = item_number_as_symbol_number (ritem[itemset[i]]); |
195 |
= item_number_as_symbol_number (ritem[itemset[i]]); |
if (!kernel_size[sym]) |
|
if (!kernel_size[symbol]) |
|
196 |
{ |
{ |
197 |
shift_symbol[nshifts] = symbol; |
shift_symbol[nshifts] = sym; |
198 |
nshifts++; |
nshifts++; |
199 |
} |
} |
200 |
|
|
201 |
kernel_base[symbol][kernel_size[symbol]] = itemset[i] + 1; |
kernel_base[sym][kernel_size[sym]] = itemset[i] + 1; |
202 |
kernel_size[symbol]++; |
kernel_size[sym]++; |
203 |
} |
} |
204 |
} |
} |
205 |
|
|
206 |
|
|
207 |
|
|
208 |
/*-----------------------------------------------------------------. |
/*--------------------------------------------------------------. |
209 |
| Find the state we would get to (from the current state) by | |
| Find the state we would get to (from the current state) by | |
210 |
| shifting SYMBOL. Create a new state if no equivalent one exists | |
| shifting SYM. Create a new state if no equivalent one exists | |
211 |
| already. Used by append_states. | |
| already. Used by append_states. | |
212 |
`-----------------------------------------------------------------*/ |
`--------------------------------------------------------------*/ |
213 |
|
|
214 |
static state_t * |
static state * |
215 |
get_state (symbol_number_t symbol, size_t core_size, item_number_t *core) |
get_state (symbol_number sym, size_t core_size, item_number *core) |
216 |
{ |
{ |
217 |
state_t *sp; |
state *sp; |
218 |
|
|
219 |
if (trace_flag & trace_automaton) |
if (trace_flag & trace_automaton) |
220 |
fprintf (stderr, "Entering get_state, symbol = %d (%s)\n", |
fprintf (stderr, "Entering get_state, symbol = %d (%s)\n", |
221 |
symbol, symbols[symbol]->tag); |
sym, symbols[sym]->tag); |
222 |
|
|
223 |
sp = state_hash_lookup (core_size, core); |
sp = state_hash_lookup (core_size, core); |
224 |
if (!sp) |
if (!sp) |
225 |
sp = state_list_append (symbol, core_size, core); |
sp = state_list_append (sym, core_size, core); |
226 |
|
|
227 |
if (trace_flag & trace_automaton) |
if (trace_flag & trace_automaton) |
228 |
fprintf (stderr, "Exiting get_state => %d\n", sp->number); |
fprintf (stderr, "Exiting get_state => %d\n", sp->number); |
232 |
|
|
233 |
/*---------------------------------------------------------------. |
/*---------------------------------------------------------------. |
234 |
| Use the information computed by new_itemsets to find the state | |
| Use the information computed by new_itemsets to find the state | |
235 |
| numbers reached by each shift transition from STATE. | |
| numbers reached by each shift transition from S. | |
236 |
| | |
| | |
237 |
| SHIFTSET is set up as a vector of those states. | |
| SHIFTSET is set up as a vector of those states. | |
238 |
`---------------------------------------------------------------*/ |
`---------------------------------------------------------------*/ |
239 |
|
|
240 |
static void |
static void |
241 |
append_states (state_t *state) |
append_states (state *s) |
242 |
{ |
{ |
243 |
int i; |
int i; |
|
int j; |
|
|
symbol_number_t symbol; |
|
244 |
|
|
245 |
if (trace_flag & trace_automaton) |
if (trace_flag & trace_automaton) |
246 |
fprintf (stderr, "Entering append_states, state = %d\n", |
fprintf (stderr, "Entering append_states, state = %d\n", s->number); |
|
state->number); |
|
247 |
|
|
248 |
/* first sort shift_symbol into increasing order */ |
/* First sort shift_symbol into increasing order. */ |
249 |
|
|
250 |
for (i = 1; i < nshifts; i++) |
for (i = 1; i < nshifts; i++) |
251 |
{ |
{ |
252 |
symbol = shift_symbol[i]; |
symbol_number sym = shift_symbol[i]; |
253 |
j = i; |
int j; |
254 |
while (j > 0 && shift_symbol[j - 1] > symbol) |
for (j = i; 0 < j && sym < shift_symbol [j - 1]; j--) |
255 |
{ |
shift_symbol[j] = shift_symbol[j - 1]; |
256 |
shift_symbol[j] = shift_symbol[j - 1]; |
shift_symbol[j] = sym; |
|
j--; |
|
|
} |
|
|
shift_symbol[j] = symbol; |
|
257 |
} |
} |
258 |
|
|
259 |
for (i = 0; i < nshifts; i++) |
for (i = 0; i < nshifts; i++) |
260 |
{ |
{ |
261 |
symbol = shift_symbol[i]; |
symbol_number sym = shift_symbol[i]; |
262 |
shiftset[i] = get_state (symbol, |
shiftset[i] = get_state (sym, kernel_size[sym], kernel_base[sym]); |
|
kernel_size[symbol], kernel_base[symbol]); |
|
263 |
} |
} |
264 |
} |
} |
265 |
|
|
271 |
`----------------------------------------------------------------*/ |
`----------------------------------------------------------------*/ |
272 |
|
|
273 |
static void |
static void |
274 |
save_reductions (state_t *state) |
save_reductions (state *s) |
275 |
{ |
{ |
276 |
int count = 0; |
int count = 0; |
277 |
int i; |
int i; |
285 |
} |
} |
286 |
|
|
287 |
/* Make a reductions structure and copy the data into it. */ |
/* Make a reductions structure and copy the data into it. */ |
288 |
state_reductions_set (state, count, redset); |
state_reductions_set (s, count, redset); |
289 |
} |
} |
290 |
|
|
291 |
|
|
296 |
static void |
static void |
297 |
set_states (void) |
set_states (void) |
298 |
{ |
{ |
299 |
states = XCALLOC (state_t *, nstates); |
states = XCALLOC (state *, nstates); |
300 |
|
|
301 |
while (first_state) |
while (first_state) |
302 |
{ |
{ |
303 |
state_list_t *this = first_state; |
state_list *this = first_state; |
304 |
|
|
305 |
/* Pessimization, but simplification of the code: make sure all |
/* Pessimization, but simplification of the code: make sure all |
306 |
the states have valid transitions and reductions members, |
the states have valid transitions and reductions members, |
307 |
even if reduced to 0. It is too soon for errs, which are |
even if reduced to 0. It is too soon for errs, which are |
308 |
computed later, but set_conflicts. */ |
computed later, but set_conflicts. */ |
309 |
state_t *state = this->state; |
state *s = this->state; |
310 |
if (!state->transitions) |
if (!s->transitions) |
311 |
state_transitions_set (state, 0, 0); |
state_transitions_set (s, 0, 0); |
312 |
if (!state->reductions) |
if (!s->reductions) |
313 |
state_reductions_set (state, 0, 0); |
state_reductions_set (s, 0, 0); |
314 |
|
|
315 |
states[state->number] = state; |
states[s->number] = s; |
316 |
|
|
317 |
first_state = this->next; |
first_state = this->next; |
318 |
free (this); |
free (this); |
330 |
void |
void |
331 |
generate_states (void) |
generate_states (void) |
332 |
{ |
{ |
333 |
state_list_t *list = NULL; |
state_list *list = NULL; |
334 |
allocate_storage (); |
allocate_storage (); |
335 |
new_closure (nritems); |
new_closure (nritems); |
336 |
|
|
344 |
|
|
345 |
while (list) |
while (list) |
346 |
{ |
{ |
347 |
state_t *state = list->state; |
state *s = list->state; |
348 |
if (trace_flag & trace_automaton) |
if (trace_flag & trace_automaton) |
349 |
fprintf (stderr, "Processing state %d (reached by %s)\n", |
fprintf (stderr, "Processing state %d (reached by %s)\n", |
350 |
state->number, |
s->number, |
351 |
symbols[state->accessing_symbol]->tag); |
symbols[s->accessing_symbol]->tag); |
352 |
/* Set up ruleset and itemset for the transitions out of this |
/* Set up ruleset and itemset for the transitions out of this |
353 |
state. ruleset gets a 1 bit for each rule that could reduce |
state. ruleset gets a 1 bit for each rule that could reduce |
354 |
now. itemset gets a vector of all the items that could be |
now. itemset gets a vector of all the items that could be |
355 |
accepted next. */ |
accepted next. */ |
356 |
closure (state->items, state->nitems); |
closure (s->items, s->nitems); |
357 |
/* Record the reductions allowed out of this state. */ |
/* Record the reductions allowed out of this state. */ |
358 |
save_reductions (state); |
save_reductions (s); |
359 |
/* Find the itemsets of the states that shifts can reach. */ |
/* Find the itemsets of the states that shifts can reach. */ |
360 |
new_itemsets (state); |
new_itemsets (s); |
361 |
/* Find or create the core structures for those states. */ |
/* Find or create the core structures for those states. */ |
362 |
append_states (state); |
append_states (s); |
363 |
|
|
364 |
/* Create the shifts structures for the shifts to those states, |
/* Create the shifts structures for the shifts to those states, |
365 |
now that the state numbers transitioning to are known. */ |
now that the state numbers transitioning to are known. */ |
366 |
state_transitions_set (state, nshifts, shiftset); |
state_transitions_set (s, nshifts, shiftset); |
367 |
|
|
368 |
/* States are queued when they are created; process them all. |
/* states are queued when they are created; process them all. |
369 |
*/ |
*/ |
370 |
list = list->next; |
list = list->next; |
371 |
} |
} |