Example #1
0
/**
 * A debug printing of a SingleGraph.
 */
void print_graph(SingleGraph g) {
u_printf("--------------------------------\n");
if (g==NULL) {
   u_printf("NULL graph\n");
   u_printf("--------------------------------\n");
   return;
}
for (int i=0;i<g->number_of_states;i++) {
   SingleGraphState s=g->states[i];
   if (is_initial_state(s)) {
      u_printf("-> ");
   } else {u_printf("   ");}
   if (is_final_state(s)) {
      u_printf("%d t ",i);
   } else {
      u_printf("%d : ",i);
   }
   u_printf("(def %d) \n\t",s->default_state);
   Transition* t=s->outgoing_transitions;
   while (t!=NULL) {
      symbols_dump((symbol_t*)t->label);
      u_printf(",%d ",t->state_number);
      t=t->next;
   }
   u_printf("\n\n");
}
u_printf("--------------------------------\n");
}
/**
 * We create a copy of the given graph using the following rules if full_simplification is not null:
 * - <E> transitions and graph calls are kept
 * - all right contexts are ignored, replaced by an epsilon transition
 * - all tags that don't match anything in the text (like $* $< and $>) are kept,
 *   because they can be involved into a E loop. We also add a real E transition.
 * - all other transitions that matches something from the text are removed
 *
 * As a consequence, the resulting graph is only made of real E transitions,
 * pseudo-E transitions, and graph calls and we can use it as follows:
 * - if no final state is accessible, it means that the graph cannot match E
 * - if the initial state is final, it means that the graph match E
 * - otherwise, we don't know yet
 *
 *
 * If full_simplification is null, we have to create a condition graph suitable for
 * E loop and left recursion detection. For that purpose, we keep the graph as is,
 * with only one modification: adding an E transition to skip right contexts. But still,
 * we keep the context, because we also have to look at it for E loops and left recursions.
 *
 */
static SingleGraph create_condition_graph(Fst2* fst2,int graph,int full_simplification) {
SingleGraph g=new_SingleGraph(INT_TAGS);
int initial_state=fst2->initial_states[graph];
int n_states=fst2->number_of_states_per_graphs[graph];
for (int i=initial_state;i<initial_state+n_states;i++) {
	SingleGraphState dst=add_state(g);
	Fst2State src=fst2->states[i];
	if (is_initial_state(src)) {
		set_initial_state(dst);
	}
	if (is_final_state(src)) {
		set_final_state(dst);
	}
	Transition* t=src->transitions;
	while (t!=NULL) {
		if (full_simplification) {
			deal_with_transition_v1(fst2,t,dst,initial_state);
		} else {
			deal_with_transition_v2(fst2,t,dst,initial_state);
		}
		t=t->next;
	}
}
clean_condition_graph(g);
return g;
}
/**
 * Creates a SingleGraph copy of the given .fst2 subgraph, using
 * the same tag numeration.
 */
SingleGraph create_copy_of_fst2_subgraph(Fst2* fst2,int n) {
int n_states=fst2->number_of_states_per_graphs[n];
SingleGraph g=new_SingleGraph(n_states,INT_TAGS);
int shift=fst2->initial_states[n];
for (int i=0;i<n_states;i++) {
   SingleGraphState dest=add_state(g);
   Fst2State src=fst2->states[i+shift];
   if (is_initial_state(src)) {
      set_initial_state(dest);
   }
   if (is_final_state(src)) {
      set_final_state(dest);
   }
   Transition* t=src->transitions;
   while (t!=NULL) {
      add_outgoing_transition(dest,t->tag_number,t->state_number);
      t=t->next;
   }
}
return g;
}