/** * 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; }