clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name determinize.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/tmp/build/foma/foma-0.10.0+g279~a2d32b38 -resource-dir /usr/lib/llvm-16/lib/clang/16 -D _GNU_SOURCE -D foma_shared_EXPORTS -I /tmp/build/foma/foma-0.10.0+g279~a2d32b38 -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-missing-field-initializers -Wno-deprecated -Wno-unused-parameter -std=c18 -fdebug-compilation-dir=/tmp/build/foma/foma-0.10.0+g279~a2d32b38 -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/build/foma/scan-build/2024-09-11-155945-2678-1 -x c /tmp/build/foma/foma-0.10.0+g279~a2d32b38/determinize.c
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | #include <stdio.h> |
19 | #include <stdlib.h> |
20 | #include <assert.h> |
21 | #include <limits.h> |
22 | #include <stdint.h> |
23 | #include <string.h> |
24 | #include "foma.h" |
25 | |
26 | #define SUBSET_EPSILON_REMOVE 1 |
27 | #define SUBSET_DETERMINIZE 2 |
28 | #define SUBSET_TEST_STAR_FREE 3 |
29 | |
30 | #define NHASH_LOAD_LIMIT 2 /* load limit for nhash table size */ |
31 | |
32 | static int fsm_linecount, num_states, num_symbols, epsilon_symbol, *single_sigma_array, *double_sigma_array, limit, num_start_states, op; |
33 | |
34 | static _Bool *finals, deterministic, numss; |
35 | |
36 | struct e_closure_memo { |
37 | int state; |
38 | int mark; |
39 | struct e_closure_memo *target; |
40 | struct e_closure_memo *next; |
41 | }; |
42 | |
43 | static unsigned int primes[26] = {61,127,251,509,1021,2039,4093,8191,16381,32749,65521,131071,262139,524287,1048573,2097143,4194301,8388593,16777213,33554393,67108859,134217689,268435399,536870909,1073741789,2147483647}; |
44 | |
45 | static struct e_closure_memo *e_closure_memo; |
46 | |
47 | int T_last_unmarked, T_limit; |
48 | |
49 | struct nhash_list { |
50 | int setnum; |
51 | unsigned int size; |
52 | unsigned int set_offset; |
53 | struct nhash_list *next; |
54 | }; |
55 | |
56 | struct T_memo { |
57 | unsigned char finalstart; |
58 | unsigned int size; |
59 | unsigned int set_offset; |
60 | }; |
61 | |
62 | struct trans_list { |
63 | int inout; |
64 | int target; |
65 | } *trans_list_determinize; |
66 | |
67 | struct trans_array { |
68 | struct trans_list *transitions; |
69 | unsigned int size; |
70 | unsigned int tail; |
71 | } *trans_array_determinize; |
72 | |
73 | static struct T_memo *T_ptr; |
74 | |
75 | static int nhash_tablesize, nhash_load, current_setnum, *e_table, *marktable, *temp_move, mainloop, maxsigma, *set_table, set_table_size, star_free_mark; |
76 | static unsigned int set_table_offset; |
77 | static struct nhash_list *table; |
78 | |
79 | extern int add_fsm_arc(struct fsm_state *fsm, int offset, int state_no, int in, int out, int target, int final_state, int start_state); |
80 | |
81 | static void init(struct fsm *net); |
82 | INLINE static int e_closure(int states); |
83 | INLINE static int set_lookup(int *lookup_table, int size); |
84 | static int initial_e_closure(struct fsm *network); |
85 | static void memoize_e_closure(struct fsm_state *fsm); |
86 | static int next_unmarked(void); |
87 | static void single_symbol_to_symbol_pair(int symbol, int *symbol_in, int *symbol_out); |
88 | static int symbol_pair_to_single_symbol(int in, int out); |
89 | static void sigma_to_pairs(struct fsm *net); |
90 | static int nhash_find_insert(int *set, int setsize); |
91 | INLINE static int hashf(int *set, int setsize); |
92 | static int nhash_insert(int hashval, int *set, int setsize); |
93 | static void nhash_rebuild_table (); |
94 | static void nhash_init (int initial_size); |
95 | static void nhash_free(struct nhash_list *nptr, int size); |
96 | static void e_closure_free(); |
97 | static void init_trans_array(struct fsm *net); |
98 | static struct fsm *fsm_subset(struct fsm *net, int operation); |
99 | |
100 | struct fsm *fsm_epsilon_remove(struct fsm *net) { |
101 | return(fsm_subset(net, SUBSET_EPSILON_REMOVE)); |
102 | } |
103 | |
104 | struct fsm *fsm_determinize(struct fsm *net) { |
105 | return(fsm_subset(net, SUBSET_DETERMINIZE)); |
| |
106 | } |
107 | |
108 | static struct fsm *fsm_subset(struct fsm *net, int operation) { |
109 | |
110 | int T, U; |
111 | |
112 | if (net->is_deterministic == YES && operation != SUBSET_TEST_STAR_FREE) { |
| 2 | | Assuming field 'is_deterministic' is not equal to YES | |
|
113 | return(net); |
114 | } |
115 | |
116 | op = operation; |
117 | fsm_count(net); |
118 | num_states = net->statecount; |
119 | deterministic = 1; |
120 | init(net); |
| |
121 | nhash_init((num_states < 12) ? 6 : num_states/2); |
122 | |
123 | T = initial_e_closure(net); |
124 | |
125 | int_stack_clear(); |
126 | |
127 | if (deterministic == 1 && epsilon_symbol == -1 && num_start_states == 1 && numss == 0) { |
128 | net->is_deterministic = YES; |
129 | net->is_epsilon_free = YES; |
130 | nhash_free(table, nhash_tablesize); |
131 | free(T_ptr); |
132 | free(e_table); |
133 | free(trans_list_determinize); |
134 | free(trans_array_determinize); |
135 | free(double_sigma_array); |
136 | free(single_sigma_array); |
137 | free(finals); |
138 | free(temp_move); |
139 | free(set_table); |
140 | return(net); |
141 | } |
142 | |
143 | if (operation == SUBSET_EPSILON_REMOVE && epsilon_symbol == -1) { |
144 | net->is_epsilon_free = YES; |
145 | nhash_free(table, nhash_tablesize); |
146 | free(T_ptr); |
147 | free(e_table); |
148 | free(trans_list_determinize); |
149 | free(trans_array_determinize); |
150 | free(double_sigma_array); |
151 | free(single_sigma_array); |
152 | free(finals); |
153 | free(temp_move); |
154 | free(set_table); |
155 | return(net); |
156 | } |
157 | |
158 | if (operation == SUBSET_TEST_STAR_FREE) { |
159 | fsm_state_init(sigma_max(net->sigma)+1); |
160 | star_free_mark = 0; |
161 | } else { |
162 | fsm_state_init(sigma_max(net->sigma)); |
163 | free(net->states); |
164 | } |
165 | |
166 | |
167 | |
168 | do { |
169 | int i, j, tail, setsize, *theset, stateno, has_trans, minsym, next_minsym, trgt, symbol_in, symbol_out; |
170 | struct trans_list *transitions; |
171 | struct trans_array *tptr; |
172 | |
173 | fsm_state_set_current_state(T, (T_ptr+T)->finalstart, T == 0 ? 1 : 0); |
174 | |
175 | |
176 | setsize = (T_ptr+T)->size; |
177 | theset = set_table+(T_ptr+T)->set_offset; |
178 | minsym = INT_MAX; |
179 | has_trans = 0; |
180 | for (i = 0; i < setsize; i++) { |
181 | stateno = *(theset+i); |
182 | tptr = trans_array_determinize+stateno; |
183 | tptr->tail = 0; |
184 | if (tptr->size == 0) |
185 | continue; |
186 | if ((tptr->transitions)->inout < minsym) { |
187 | minsym = (tptr->transitions)->inout; |
188 | has_trans = 1; |
189 | } |
190 | } |
191 | if (!has_trans) { |
192 | |
193 | fsm_state_end_state(); |
194 | continue; |
195 | } |
196 | |
197 | |
198 | |
199 | for (next_minsym = INT_MAX; minsym != INT_MAX ; minsym = next_minsym, next_minsym = INT_MAX) { |
200 | theset = set_table+(T_ptr+T)->set_offset; |
201 | |
202 | for (i = 0, j = 0 ; i < setsize; i++) { |
203 | |
204 | stateno = *(theset+i); |
205 | tptr = trans_array_determinize+stateno; |
206 | tail = tptr->tail; |
207 | transitions = (tptr->transitions)+tail; |
208 | |
209 | while (tail < tptr->size && transitions->inout == minsym) { |
210 | trgt = transitions->target; |
211 | if (*(e_table+(trgt)) != mainloop) { |
212 | *(e_table+(trgt)) = mainloop; |
213 | *(temp_move+j) = trgt; |
214 | j++; |
215 | |
216 | if (operation == SUBSET_EPSILON_REMOVE) { |
217 | mainloop++; |
218 | if ((U = e_closure(j)) != -1) { |
219 | single_symbol_to_symbol_pair(minsym, &symbol_in, &symbol_out); |
220 | fsm_state_add_arc(T, symbol_in, symbol_out, U, (T_ptr+T)->finalstart, T == 0 ? 1 : 0); |
221 | j = 0; |
222 | } |
223 | } |
224 | } |
225 | tail++; |
226 | transitions++; |
227 | } |
228 | |
229 | tptr->tail = tail; |
230 | |
231 | if (tail == tptr->size) |
232 | continue; |
233 | |
234 | if (transitions->inout < next_minsym) { |
235 | next_minsym = transitions->inout; |
236 | } |
237 | } |
238 | if (operation == SUBSET_DETERMINIZE) { |
239 | mainloop++; |
240 | if ((U = e_closure(j)) != -1) { |
241 | single_symbol_to_symbol_pair(minsym, &symbol_in, &symbol_out); |
242 | fsm_state_add_arc(T, symbol_in, symbol_out, U, (T_ptr+T)->finalstart, T == 0 ? 1 : 0); |
243 | } |
244 | } |
245 | if (operation == SUBSET_TEST_STAR_FREE) { |
246 | mainloop++; |
247 | if ((U = e_closure(j)) != -1) { |
248 | single_symbol_to_symbol_pair(minsym, &symbol_in, &symbol_out); |
249 | fsm_state_add_arc(T, symbol_in, symbol_out, U, (T_ptr+T)->finalstart, T == 0 ? 1 : 0); |
250 | if (star_free_mark == 1) { |
251 | |
252 | star_free_mark = 0; |
253 | } |
254 | } |
255 | } |
256 | } |
257 | |
258 | fsm_state_end_state(); |
259 | } while ((T = next_unmarked()) != -1); |
260 | |
261 | |
262 | nhash_free(table, nhash_tablesize); |
263 | free(set_table); |
264 | free(T_ptr); |
265 | free(temp_move); |
266 | free(e_table); |
267 | free(trans_list_determinize); |
268 | free(trans_array_determinize); |
269 | |
270 | if (epsilon_symbol != -1) |
271 | e_closure_free(); |
272 | free(double_sigma_array); |
273 | free(single_sigma_array); |
274 | free(finals); |
275 | fsm_state_close(net); |
276 | return(net); |
277 | } |
278 | |
279 | static void init(struct fsm *net) { |
280 | |
281 | |
282 | |
283 | e_table = calloc(net->statecount,sizeof(int)); |
284 | |
285 | |
286 | |
287 | mainloop = 1; |
288 | |
289 | |
290 | |
291 | |
292 | |
293 | temp_move = malloc((net->statecount + 1) *sizeof(int)); |
294 | |
295 | |
296 | |
297 | |
298 | limit = next_power_of_two(net->linecount); |
299 | fsm_linecount = 0; |
300 | sigma_to_pairs(net); |
| 4 | | Calling 'sigma_to_pairs' | |
|
301 | |
302 | |
303 | |
304 | |
305 | |
306 | |
307 | |
308 | T_last_unmarked = 0; |
309 | T_limit = next_power_of_two(num_states); |
310 | |
311 | T_ptr = calloc(T_limit,sizeof(struct T_memo)); |
312 | |
313 | |
314 | |
315 | |
316 | |
317 | set_table_size = next_power_of_two(num_states); |
318 | set_table = malloc(set_table_size*sizeof(int)); |
319 | set_table_offset = 0; |
320 | |
321 | init_trans_array(net); |
322 | } |
323 | |
324 | static int trans_sort_cmp(const void *a, const void *b) { |
325 | return (((const struct trans_list *)a)->inout - ((const struct trans_list *)b)->inout); |
326 | } |
327 | |
328 | static void init_trans_array(struct fsm *net) { |
329 | struct trans_list *arrptr; |
330 | struct fsm_state *fsm; |
331 | int i, j, laststate, lastsym, inout, size, state; |
332 | |
333 | arrptr = trans_list_determinize = malloc(net->linecount * sizeof(struct trans_list)); |
334 | trans_array_determinize = calloc(net->statecount, sizeof(struct trans_array)); |
335 | |
336 | laststate = -1; |
337 | fsm = net->states; |
338 | |
339 | for (i=0, size = 0; (fsm+i)->state_no != -1; i++) { |
340 | state = (fsm+i)->state_no; |
341 | if (state != laststate) { |
342 | if (laststate != -1) { |
343 | (trans_array_determinize+laststate)->size = size; |
344 | } |
345 | (trans_array_determinize+state)->transitions = arrptr; |
346 | size = 0; |
347 | } |
348 | laststate = state; |
349 | |
350 | if ((fsm+i)->target == -1) |
351 | continue; |
352 | inout = symbol_pair_to_single_symbol((fsm+i)->in, (fsm+i)->out); |
353 | if (inout == epsilon_symbol) |
354 | continue; |
355 | |
356 | arrptr->inout = inout; |
357 | arrptr->target = (fsm+i)->target; |
358 | arrptr++; |
359 | size++; |
360 | } |
361 | |
362 | if (laststate != -1) { |
363 | (trans_array_determinize+laststate)->size = size; |
364 | } |
365 | |
366 | for (i=0; i < net->statecount; i++) { |
367 | arrptr = (trans_array_determinize+i)->transitions; |
368 | size = (trans_array_determinize+i)->size; |
369 | if (size > 1) { |
370 | qsort(arrptr, size, sizeof(struct trans_list), trans_sort_cmp); |
371 | lastsym = -1; |
372 | |
373 | for (j=0; j < size; j++) { |
374 | if ((arrptr+j)->inout == lastsym) |
375 | deterministic = 0; |
376 | lastsym = (arrptr+j)->inout; |
377 | } |
378 | } |
379 | } |
380 | } |
381 | |
382 | INLINE static int e_closure(int states) { |
383 | |
384 | int i, set_size; |
385 | struct e_closure_memo *ptr; |
386 | |
387 | |
388 | |
389 | |
390 | if (epsilon_symbol == -1) |
391 | return(set_lookup(temp_move, states)); |
392 | |
393 | if (states == 0) |
394 | return -1; |
395 | |
396 | mainloop--; |
397 | |
398 | set_size = states; |
399 | |
400 | for (i = 0; i < states; i++) { |
401 | |
402 | |
403 | ptr = e_closure_memo + *(temp_move+i); |
404 | if (ptr->target == NULL) |
405 | continue; |
406 | ptr_stack_push(ptr); |
407 | |
408 | while (!(ptr_stack_isempty())) { |
409 | ptr = ptr_stack_pop(); |
410 | |
411 | if (*(marktable+ptr->state) == mainloop) |
412 | continue; |
413 | |
414 | ptr->mark = mainloop; |
415 | *(marktable+ptr->state) = mainloop; |
416 | |
417 | if (*(e_table+(ptr->state)) != mainloop) { |
418 | *(temp_move+set_size) = ptr->state; |
419 | *(e_table+(ptr->state)) = mainloop; |
420 | set_size++; |
421 | } |
422 | |
423 | if (ptr->target == NULL) |
424 | continue; |
425 | |
426 | |
427 | for (; ptr != NULL ; ptr = ptr->next) { |
428 | if (ptr->target->mark != mainloop) { |
429 | |
430 | ptr->target->mark = mainloop; |
431 | ptr_stack_push(ptr->target); |
432 | } |
433 | } |
434 | } |
435 | } |
436 | |
437 | mainloop++; |
438 | return(set_lookup(temp_move, set_size)); |
439 | } |
440 | |
441 | INLINE static int set_lookup (int *lookup_table, int size) { |
442 | |
443 | |
444 | |
445 | |
446 | return(nhash_find_insert(lookup_table, size)); |
447 | |
448 | } |
449 | |
450 | void add_T_ptr(int setnum, int setsize, unsigned int theset, int fs) { |
451 | |
452 | int i; |
453 | if (setnum >= T_limit) { |
454 | T_limit *= 2; |
455 | T_ptr = realloc(T_ptr, sizeof(struct T_memo)*T_limit); |
456 | for (i=setnum; i < T_limit; i++) { |
457 | (T_ptr+i)->size = 0; |
458 | } |
459 | } |
460 | |
461 | (T_ptr + setnum)->size = setsize; |
462 | (T_ptr + setnum)->set_offset = theset; |
463 | (T_ptr + setnum)->finalstart = fs; |
464 | int_stack_push(setnum); |
465 | |
466 | } |
467 | |
468 | static int initial_e_closure(struct fsm *net) { |
469 | |
470 | struct fsm_state *fsm; |
471 | int i,j; |
472 | |
473 | finals = calloc(num_states, sizeof(_Bool)); |
474 | |
475 | num_start_states = 0; |
476 | fsm = net->states; |
477 | |
478 | |
479 | for (i=0,j=0; (fsm+i)->state_no != -1; i++) { |
480 | if ((fsm+i)->final_state) { |
481 | finals[(fsm+i)->state_no] = 1; |
482 | } |
483 | |
484 | if ((op == SUBSET_TEST_STAR_FREE) || ((fsm+i)->start_state)) { |
485 | if (*(e_table+((fsm+i)->state_no)) != mainloop) { |
486 | num_start_states++; |
487 | numss = (fsm+i)->state_no; |
488 | *(e_table+((fsm+i)->state_no)) = mainloop; |
489 | *(temp_move+j) = (fsm+i)->state_no; |
490 | j++; |
491 | } |
492 | } |
493 | } |
494 | mainloop++; |
495 | |
496 | if (epsilon_symbol != -1) { |
497 | memoize_e_closure(fsm); |
498 | } |
499 | return(e_closure(j)); |
500 | } |
501 | |
502 | static void memoize_e_closure(struct fsm_state *fsm) { |
503 | |
504 | int i, state, laststate, *redcheck; |
505 | struct e_closure_memo *ptr; |
506 | |
507 | e_closure_memo = calloc(num_states,sizeof(struct e_closure_memo)); |
508 | marktable = calloc(num_states,sizeof(int)); |
509 | |
510 | redcheck = malloc(num_states*sizeof(int)); |
511 | |
512 | for (i=0; i < num_states; i++) { |
513 | ptr = e_closure_memo+i; |
514 | ptr->state = i; |
515 | ptr->target = NULL; |
516 | *(redcheck+i) = -1; |
517 | } |
518 | |
519 | laststate = -1; |
520 | |
521 | for (i=0; ;i++) { |
522 | |
523 | state = (fsm+i)->state_no; |
524 | |
525 | if (state != laststate) { |
526 | if (!int_stack_isempty()) { |
527 | deterministic = 0; |
528 | ptr = e_closure_memo+laststate; |
529 | ptr->target = e_closure_memo+int_stack_pop(); |
530 | while (!int_stack_isempty()) { |
531 | ptr->next = malloc(sizeof(struct e_closure_memo)); |
532 | ptr->next->state = laststate; |
533 | ptr->next->target = e_closure_memo+int_stack_pop(); |
534 | ptr->next->next = NULL; |
535 | ptr = ptr->next; |
536 | } |
537 | } |
538 | } |
539 | if (state == -1) { |
540 | break; |
541 | } |
542 | if ((fsm+i)->target == -1) { |
543 | continue; |
544 | } |
545 | |
546 | if ((fsm+i)->in == EPSILON && (fsm+i)->out == EPSILON) { |
547 | if (*(redcheck+((fsm+i)->target)) != (fsm+i)->state_no) { |
548 | if ((fsm+i)->target != (fsm+i)->state_no) { |
549 | int_stack_push((fsm+i)->target); |
550 | *(redcheck+((fsm+i)->target)) = (fsm+i)->state_no; |
551 | } |
552 | } |
553 | laststate = state; |
554 | } |
555 | } |
556 | free(redcheck); |
557 | } |
558 | |
559 | static int next_unmarked(void) { |
560 | if ((int_stack_isempty())) |
561 | return -1; |
562 | return(int_stack_pop()); |
563 | |
564 | if ((T_limit <= T_last_unmarked + 1) || (T_ptr+T_last_unmarked+1)->size == 0) { |
565 | return -1; |
566 | } else { |
567 | T_last_unmarked++; |
568 | return(T_last_unmarked); |
569 | } |
570 | } |
571 | |
572 | static void single_symbol_to_symbol_pair(int symbol, int *symbol_in, int *symbol_out) { |
573 | |
574 | *symbol_in = *(single_sigma_array+(symbol*2)); |
575 | *symbol_out = *(single_sigma_array+(symbol*2+1)); |
576 | |
577 | } |
578 | |
579 | static int symbol_pair_to_single_symbol(int in, int out) { |
580 | return(*(double_sigma_array+maxsigma*in+out)); |
581 | } |
582 | |
583 | static void sigma_to_pairs(struct fsm *net) { |
584 | |
585 | int i, j, x, y, z, next_x = 0; |
586 | struct fsm_state *fsm; |
587 | |
588 | fsm = net->states; |
589 | |
590 | epsilon_symbol = -1; |
591 | maxsigma = sigma_max(net->sigma); |
592 | maxsigma++; |
593 | |
594 | single_sigma_array = malloc(2*maxsigma*maxsigma*sizeof(int)); |
595 | double_sigma_array = malloc(maxsigma*maxsigma*sizeof(int)); |
| 5 | | Storing uninitialized value | |
|
596 | |
597 | for (i=0; i < maxsigma; i++) { |
| 6 | | Assuming 'i' is < 'maxsigma' | |
|
| 7 | | Loop condition is true. Entering loop body | |
|
| 11 | | Loop condition is false. Execution continues on line 617 | |
|
598 | for (j=0; j< maxsigma; j++) { |
| 8 | | Loop condition is true. Entering loop body | |
|
| 9 | | Assuming 'j' is >= 'maxsigma' | |
|
| 10 | | Loop condition is false. Execution continues on line 597 | |
|
599 | *(double_sigma_array+maxsigma*i+j) = -1; |
600 | } |
601 | } |
602 | |
603 | |
604 | |
605 | |
606 | |
607 | |
608 | |
609 | |
610 | |
611 | |
612 | |
613 | |
614 | |
615 | |
616 | |
617 | x = 0; |
618 | net->arity = 1; |
619 | for (i=0; (fsm+i)->state_no != -1; i++) { |
| 12 | | Assuming the condition is true | |
|
| 13 | | Loop condition is true. Entering loop body | |
|
620 | y = (fsm+i)->in; |
621 | z = (fsm+i)->out; |
622 | if ((y == -1) || (z == -1)) |
| 14 | | Assuming the condition is false | |
|
| 15 | | Assuming the condition is false | |
|
623 | continue; |
624 | if (y != z || y == UNKNOWN || z == UNKNOWN) |
| 16 | | Assuming 'y' is equal to 'z' | |
|
| 17 | | Assuming 'y' is equal to UNKNOWN | |
|
625 | net->arity = 2; |
626 | if (*(double_sigma_array+maxsigma*y+z) == -1) { |
| 18 | | The left operand of '==' is a garbage value |
|
627 | *(double_sigma_array+maxsigma*y+z) = x; |
628 | *(single_sigma_array+next_x) = y; |
629 | next_x++; |
630 | *(single_sigma_array+next_x) = z; |
631 | next_x++; |
632 | if (y == EPSILON && z == EPSILON) { |
633 | epsilon_symbol = x; |
634 | } |
635 | x++; |
636 | } |
637 | } |
638 | num_symbols = x; |
639 | } |
640 | |
641 | |
642 | |
643 | |
644 | |
645 | |
646 | static int nhash_find_insert(int *set, int setsize) { |
647 | int j, found, *currlist; |
648 | struct nhash_list *tableptr; |
649 | unsigned int hashval; |
650 | |
651 | hashval = hashf(set, setsize); |
652 | if ((table+hashval)->size == 0) { |
653 | return(nhash_insert(hashval, set, setsize)); |
654 | } else { |
655 | for (tableptr=(table+hashval); tableptr != NULL; tableptr = tableptr->next) { |
656 | if ((tableptr)->size != setsize) { |
657 | continue; |
658 | } else { |
659 | |
660 | |
661 | |
662 | for (j=0, found = 1, currlist= set_table+tableptr->set_offset; j < setsize; j++) { |
663 | if (*(e_table+(*(currlist+j))) != (mainloop-1)) { |
664 | found = 0; |
665 | break; |
666 | } |
667 | } |
668 | if (op == SUBSET_TEST_STAR_FREE && found == 1) { |
669 | for (j=0, currlist= set_table+tableptr->set_offset; j < setsize; j++) { |
670 | if (*(set+j) != *(currlist+j)) { |
671 | |
672 | star_free_mark = 1; |
673 | } |
674 | } |
675 | } |
676 | if (found == 1) { |
677 | return(tableptr->setnum); |
678 | } |
679 | } |
680 | } |
681 | |
682 | if (nhash_load / NHASH_LOAD_LIMIT > nhash_tablesize) { |
683 | nhash_rebuild_table(); |
684 | hashval = hashf(set, setsize); |
685 | } |
686 | return(nhash_insert(hashval, set, setsize)); |
687 | } |
688 | } |
689 | |
690 | INLINE static int hashf(int *set, int setsize) { |
691 | int i; |
692 | unsigned int hashval, sum = 0; |
693 | hashval = 6703271; |
694 | for (i = 0; i < setsize; i++) { |
695 | hashval = (unsigned int) (*(set+i) + 1103 * setsize) * hashval; |
696 | sum += *(set+i) + i; |
697 | } |
698 | hashval = hashval + sum * 31; |
699 | hashval = (hashval % nhash_tablesize); |
700 | return hashval; |
701 | } |
702 | |
703 | static unsigned int move_set(int *set, int setsize) { |
704 | unsigned int old_offset; |
705 | if (set_table_offset + setsize >= set_table_size) { |
706 | while (set_table_offset + setsize >= set_table_size) { |
707 | set_table_size *= 2; |
708 | } |
709 | set_table = realloc(set_table, set_table_size * sizeof(int)); |
710 | } |
711 | memcpy(set_table+set_table_offset, set, setsize * sizeof(int)); |
712 | old_offset = set_table_offset; |
713 | set_table_offset += setsize; |
714 | return(old_offset); |
715 | } |
716 | |
717 | static int nhash_insert(int hashval, int *set, int setsize) { |
718 | struct nhash_list *tableptr; |
719 | int i, fs = 0; |
720 | |
721 | current_setnum++; |
722 | tableptr = table+hashval; |
723 | |
724 | nhash_load++; |
725 | for (i = 0; i < setsize; i++) { |
726 | if (finals[*(set+i)]) |
727 | fs = 1; |
728 | } |
729 | if (tableptr->size == 0) { |
730 | |
731 | tableptr->set_offset = move_set(set, setsize); |
732 | tableptr->size = setsize; |
733 | tableptr->setnum = current_setnum; |
734 | |
735 | add_T_ptr(current_setnum, setsize, tableptr->set_offset, fs); |
736 | return(current_setnum); |
737 | } |
738 | |
739 | tableptr = malloc(sizeof(struct nhash_list)); |
740 | tableptr->next = (table+hashval)->next; |
741 | (table+hashval)->next = tableptr; |
742 | tableptr->setnum = current_setnum; |
743 | tableptr->size = setsize; |
744 | tableptr->set_offset = move_set(set, setsize); |
745 | |
746 | add_T_ptr(current_setnum, setsize, tableptr->set_offset, fs); |
747 | return(current_setnum); |
748 | } |
749 | |
750 | static void nhash_rebuild_table () { |
751 | int i, oldsize; |
752 | struct nhash_list *oldtable, *tableptr, *ntableptr, *newptr; |
753 | unsigned int hashval; |
754 | |
755 | oldtable = table; |
756 | oldsize = nhash_tablesize; |
757 | |
758 | nhash_load = 0; |
759 | for (i=0; primes[i] < nhash_tablesize; i++) { } |
760 | nhash_tablesize = primes[(i+1)]; |
761 | |
762 | table = calloc(nhash_tablesize,sizeof(struct nhash_list)); |
763 | for (i=0; i < oldsize;i++) { |
764 | if ((oldtable+i)->size == 0) { |
765 | continue; |
766 | } |
767 | tableptr = oldtable+i; |
768 | for ( ; tableptr != NULL; (tableptr = tableptr->next)) { |
769 | |
770 | hashval = hashf(set_table+tableptr->set_offset,tableptr->size); |
771 | ntableptr = table+hashval; |
772 | if (ntableptr->size == 0) { |
773 | nhash_load++; |
774 | ntableptr->size = tableptr->size; |
775 | ntableptr->set_offset = tableptr->set_offset; |
776 | ntableptr->setnum = tableptr->setnum; |
777 | ntableptr->next = NULL; |
778 | } else { |
779 | newptr = malloc(sizeof(struct nhash_list)); |
780 | newptr->next = ntableptr->next; |
781 | ntableptr->next = newptr; |
782 | newptr->setnum = tableptr->setnum; |
783 | newptr->size = tableptr->size; |
784 | newptr->set_offset = tableptr->set_offset; |
785 | } |
786 | } |
787 | } |
788 | nhash_free(oldtable, oldsize); |
789 | } |
790 | |
791 | static void nhash_init (int initial_size) { |
792 | |
793 | int i; |
794 | |
795 | for (i=0; primes[i] < initial_size; i++) { } |
796 | nhash_load = 0; |
797 | nhash_tablesize = primes[i]; |
798 | table = calloc(nhash_tablesize , sizeof(struct nhash_list)); |
799 | current_setnum = -1; |
800 | } |
801 | static void e_closure_free() { |
802 | int i; |
803 | struct e_closure_memo *eptr, *eprev; |
804 | free(marktable); |
805 | for (i=0;i < num_states; i++) { |
806 | eptr = (e_closure_memo+i)->next; |
807 | for (eprev = NULL; eptr != NULL; ) { |
808 | eprev = eptr; |
809 | eptr = eptr->next; |
810 | free(eprev); |
811 | } |
812 | |
813 | } |
814 | free(e_closure_memo); |
815 | } |
816 | |
817 | static void nhash_free(struct nhash_list *nptr, int size) { |
818 | struct nhash_list *nptr2, *nnext; |
819 | int i; |
820 | for (i=0; i < size; i++) { |
821 | for (nptr2 = (nptr+i)->next; nptr2 != NULL; nptr2 = nnext) { |
822 | nnext = nptr2->next; |
823 | free(nptr2); |
824 | } |
825 | } |
826 | free(nptr); |
827 | } |