static void memoize_e_closure(struct fsm_state *fsm) { int i, state, laststate, *redcheck; struct e_closure_memo *ptr; e_closure_memo = xxcalloc(num_states,sizeof(struct e_closure_memo)); marktable = xxcalloc(num_states,sizeof(int)); /* Table for avoiding redundant epsilon arcs in closure */ redcheck = xxmalloc(num_states*sizeof(int)); for (i=0; i < num_states; i++) { ptr = e_closure_memo+i; ptr->state = i; ptr->target = NULL; *(redcheck+i) = -1; } laststate = -1; for (i=0; ;i++) { state = (fsm+i)->state_no; if (state != laststate) { if (!int_stack_isempty()) { deterministic = 0; ptr = e_closure_memo+laststate; ptr->target = e_closure_memo+int_stack_pop(); while (!int_stack_isempty()) { ptr->next = xxmalloc(sizeof(struct e_closure_memo)); ptr->next->state = laststate; ptr->next->target = e_closure_memo+int_stack_pop(); ptr->next->next = NULL; ptr = ptr->next; } } } if (state == -1) { break; } if ((fsm+i)->target == -1) { continue; } /* Check if we have a redundant epsilon arc */ if ((fsm+i)->in == EPSILON && (fsm+i)->out == EPSILON) { if (*(redcheck+((fsm+i)->target)) != (fsm+i)->state_no) { if ((fsm+i)->target != (fsm+i)->state_no) { int_stack_push((fsm+i)->target); *(redcheck+((fsm+i)->target)) = (fsm+i)->state_no; } } laststate = state; } } xxfree(redcheck); }
int cmds_scoped_endif(void) { if(is_at_scope_bottom(&if_levels)) { return 1; } int_stack_pop(&if_levels); return 0; }
static int next_unmarked(void) { if ((int_stack_isempty())) return -1; return(int_stack_pop()); if ((T_limit <= T_last_unmarked + 1) || (T_ptr+T_last_unmarked+1)->size == 0) { return -1; } else { T_last_unmarked++; return(T_last_unmarked); } }
int commands_scope_finish(void) { if(!is_at_scope_bottom(&if_levels)) { status_bar_error("Missing :endif"); int_stack_pop_seq(&if_levels, IF_SCOPE_GUARD); return 1; } int_stack_pop(&if_levels); return 0; }
struct fsm *fsm_topsort (struct fsm *net) { /* We topologically sort the network by looking for a state */ /* with inverse count 0. We then examine all the arcs from that */ /* state, and decrease the target invcounts. If we find a new */ /* state with invcount 0, we push that on the stack to be treated */ /* If the graph is cyclic, one of two things will happen: */ /* (1) We fail to find a state with invcount 0 before we've treated */ /* all states */ /* (2) A state under treatment has an arc to a state already treated */ /* or itself (we mark a state as treated as soon as we start */ /* working on it). */ /* Of course we also count the number of paths in the network. */ int i, j, curr_state, *statemap, treatcount, *order, lc, *newnum, newtarget, newstate; unsigned short int *invcount; unsigned char *treated, overflow; long long grand_pathcount, *pathcount; struct fsm_state *fsm, *curr_fsm, *new_fsm; fsm_count(net); fsm = net->states; statemap = xxmalloc(sizeof(int)*net->statecount); order = xxmalloc(sizeof(int)*net->statecount); pathcount = xxmalloc(sizeof(long long)*net->statecount); newnum = xxmalloc(sizeof(int)*net->statecount); invcount = xxmalloc(sizeof(unsigned short int)*net->statecount); treated = xxmalloc(sizeof(unsigned char)*net->statecount); for (i=0; i < net->statecount; i++) { *(statemap+i) = -1; *(invcount+i) = 0; *(treated+i) = 0; *(order+i) = 0; *(pathcount+i) = 0; } for (i=0, lc=0; (fsm+i)->state_no != -1; i++) { lc++; if ((fsm+i)->target != -1) { (*(invcount+(fsm+i)->target))++; /* Do a fast check here to see if we have a selfloop */ if ((fsm+i)->state_no == (fsm+i)->target) { net->pathcount = PATHCOUNT_CYCLIC; net->is_loop_free = 0; goto cyclic; } } if (*(statemap+(fsm+i)->state_no) == -1) { *(statemap+(fsm+i)->state_no) = i; } } treatcount = net->statecount; int_stack_clear(); int_stack_push(0); grand_pathcount = 0; *(pathcount+0) = 1; overflow = 0; for (i=0 ; !int_stack_isempty(); i++) { /* Treat a state */ curr_state = int_stack_pop(); *(treated+curr_state) = 1; *(order+i) = curr_state; *(newnum+curr_state) = i; treatcount--; curr_fsm = fsm+*(statemap+curr_state); while (curr_fsm->state_no == curr_state) { if (curr_fsm->target != -1 ) { (*(invcount+(curr_fsm->target)))--; /* Check if we overflow the path counter */ if (!overflow) { *(pathcount+(curr_fsm->target)) += *(pathcount+curr_state); if ((*(pathcount+(curr_fsm->target)) < 0)) { overflow = 1; } } /* Case (1) for cyclic */ if (*(treated+(curr_fsm)->target) == 1) { net->pathcount = PATHCOUNT_CYCLIC; net->is_loop_free = 0; goto cyclic; } if ( *(invcount+(curr_fsm->target)) == 0) { int_stack_push(curr_fsm->target); } } curr_fsm++; } } /* Case (2) */ if (treatcount > 0) { net->pathcount = PATHCOUNT_CYCLIC; net->is_loop_free = 0; goto cyclic; } new_fsm = xxmalloc(sizeof(struct fsm_state) * (lc+1)); for (i=0, j=0 ; i < net->statecount; i++) { curr_state = *(order+i); curr_fsm = fsm+*(statemap+curr_state); if (curr_fsm->final_state == 1 && !overflow) { grand_pathcount += *(pathcount + curr_state); if (grand_pathcount < 0) overflow = 1; } for (; curr_fsm->state_no == curr_state; curr_fsm++) { newstate = curr_fsm->state_no == -1 ? -1 : *(newnum+(curr_fsm->state_no)); newtarget = curr_fsm->target == -1 ? -1 : *(newnum+(curr_fsm->target)); add_fsm_arc(new_fsm, j, newstate, curr_fsm->in, curr_fsm->out, newtarget, curr_fsm->final_state, curr_fsm->start_state); j++; } } add_fsm_arc(new_fsm, j, -1, -1, -1, -1, -1, -1); net->states = new_fsm; net->pathcount = grand_pathcount; net->is_loop_free = 1; if (overflow == 1) { net->pathcount = PATHCOUNT_OVERFLOW; } xxfree(fsm); cyclic: xxfree(statemap); xxfree(order); xxfree(pathcount); xxfree(newnum); xxfree(invcount); xxfree(treated); int_stack_clear(); return(net); }
struct fsm *fsm_coaccessible(struct fsm *net) { struct invtable *inverses, *temp_i, *temp_i_prev, *current_ptr; int i, j, s, t, *coacc, current_state, markcount, *mapping, terminate, new_linecount, new_arccount, *added, old_statecount; struct fsm_state *fsm; fsm = net->states; new_arccount = 0; /* printf("statecount %i\n",net->statecount); */ old_statecount = net->statecount; inverses = xxcalloc(net->statecount, sizeof(struct invtable)); coacc = xxmalloc(sizeof(int)*(net->statecount)); mapping = xxmalloc(sizeof(int)*(net->statecount)); added = xxmalloc(sizeof(int)*(net->statecount)); for (i=0; i < (net->statecount); i++) { (inverses+i)->state = -1; *(coacc+i) = 0; *(added+i) = 0; } for (i=0; (fsm+i)->state_no != -1; i++) { s = (fsm+i)->state_no; t = (fsm+i)->target; if (t != -1 && s != t) { if (((inverses+t)->state) == -1) { (inverses+t)->state = s; } else { temp_i = xxmalloc(sizeof(struct invtable)); temp_i->next = (inverses+t)->next; (inverses+t)->next = temp_i; temp_i->state = s; } } } /* Push & mark finals */ markcount = 0; for (i=0; (fsm+i)->state_no != -1; i++) { if ((fsm+i)->final_state && (!*(coacc+((fsm+i)->state_no)))) { int_stack_push((fsm+i)->state_no); *(coacc+(fsm+i)->state_no) = 1; markcount++; } } terminate = 0; while(!int_stack_isempty()) { current_state = int_stack_pop(); current_ptr = inverses+current_state; while(current_ptr != NULL && current_ptr->state != -1) { if (!*(coacc+(current_ptr->state))) { *(coacc+(current_ptr->state)) = 1; int_stack_push(current_ptr->state); markcount++; } current_ptr = current_ptr->next; } if (markcount >= net->statecount) { /* printf("Already coacc\n"); */ terminate = 1; int_stack_clear(); break; } } if (terminate == 0) { *mapping = 0; /* state 0 always exists */ new_linecount = 0; for (i=1,j=0; i < (net->statecount);i++) { if (*(coacc+i) == 1) { j++; *(mapping+i) = j; } } for (i=0,j=0; (fsm+i)->state_no != -1; i++) { if (i > 0 && (fsm+i)->state_no != (fsm+i-1)->state_no && (fsm+i-1)->final_state && !*(added+((fsm+i-1)->state_no))) { add_fsm_arc(fsm, j++, *(mapping+((fsm+i-1)->state_no)), -1, -1, -1, 1, (fsm+i-1)->start_state); new_linecount++; *(added+((fsm+i-1)->state_no)) = 1; /* printf("addf ad %i\n",i); */ } if (*(coacc+((fsm+i)->state_no)) && (((fsm+i)->target == -1) || *(coacc+((fsm+i)->target)))) { (fsm+j)->state_no = *(mapping+((fsm+i)->state_no)); if ((fsm+i)->target == -1) { (fsm+j)->target = -1; } else { (fsm+j)->target = *(mapping+((fsm+i)->target)); } (fsm+j)->final_state = (fsm+i)->final_state; (fsm+j)->start_state = (fsm+i)->start_state; (fsm+j)->in = (fsm+i)->in; (fsm+j)->out = (fsm+i)->out; j++; new_linecount++; *(added+(fsm+i)->state_no) = 1; if ((fsm+i)->target != -1) { new_arccount++; } } } if ((i > 1) && ((fsm+i-1)->final_state) && *(added+((fsm+i-1)->state_no)) == 0) { /* printf("addf\n"); */ add_fsm_arc(fsm, j++, *(mapping+((fsm+i-1)->state_no)), -1, -1, -1, 1, (fsm+i-1)->start_state); new_linecount++; } if (new_linecount == 0) { add_fsm_arc(fsm, j++, 0, -1, -1, -1, -1, -1); } add_fsm_arc(fsm, j, -1, -1, -1, -1, -1, -1); if (markcount == 0) { /* We're dealing with the empty language */ xxfree(fsm); net->states = fsm_empty(); net->sigma = sigma_create(); } net->linecount = new_linecount; net->arccount = new_arccount; net->statecount = markcount; } /* printf("Markccount %i \n",markcount); */ for (i = 0; i < old_statecount ; i++) { for (temp_i = inverses+i; temp_i != NULL ; ) { temp_i_prev = temp_i; temp_i = temp_i->next; if (temp_i_prev != inverses+i) xxfree(temp_i_prev); } } xxfree(inverses); xxfree(coacc); xxfree(added); xxfree(mapping); net->is_pruned = YES; return(net); }