示例#1
0
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);
}
示例#2
0
int
cmds_scoped_endif(void)
{
	if(is_at_scope_bottom(&if_levels))
	{
		return 1;
	}

	int_stack_pop(&if_levels);
	return 0;
}
示例#3
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);
    }
}
示例#4
0
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;
}
示例#5
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);
}