37 |
#include "lalr.h" |
#include "lalr.h" |
38 |
#include "reduce.h" |
#include "reduce.h" |
39 |
|
|
40 |
static state_t *first_state = NULL; |
typedef struct state_list_s |
41 |
|
{ |
42 |
|
struct state_list_s *next; |
43 |
|
state_t *state; |
44 |
|
} state_list_t; |
45 |
|
|
46 |
|
static state_list_t *first_state = NULL; |
47 |
|
static state_list_t *last_state = NULL; |
48 |
|
|
49 |
static state_t *this_state = NULL; |
static void |
50 |
static state_t *last_state = NULL; |
state_list_append (state_t *state) |
51 |
|
{ |
52 |
|
state_list_t *node = XMALLOC (state_list_t, 1); |
53 |
|
node->next = NULL; |
54 |
|
node->state = state; |
55 |
|
|
56 |
|
if (!first_state) |
57 |
|
first_state = node; |
58 |
|
if (last_state) |
59 |
|
last_state->next = node; |
60 |
|
last_state = node; |
61 |
|
} |
62 |
|
|
63 |
static int nshifts; |
static int nshifts; |
64 |
static symbol_number_t *shift_symbol = NULL; |
static symbol_number_t *shift_symbol = NULL; |
140 |
|
|
141 |
|
|
142 |
|
|
143 |
/*----------------------------------------------------------------. |
/*---------------------------------------------------------------. |
144 |
| Find which symbols can be shifted in the current state, and for | |
| Find which symbols can be shifted in STATE, and for each one | |
145 |
| each one record which items would be active after that shift. | |
| record which items would be active after that shift. Uses the | |
146 |
| Uses the contents of itemset. | |
| contents of itemset. | |
147 |
| | |
| | |
148 |
| shift_symbol is set to a vector of the symbols that can be | |
| shift_symbol is set to a vector of the symbols that can be | |
149 |
| shifted. For each symbol in the grammar, kernel_base[symbol] | |
| shifted. For each symbol in the grammar, kernel_base[symbol] | |
150 |
| points to a vector of item numbers activated if that symbol is | |
| points to a vector of item numbers activated if that symbol is | |
151 |
| shifted, and kernel_size[symbol] is their numbers. | |
| shifted, and kernel_size[symbol] is their numbers. | |
152 |
`----------------------------------------------------------------*/ |
`---------------------------------------------------------------*/ |
153 |
|
|
154 |
static void |
static void |
155 |
new_itemsets (void) |
new_itemsets (state_t *state) |
156 |
{ |
{ |
157 |
int i; |
int i; |
158 |
|
|
159 |
if (trace_flag) |
if (trace_flag) |
160 |
fprintf (stderr, "Entering new_itemsets, state = %d\n", |
fprintf (stderr, "Entering new_itemsets, state = %d\n", |
161 |
this_state->number); |
state->number); |
162 |
|
|
163 |
for (i = 0; i < nsyms; i++) |
for (i = 0; i < nsyms; i++) |
164 |
kernel_size[i] = 0; |
kernel_size[i] = 0; |
205 |
if (symbol == 0 && first_state) |
if (symbol == 0 && first_state) |
206 |
final_state = res; |
final_state = res; |
207 |
|
|
208 |
if (!first_state) |
state_list_append (res); |
|
first_state = res; |
|
|
if (last_state) |
|
|
last_state->next = res; |
|
|
last_state = res; |
|
|
|
|
209 |
return res; |
return res; |
210 |
} |
} |
211 |
|
|
222 |
state_t *sp; |
state_t *sp; |
223 |
|
|
224 |
if (trace_flag) |
if (trace_flag) |
225 |
fprintf (stderr, "Entering get_state, state = %d, symbol = %d (%s)\n", |
fprintf (stderr, "Entering get_state, symbol = %d (%s)\n", |
226 |
this_state->number, symbol, |
symbol, symbol_tag_get (symbols[symbol])); |
|
symbol_tag_get (symbols[symbol])); |
|
227 |
|
|
228 |
sp = state_hash_lookup (core_size, core); |
sp = state_hash_lookup (core_size, core); |
229 |
if (!sp) |
if (!sp) |
237 |
|
|
238 |
/*------------------------------------------------------------------. |
/*------------------------------------------------------------------. |
239 |
| Use the information computed by new_itemsets to find the state | |
| Use the information computed by new_itemsets to find the state | |
240 |
| numbers reached by each shift transition from the current state. | |
| numbers reached by each shift transition from STATE. | |
241 |
| | |
| | |
242 |
| shiftset is set up as a vector of state numbers of those states. | |
| SHIFTSET is set up as a vector of state numbers of those states. | |
243 |
`------------------------------------------------------------------*/ |
`------------------------------------------------------------------*/ |
244 |
|
|
245 |
static void |
static void |
246 |
append_states (void) |
append_states (state_t *state) |
247 |
{ |
{ |
248 |
int i; |
int i; |
249 |
int j; |
int j; |
251 |
|
|
252 |
if (trace_flag) |
if (trace_flag) |
253 |
fprintf (stderr, "Entering append_states, state = %d\n", |
fprintf (stderr, "Entering append_states, state = %d\n", |
254 |
this_state->number); |
state->number); |
255 |
|
|
256 |
/* first sort shift_symbol into increasing order */ |
/* first sort shift_symbol into increasing order */ |
257 |
|
|
282 |
/* The 0 at the lhs is the index of the item of this initial rule. */ |
/* The 0 at the lhs is the index of the item of this initial rule. */ |
283 |
kernel_base[0][0] = 0; |
kernel_base[0][0] = 0; |
284 |
kernel_size[0] = 1; |
kernel_size[0] = 1; |
285 |
this_state = new_state (0, kernel_size[0], kernel_base[0]); |
state_list_append (new_state (0, kernel_size[0], kernel_base[0])); |
286 |
} |
} |
287 |
|
|
288 |
|
|
|
/*------------------------------------------------------------. |
|
|
| Save the NSHIFTS of SHIFTSET into the current linked list. | |
|
|
`------------------------------------------------------------*/ |
|
|
|
|
|
static void |
|
|
save_shifts (void) |
|
|
{ |
|
|
shifts *p = shifts_new (nshifts); |
|
|
memcpy (p->shifts, shiftset, nshifts * sizeof (shiftset[0])); |
|
|
this_state->shifts = p; |
|
|
} |
|
|
|
|
289 |
|
|
290 |
/*----------------------------------------------------------------. |
/*----------------------------------------------------------------. |
291 |
| Find which rules can be used for reduction transitions from the | |
| Find which rules can be used for reduction transitions from the | |
294 |
`----------------------------------------------------------------*/ |
`----------------------------------------------------------------*/ |
295 |
|
|
296 |
static void |
static void |
297 |
save_reductions (void) |
save_reductions (state_t *state) |
298 |
{ |
{ |
299 |
int count = 0; |
int count = 0; |
300 |
int i; |
int i; |
301 |
|
|
302 |
/* If this is the final state, we want it to have no reductions at |
/* If this is the final state, we want it to have no reductions at |
303 |
all, although it has one for `START_SYMBOL EOF .'. */ |
all, although it has one for `START_SYMBOL EOF .'. */ |
304 |
if (final_state && this_state->number == final_state->number) |
if (final_state && state->number == final_state->number) |
305 |
return; |
return; |
306 |
|
|
307 |
/* Find and count the active items that represent ends of rules. */ |
/* Find and count the active items that represent ends of rules. */ |
313 |
} |
} |
314 |
|
|
315 |
/* Make a reductions structure and copy the data into it. */ |
/* Make a reductions structure and copy the data into it. */ |
316 |
this_state->reductions = reductions_new (count); |
state->reductions = reductions_new (count); |
317 |
memcpy (this_state->reductions->rules, redset, count * sizeof (redset[0])); |
memcpy (state->reductions->rules, redset, count * sizeof (redset[0])); |
318 |
} |
} |
319 |
|
|
320 |
|
|
325 |
static void |
static void |
326 |
set_states (void) |
set_states (void) |
327 |
{ |
{ |
|
state_t *sp; |
|
328 |
states = XCALLOC (state_t *, nstates); |
states = XCALLOC (state_t *, nstates); |
329 |
|
|
330 |
for (sp = first_state; sp; sp = sp->next) |
while (first_state) |
331 |
{ |
{ |
332 |
|
state_list_t *this = first_state; |
333 |
|
|
334 |
/* Pessimization, but simplification of the code: make sure all |
/* Pessimization, but simplification of the code: make sure all |
335 |
the states have a shifts, errs, and reductions, even if |
the states have a shifts, errs, and reductions, even if |
336 |
reduced to 0. */ |
reduced to 0. */ |
337 |
if (!sp->shifts) |
state_t *state = this->state; |
338 |
sp->shifts = shifts_new (0); |
if (!state->shifts) |
339 |
if (!sp->errs) |
state_shifts_set (state, 0, 0); |
340 |
sp->errs = errs_new (0); |
if (!state->errs) |
341 |
if (!sp->reductions) |
state->errs = errs_new (0); |
342 |
sp->reductions = reductions_new (0); |
if (!state->reductions) |
343 |
|
state->reductions = reductions_new (0); |
344 |
|
|
345 |
states[sp->number] = sp; |
states[state->number] = state; |
346 |
|
|
347 |
|
first_state = this->next; |
348 |
|
free (this); |
349 |
} |
} |
350 |
|
first_state = NULL; |
351 |
|
last_state = NULL; |
352 |
} |
} |
353 |
|
|
354 |
|
|
360 |
void |
void |
361 |
generate_states (void) |
generate_states (void) |
362 |
{ |
{ |
363 |
|
state_list_t *list = NULL; |
364 |
allocate_storage (); |
allocate_storage (); |
365 |
new_closure (nritems); |
new_closure (nritems); |
366 |
new_states (); |
new_states (); |
367 |
|
list = first_state; |
368 |
|
|
369 |
while (this_state) |
while (list) |
370 |
{ |
{ |
371 |
|
state_t *state = list->state; |
372 |
if (trace_flag) |
if (trace_flag) |
373 |
fprintf (stderr, "Processing state %d (reached by %s)\n", |
fprintf (stderr, "Processing state %d (reached by %s)\n", |
374 |
this_state->number, |
state->number, |
375 |
symbol_tag_get (symbols[this_state->accessing_symbol])); |
symbol_tag_get (symbols[state->accessing_symbol])); |
376 |
/* Set up ruleset and itemset for the transitions out of this |
/* Set up ruleset and itemset for the transitions out of this |
377 |
state. ruleset gets a 1 bit for each rule that could reduce |
state. ruleset gets a 1 bit for each rule that could reduce |
378 |
now. itemset gets a vector of all the items that could be |
now. itemset gets a vector of all the items that could be |
379 |
accepted next. */ |
accepted next. */ |
380 |
closure (this_state->items, this_state->nitems); |
closure (state->items, state->nitems); |
381 |
/* record the reductions allowed out of this state */ |
/* Record the reductions allowed out of this state. */ |
382 |
save_reductions (); |
save_reductions (state); |
383 |
/* find the itemsets of the states that shifts can reach */ |
/* Find the itemsets of the states that shifts can reach. */ |
384 |
new_itemsets (); |
new_itemsets (state); |
385 |
/* find or create the core structures for those states */ |
/* Find or create the core structures for those states. */ |
386 |
append_states (); |
append_states (state); |
387 |
|
|
388 |
/* create the shifts structures for the shifts to those states, |
/* Create the shifts structures for the shifts to those states, |
389 |
now that the state numbers transitioning to are known */ |
now that the state numbers transitioning to are known. */ |
390 |
save_shifts (); |
state_shifts_set (state, nshifts, shiftset); |
391 |
|
|
392 |
/* states are queued when they are created; process them all */ |
/* States are queued when they are created; process them all. |
393 |
this_state = this_state->next; |
*/ |
394 |
|
list = list->next; |
395 |
} |
} |
396 |
|
|
397 |
/* discard various storage */ |
/* discard various storage */ |