17 |
/* along with this program; if not, write to the Free Software */ |
/* along with this program; if not, write to the Free Software */ |
18 |
/* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
/* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
19 |
|
|
|
/* $Id$ */ |
|
|
|
|
20 |
/** |
/** |
21 |
* \file automaton.c |
* \file automaton.c |
22 |
* \brief (Non)Deterministic Finite Automaton for Regexp |
* \brief (Non)Deterministic Finite Automaton for Regexp |
54 |
/* ************************************************** * |
/* ************************************************** * |
55 |
exported functions for static automata |
exported functions for static automata |
56 |
* ************************************************** */ |
* ************************************************** */ |
57 |
|
|
58 |
automaton automaton_build (int init_state, int *ptl, int *PS, struct search_RegE_list_t *list); |
automaton automaton_build (int init_state, int *ptl, int *PS, struct search_RegE_list_t *list); |
59 |
void automaton_delete (automaton a); |
void automaton_delete (automaton a); |
60 |
int automaton_get_nstate (automaton a); |
int automaton_get_nstate (automaton a); |
62 |
int automaton_get_accept (automaton a, int state); |
int automaton_get_accept (automaton a, int state); |
63 |
int automaton_get_next_state (automaton a, int start, char l); |
int automaton_get_next_state (automaton a, int start, char l); |
64 |
void automaton_dump (automaton a, char* filename); |
void automaton_dump (automaton a, char* filename); |
65 |
|
|
66 |
|
|
67 |
/* ************************************************** * |
/* ************************************************** * |
68 |
static functions for dynamic automata |
static functions for dynamic automata |
114 |
exported functions for static automata |
exported functions for static automata |
115 |
* ************************************************** */ |
* ************************************************** */ |
116 |
|
|
117 |
automaton |
automaton |
118 |
automaton_build(int init_state, int *ptl, int *PS, struct search_RegE_list_t *list) |
automaton_build(int init_state, int *ptl, int *PS, struct search_RegE_list_t *list) |
119 |
{ |
{ |
120 |
Automaton nfa,dfa; |
Automaton nfa,dfa; |
137 |
return final; |
return final; |
138 |
} |
} |
139 |
|
|
140 |
void |
void |
141 |
automaton_delete(automaton a) |
automaton_delete(automaton a) |
142 |
{ |
{ |
143 |
int i; |
int i; |
172 |
return a->trans[state][(int)l]; |
return a->trans[state][(int)l]; |
173 |
} |
} |
174 |
|
|
175 |
void |
void |
176 |
automaton_dump(automaton a, char* filename) |
automaton_dump(automaton a, char* filename) |
177 |
{ |
{ |
178 |
int i,l; |
int i,l; |
233 |
|
|
234 |
static Automaton |
static Automaton |
235 |
s_automaton_create() |
s_automaton_create() |
236 |
{ |
{ |
237 |
Automaton a; |
Automaton a; |
238 |
a = (Automaton)malloc(sizeof(struct Automaton_t)); |
a = (Automaton)malloc(sizeof(struct Automaton_t)); |
239 |
a->nstates = 0; |
a->nstates = 0; |
240 |
a->init_state = NULL; |
a->init_state = NULL; |
285 |
return s; |
return s; |
286 |
} |
} |
287 |
|
|
288 |
static void |
static void |
289 |
s_automaton_add_state(Automaton a, astate s) |
s_automaton_add_state(Automaton a, astate s) |
290 |
{ |
{ |
291 |
a->nstates ++; |
a->nstates ++; |
292 |
alist_add(a->states,(void*)s); |
alist_add(a->states,(void*)s); |
293 |
DMSG(printf("** state %s added to automaton\n",s_automaton_id_to_str(s->id))); |
DMSG(printf("** state %s added to automaton\n",s_automaton_id_to_str(s->id))); |
306 |
//DMSG(printf("** get state %s ok\n",s_automaton_id_to_str(s->id))); |
//DMSG(printf("** get state %s ok\n",s_automaton_id_to_str(s->id))); |
307 |
return s; |
return s; |
308 |
} |
} |
309 |
} |
} |
310 |
return NULL; |
return NULL; |
311 |
} |
} |
312 |
|
|
342 |
DMSG(printf("** current state = %s\n",s_automaton_id_to_str(current_state->id))); |
DMSG(printf("** current state = %s\n",s_automaton_id_to_str(current_state->id))); |
343 |
memset(used_letter,0,sizeof(used_letter)); |
memset(used_letter,0,sizeof(used_letter)); |
344 |
/* 3: \foreach l in \sigma | l \neq # */ |
/* 3: \foreach l in \sigma | l \neq # */ |
345 |
for(p=1; p < maxpos; p++) |
for(p=1; p < maxpos; p++) |
346 |
{ |
{ |
347 |
int current_letter = ptl[p]; |
int current_letter = ptl[p]; |
348 |
if (used_letter[current_letter] == 0) |
if (used_letter[current_letter] == 0) |
351 |
int pos, ens = 0; |
int pos, ens = 0; |
352 |
for(pos = 1; pos <= maxpos; pos++) |
for(pos = 1; pos <= maxpos; pos++) |
353 |
{ |
{ |
354 |
if (ptl[pos] == current_letter && |
if (ptl[pos] == current_letter && |
355 |
(int)alist_elt_get_value(alist_get_first(current_state->id)) & (1 << (pos - 1))) |
(int)alist_elt_get_value(alist_get_first(current_state->id)) & (1 << (pos - 1))) |
356 |
ens |= PS[pos]; |
ens |= PS[pos]; |
357 |
} |
} |
367 |
current_state->next[current_letter] = temp_state; |
current_state->next[current_letter] = temp_state; |
368 |
alist_add(L,temp_state); |
alist_add(L,temp_state); |
369 |
} |
} |
370 |
else |
else |
371 |
{ |
{ |
372 |
alist_delete(temp_id); |
alist_delete(temp_id); |
373 |
current_state->next[current_letter] = temp_state; |
current_state->next[current_letter] = temp_state; |
415 |
|
|
416 |
if ((z = y->next[letter]) != NULL) /* \delta (y,z) = l */ |
if ((z = y->next[letter]) != NULL) /* \delta (y,z) = l */ |
417 |
{ |
{ |
418 |
r = s_automaton_successor(z->id,RE_EPSILON,nfa, list); |
r = s_automaton_successor(z->id,RE_EPSILON,nfa, list); |
419 |
alist_insert(Ry,r); |
alist_insert(Ry,r); |
420 |
alist_delete(r); |
alist_delete(r); |
421 |
alist_insert(Ry,z->id); /* Ry = Ry \cup succ(z) */ |
alist_insert(Ry,z->id); /* Ry = Ry \cup succ(z) */ |
424 |
/* \epsilon transition from start node */ |
/* \epsilon transition from start node */ |
425 |
if ((z = y->next[RE_EPSILON]) != NULL) /* \delta (y,z) = \epsilon */ |
if ((z = y->next[RE_EPSILON]) != NULL) /* \delta (y,z) = \epsilon */ |
426 |
{ |
{ |
427 |
r = s_automaton_successor(z->id,letter,nfa, list); |
r = s_automaton_successor(z->id,letter,nfa, list); |
428 |
alist_insert(Ry,r); /* Ry = Ry \cup succ(z) */ |
alist_insert(Ry,r); /* Ry = Ry \cup succ(z) */ |
429 |
alist_delete(r); |
alist_delete(r); |
430 |
} |
} |
441 |
DMSG(printf("is in ")); |
DMSG(printf("is in ")); |
442 |
DMSG(regexp_print_letter(stdout,i)); |
DMSG(regexp_print_letter(stdout,i)); |
443 |
|
|
444 |
r = s_automaton_successor(z->id,RE_EPSILON,nfa, list); |
r = s_automaton_successor(z->id,RE_EPSILON,nfa, list); |
445 |
alist_insert(Ry,r); |
alist_insert(Ry,r); |
446 |
alist_delete(r); |
alist_delete(r); |
447 |
alist_insert(Ry,z->id); |
alist_insert(Ry,z->id); |
475 |
DMSG(printf("%s ",s_automaton_id_to_str(ns->id))); |
DMSG(printf("%s ",s_automaton_id_to_str(ns->id))); |
476 |
if (ns->accept && alist_is_in(s->id,idx)) |
if (ns->accept && alist_is_in(s->id,idx)) |
477 |
{ |
{ |
478 |
DMSG(printf("(ok) ")); |
DMSG(printf("(ok) ")); |
479 |
s->accept = 1; |
s->accept = 1; |
480 |
} |
} |
481 |
} |
} |
482 |
DMSG(printf("\n")); |
DMSG(printf("\n")); |
483 |
} |
} |
484 |
|
|
485 |
static Automaton |
static Automaton |
486 |
s_automaton_NFA_to_DFA(Automaton nfa, struct search_RegE_list_t *list) |
s_automaton_NFA_to_DFA(Automaton nfa, struct search_RegE_list_t *list) |
487 |
{ |
{ |
488 |
Automaton dfa = NULL; |
Automaton dfa = NULL; |
512 |
|
|
513 |
if (! alist_is_empty(temp_id)) |
if (! alist_is_empty(temp_id)) |
514 |
{ |
{ |
515 |
|
|
516 |
DMSG(printf("*** successor of %s for ",s_automaton_id_to_str(current_state->id))); |
DMSG(printf("*** successor of %s for ",s_automaton_id_to_str(current_state->id))); |
517 |
DMSG(regexp_print_letter(stdout,letter)); |
DMSG(regexp_print_letter(stdout,letter)); |
518 |
DMSG(printf(" = %s\n", s_automaton_id_to_str(temp_id))); |
DMSG(printf(" = %s\n", s_automaton_id_to_str(temp_id))); |
520 |
temp_state = s_automaton_get_state(dfa,temp_id); |
temp_state = s_automaton_get_state(dfa,temp_id); |
521 |
|
|
522 |
// DMSG(printf("*** automaton get state -%s- ok\n",s_automaton_id_to_str(temp_id))); |
// DMSG(printf("*** automaton get state -%s- ok\n",s_automaton_id_to_str(temp_id))); |
523 |
|
|
524 |
if (temp_state == NULL) |
if (temp_state == NULL) |
525 |
{ |
{ |
526 |
temp_state = s_automaton_state_create(temp_id); |
temp_state = s_automaton_state_create(temp_id); |
538 |
{ |
{ |
539 |
alist_delete(temp_id); |
alist_delete(temp_id); |
540 |
} |
} |
541 |
} |
} |
542 |
} |
} |
543 |
|
|
544 |
for(ptr = alist_get_first(dfa->states) ; ptr ; ptr = alist_get_next(dfa->states,ptr)) |
for(ptr = alist_get_first(dfa->states) ; ptr ; ptr = alist_get_next(dfa->states,ptr)) |
546 |
astate s = (astate)alist_elt_get_value(ptr); |
astate s = (astate)alist_elt_get_value(ptr); |
547 |
s_automaton_node_set_accept(s,nfa); |
s_automaton_node_set_accept(s,nfa); |
548 |
} |
} |
549 |
|
|
550 |
alist_delete(L); |
alist_delete(L); |
551 |
return dfa; |
return dfa; |
552 |
} |
} |
555 |
* ************************************************** * |
* ************************************************** * |
556 |
* ************************************************** */ |
* ************************************************** */ |
557 |
|
|
558 |
static automaton |
static automaton |
559 |
s_automaton_finalize(Automaton a) |
s_automaton_finalize(Automaton a) |
560 |
{ |
{ |
561 |
int i,l; |
int i,l; |
562 |
automaton fa = NULL; |
automaton fa = NULL; |
563 |
alist_elt ptr; |
alist_elt ptr; |
564 |
astate s; |
astate s; |
565 |
|
|
591 |
s = (astate)alist_elt_get_value(ptr); |
s = (astate)alist_elt_get_value(ptr); |
592 |
i = s->id_static; |
i = s->id_static; |
593 |
|
|
594 |
if (s == a->init_state) |
if (s == a->init_state) |
595 |
fa->init = i; |
fa->init = i; |
596 |
if (s->accept == 1) |
if (s->accept == 1) |
597 |
fa->accept[i] = 1; |
fa->accept[i] = 1; |
598 |
|
|
599 |
for(l=0; l < MAX_TRANSITION_LETTERS; l++) |
for(l=0; l < MAX_TRANSITION_LETTERS; l++) |
609 |
* ************************************************** * |
* ************************************************** * |
610 |
* ************************************************** */ |
* ************************************************** */ |
611 |
|
|
612 |
static void |
static void |
613 |
s_automaton_print_nodes(FILE* f, Automaton a) |
s_automaton_print_nodes(FILE* f, Automaton a) |
614 |
{ |
{ |
615 |
char * sid; |
char * sid; |
633 |
fprintf(f,"\n"); |
fprintf(f,"\n"); |
634 |
} |
} |
635 |
|
|
636 |
static void |
static void |
637 |
s_automaton_print_edges(FILE* f, Automaton a) |
s_automaton_print_edges(FILE* f, Automaton a) |
638 |
{ |
{ |
639 |
int letter; |
int letter; |
658 |
} |
} |
659 |
} |
} |
660 |
|
|
661 |
static void |
static void |
662 |
s_automaton_dump(Automaton a, char* filename) |
s_automaton_dump(Automaton a, char* filename) |
663 |
{ |
{ |
664 |
FILE* f; |
FILE* f; |