52 |
static int *kernel_size = NULL; |
static int *kernel_size = NULL; |
53 |
static item_number_t *kernel_items = NULL; |
static item_number_t *kernel_items = NULL; |
54 |
|
|
|
/* hash table for states, to recognize equivalent ones. */ |
|
|
|
|
|
#define STATE_HASH_SIZE 1009 |
|
|
static state_t **state_hash = NULL; |
|
|
|
|
55 |
|
|
56 |
static void |
static void |
57 |
allocate_itemsets (void) |
allocate_itemsets (void) |
102 |
|
|
103 |
shiftset = XCALLOC (state_number_t, nsyms); |
shiftset = XCALLOC (state_number_t, nsyms); |
104 |
redset = XCALLOC (short, nrules + 1); |
redset = XCALLOC (short, nrules + 1); |
105 |
state_hash = XCALLOC (state_t *, STATE_HASH_SIZE); |
state_hash_new (); |
106 |
shift_symbol = XCALLOC (symbol_number_t, nsyms); |
shift_symbol = XCALLOC (symbol_number_t, nsyms); |
107 |
} |
} |
108 |
|
|
116 |
free (kernel_base); |
free (kernel_base); |
117 |
free (kernel_size); |
free (kernel_size); |
118 |
XFREE (kernel_items); |
XFREE (kernel_items); |
119 |
free (state_hash); |
state_hash_free (); |
120 |
} |
} |
121 |
|
|
122 |
|
|
180 |
nstates, symbol, symbol_tag_get (symbols[symbol])); |
nstates, symbol, symbol_tag_get (symbols[symbol])); |
181 |
|
|
182 |
res = state_new (symbol, core_size, core); |
res = state_new (symbol, core_size, core); |
183 |
|
state_hash_insert (res); |
184 |
|
|
185 |
/* If this is the eoftoken, and this is not the initial state, then |
/* If this is the eoftoken, and this is not the initial state, then |
186 |
this is the final state. */ |
this is the final state. */ |
206 |
static state_number_t |
static state_number_t |
207 |
get_state (symbol_number_t symbol, size_t core_size, item_number_t *core) |
get_state (symbol_number_t symbol, size_t core_size, item_number_t *core) |
208 |
{ |
{ |
|
int key; |
|
|
size_t i; |
|
209 |
state_t *sp; |
state_t *sp; |
210 |
|
|
211 |
if (trace_flag) |
if (trace_flag) |
213 |
this_state->number, symbol, |
this_state->number, symbol, |
214 |
symbol_tag_get (symbols[symbol])); |
symbol_tag_get (symbols[symbol])); |
215 |
|
|
216 |
/* Add up the target state's active item numbers to get a hash key. |
sp = state_hash_lookup (core_size, core); |
217 |
*/ |
if (!sp) |
218 |
key = 0; |
sp = new_state (symbol, core_size, core); |
|
for (i = 0; i < core_size; ++i) |
|
|
key += core[i]; |
|
|
key = key % STATE_HASH_SIZE; |
|
|
sp = state_hash[key]; |
|
|
|
|
|
if (sp) |
|
|
{ |
|
|
int found = 0; |
|
|
while (!found) |
|
|
{ |
|
|
if (sp->nitems == core_size) |
|
|
{ |
|
|
found = 1; |
|
|
for (i = 0; i < core_size; ++i) |
|
|
if (core[i] != sp->items[i]) |
|
|
found = 0; |
|
|
} |
|
|
|
|
|
if (!found) |
|
|
{ |
|
|
if (sp->link) |
|
|
{ |
|
|
sp = sp->link; |
|
|
} |
|
|
else /* bucket exhausted and no match */ |
|
|
{ |
|
|
sp = sp->link = new_state (symbol, core_size, core); |
|
|
found = 1; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
else /* bucket is empty */ |
|
|
{ |
|
|
state_hash[key] = sp = new_state (symbol, core_size, core); |
|
|
} |
|
219 |
|
|
220 |
if (trace_flag) |
if (trace_flag) |
221 |
fprintf (stderr, "Exiting get_state => %d\n", sp->number); |
fprintf (stderr, "Exiting get_state => %d\n", sp->number); |
344 |
} |
} |
345 |
} |
} |
346 |
|
|
347 |
|
|
348 |
/*-------------------------------------------------------------------. |
/*-------------------------------------------------------------------. |
349 |
| Compute the nondeterministic finite state machine (see state.h for | |
| Compute the nondeterministic finite state machine (see state.h for | |
350 |
| details) from the grammar. | |
| details) from the grammar. | |