/[eliot]/eliot/dic/automaton.c
ViewVC logotype

Diff of /eliot/dic/automaton.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.6 by afrab, Tue Apr 19 20:18:32 2005 UTC revision 1.7 by afrab, Thu May 5 23:45:04 2005 UTC
# Line 1  Line 1 
1  /* Eliot                                                                     */  /* Eliot                                                                     */
2  /* Copyright (C) 1999  antoine.fraboulet                                     */  /* Copyright (C) 2005  Antoine Fraboulet                                     */
 /* antoine.fraboulet@free.fr                                                 */  
3  /*                                                                           */  /*                                                                           */
4  /* This program is free software; you can redistribute it and/or modify      */  /* This file is part of Eliot.                                               */
5    /*                                                                           */
6    /* Eliot is free software; you can redistribute it and/or modify             */
7  /* it under the terms of the GNU General Public License as published by      */  /* it under the terms of the GNU General Public License as published by      */
8  /* the Free Software Foundation; either version 2 of the License, or         */  /* the Free Software Foundation; either version 2 of the License, or         */
9  /* (at your option) any later version.                                       */  /* (at your option) any later version.                                       */
10  /*                                                                           */  /*                                                                           */
11  /* This program is distributed in the hope that it will be useful,           */  /* Elit is distributed in the hope that it will be useful,                   */
12  /* but WITHOUT ANY WARRANTY; without even the implied warranty of            */  /* but WITHOUT ANY WARRANTY; without even the implied warranty of            */
13  /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */  /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
14  /* GNU General Public License for more details.                              */  /* GNU General Public License for more details.                              */
# Line 15  Line 16 
16  /* You should have received a copy of the GNU General Public License         */  /* You should have received a copy of the GNU General Public License         */
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */  /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
19    
20  /*  /*
21   * $Id$   * $Id$
22   */   */
23    
24  #include "config.h"  #include "config.h"
25    #include <assert.h>
26  #include <string.h>  #include <string.h>
27  #include <stdlib.h>  #include <stdlib.h>
28  #include <stdio.h>  #include <stdio.h>
# Line 27  Line 31 
31  #   include <sys/wait.h>  #   include <sys/wait.h>
32  #endif  #endif
33  #include <unistd.h>  #include <unistd.h>
34    
35  #include "dic.h"  #include "dic.h"
36  #include "regexp.h"  #include "regexp.h"
37    #include "alist.h"
38  #include "automaton.h"  #include "automaton.h"
39    
40  #ifndef PDBG  #ifdef DEBUG_AUTOMATON__
41  #ifdef DEBUG_RE2  #define DMSG(a) a
 #   define PDBG(s) s  
42  #else  #else
43  #   define PDBG(s)  #define DMSG(a)
44  #endif  #endif
45    
46    #define MAX_TRANSITION_LETTERS 256
47    
48    typedef struct automaton_state_t *astate;
49    typedef struct Automaton_t       *Automaton;
50    
51    /* ************************************************** *
52       exported functions for static automata
53     * ************************************************** */
54    
55    automaton automaton_build          (int init_state, int *ptl, int *PS, struct search_RegE_list_t *list);
56    void      automaton_delete         (automaton a);
57    int       automaton_get_nstate     (automaton a);
58    int       automaton_get_init       (automaton a);
59    int       automaton_get_accept     (automaton a, int state);
60    int       automaton_get_next_state (automaton a, int start, char l);
61    void      automaton_dump           (automaton a, char* filename);
62        
63    
64    /* ************************************************** *
65       static functions for dynamic automata
66     * ************************************************** */
67    
68    static Automaton s_automaton_create         ();
69    static void      s_automaton_delete         (Automaton a);
70    
71    static alist     s_automaton_id_create      (int id);
72    static char*     s_automaton_id_to_str      (alist id);
73    
74    static astate    s_automaton_state_create   (alist id);
75    
76    static void      s_automaton_add_state      (Automaton a, astate s);
77    static astate    s_automaton_get_state      (Automaton a, alist id);
78    
79    static Automaton s_automaton_PS_to_NFA      (int init_state, int *ptl, int *PS);
80    static Automaton s_automaton_NFA_to_DFA     (Automaton a, struct search_RegE_list_t *list);
81    static automaton s_automaton_finalize       (Automaton a);
82    #ifdef DEBUG_AUTOMATON
83    static void      s_automaton_dump           (Automaton a, char* filename);
84  #endif  #endif
85    
86  automaton  /* ************************************************** *
87  automaton_build(int init_state, int *ptl, int *PS)     data types
88     * ************************************************** */
89    
90    struct automaton_state_t {
91      alist    id;                     // alist of int
92      int      accept;
93      int      id_static;
94      astate   next[MAX_TRANSITION_LETTERS];
95    };
96    
97    struct Automaton_t {
98      int      nstates;
99      astate   init_state;
100      alist    states;                 // alist of alist of int
101    };
102    
103    struct automaton_t {
104      int   nstates;
105      int   init;
106      int  *accept;
107      int **trans;
108    };
109    
110    /* ************************************************** *
111       exported functions for static automata
112     * ************************************************** */
113    
114    automaton
115    automaton_build(int init_state, int *ptl, int *PS, struct search_RegE_list_t *list)
116  {  {
117    /* int init_state; == root->PP           */    Automaton nfa,dfa;
118    /* int *ptl; mapping postition -> lettre */    automaton final;
   /* int *PS;  Position Suivante [ 1 << (position-1)] = \cup { 1 << (p-1) | p \in position acceptée } */  
   
   int  i,l,pos,letter,ens;  
   int  state,plist;  
   int  *state_list;  
   char used_letter[256];  
   automaton a;  
119    
120    a = (automaton)malloc(sizeof(struct _automaton));    nfa = s_automaton_PS_to_NFA(init_state,ptl,PS);
121        DMSG(printf("\n non deterministic automaton OK \n\n"));
122    a->nterm  = PS[0];    DMSG(s_automaton_dump(nfa,"auto_nfa"));
123    a->nstate = 1;  
124    a->init   = init_state;    dfa = s_automaton_NFA_to_DFA(nfa, list);
125    a->accept = (int*) calloc(1 << PS[0], sizeof(int));   // #{states}    DMSG(printf("\n deterministic automaton OK \n\n"));
126    a->marque = (int*) calloc(1 << PS[0], sizeof(int));   // #{states}    DMSG(s_automaton_dump(dfa,"auto_dfa"));
127    a->Dtrans = (int**)calloc(1 << PS[0], sizeof(int*));  // #{states} * #{letters}  
128    a->callocsize = 1 << PS[0];    final = s_automaton_finalize(dfa);
129      DMSG(printf("\n final automaton OK \n\n"));
130      DMSG(automaton_dump(final,"auto_fin"));
131    
132      s_automaton_delete(nfa);
133      s_automaton_delete(dfa);
134      return final;
135    }
136    
137    void
138    automaton_delete(automaton a)
139    {
140      int i;
141      free(a->accept);
142      for(i=0; i <= a->nstates; i++)
143        free(a->trans[i]);
144      free(a->trans);
145      free(a);
146    }
147    
148    inline int
149    automaton_get_nstates(automaton a)
150    {
151      return a->nstates;
152    }
153    
154    inline int
155    automaton_get_init(automaton a)
156    {
157      return a->init;
158    }
159    
160    inline int
161    automaton_get_accept(automaton a, int state)
162    {
163      assert(0 <= state && state <= a->nstates);
164      return a->accept[state];
165    }
166    
167    inline int
168    automaton_get_next_state(automaton a, int state, char l)
169    {
170      assert(0 <= state && state <= a->nstates);
171      return a->trans[state][(int)l];
172    }
173    
174    void
175    automaton_dump(automaton a, char* filename)
176    {
177      int i,l;
178      FILE* f;
179      pid_t   pid;
180      if (a == NULL)
181        return ;
182      f=fopen(filename,"w");
183      fprintf(f,"digraph automaton {\n");
184      for(i=1; i<=a->nstates; i++)
185        {
186          fprintf(f,"\t%d [label = \"%d\"",i,i);
187          if (i == a->init)
188            fprintf(f,", style = filled, color=lightgrey");
189          if (a->accept[i])
190            fprintf(f,", shape = doublecircle");
191          fprintf(f,"];\n");
192        }
193      fprintf(f,"\n");
194      for(i=1; i<=a->nstates; i++)
195        for(l=0; l < MAX_TRANSITION_LETTERS; l++)
196          if (a->trans[i][l])
197            {
198              fprintf(f,"\t%d -> %d [label = \"",i,a->trans[i][l]);
199              regexp_print_letter(f,l);
200              fprintf(f,"\"];\n");
201            }
202      fprintf(f,"fontsize=20;\n");
203      fprintf(f,"}\n");
204      fclose(f);
205    
206    #ifdef HAVE_SYS_WAIT_H
207      pid = fork ();
208      if (pid > 0) {
209        wait(NULL);
210      } else if (pid == 0) {
211        execlp("dotty","dotty",filename,NULL);
212        printf("exec dotty failed\n");
213        exit(1);
214      }
215    #endif
216    }
217    
218    /* ************************************************** *
219     * ************************************************** *
220     * ************************************************** */
221    
222    void
223    state_delete_fun(void* ps)
224    {
225      astate s = ps;
226      alist_delete(s->id);
227      free(s);
228    }
229    
230    static Automaton
231    s_automaton_create()
232    {  
233      Automaton a;
234      a = (Automaton)malloc(sizeof(struct Automaton_t));
235      a->nstates      = 0;
236      a->init_state   = NULL;
237      a->states       = alist_create();
238      alist_set_delete(a->states,state_delete_fun);
239      return a;
240    }
241    
242    
243    static void
244    s_automaton_delete(Automaton a)
245    {
246      alist_delete(a->states);
247      free(a);
248    }
249    
250    static alist
251    s_automaton_id_create(int id)
252    {
253      alist a = alist_create();
254      alist_add(a,(void*)id);
255      return a;
256    }
257    
258    for(i=0; i < (1 << PS[0]); i++)  static char* s_automaton_id_to_str(alist id)
259    {
260      static char s[250];
261      memset(s,0,sizeof(s));
262      alist_elt ptr;
263      for(ptr = alist_get_first(id); ptr ; ptr = alist_get_next(id,ptr))
264      {      {
265        // 256 different letters max        char tmp[50];
266        a->Dtrans[i] = (int*)calloc(256, sizeof(int));            sprintf(tmp,"%d ",(int)alist_elt_get_value(ptr));
267          strcat(s,tmp);
268      }      }
269      return s;
270    }
271    
272    static astate
273    s_automaton_state_create(alist id)
274    {
275      astate s;
276      s = (astate)malloc(sizeof(struct automaton_state_t));
277      s->id      = id;
278      s->accept  = 0;
279      memset(s->next,0,sizeof(astate)*MAX_TRANSITION_LETTERS);
280      DMSG(printf("** state %s creation\n",s_automaton_id_to_str(id)));
281      return s;
282    }
283    
284    static void
285    s_automaton_add_state(Automaton a, astate s)
286    {
287      a->nstates ++;
288      alist_add(a->states,(void*)s);
289      DMSG(printf("** state %s added to automaton\n",s_automaton_id_to_str(s->id)));
290    }
291    
292    static astate
293    s_automaton_get_state(Automaton a, alist id)
294    {
295      astate s;
296      alist_elt ptr;
297      for(ptr = alist_get_first(a->states) ;  ptr ; ptr = alist_get_next(a->states,ptr))
298        {
299          s = alist_elt_get_value(ptr);
300          if (alist_equal(s->id,id))
301            {
302              //DMSG(printf("** get state %s ok\n",s_automaton_id_to_str(s->id)));
303              return s;
304            }
305        }
306      return NULL;
307    }
308    
309    /* ************************************************** *
310     * ************************************************** *
311     * ************************************************** */
312    
313    state_list = (int*)calloc(1 << PS[0], sizeof(int));   // #{states}  Automaton
314    s_automaton_PS_to_NFA(int init_state_id, int *ptl, int *PS)
315    {
316      int p;
317      int maxpos = PS[0];
318      Automaton nfa = NULL;
319      alist temp_id;
320      alist_elt ptr;
321      astate temp_state,current_state;
322      alist L;
323      char used_letter[MAX_TRANSITION_LETTERS];
324    
325      nfa = s_automaton_create();
326      L   = alist_create();
327    
328    /* 1: init_state = root->PP */    /* 1: init_state = root->PP */
329    plist = 0;    temp_id          = s_automaton_id_create(init_state_id);
330    state_list[plist++] = a->init;    temp_state       = s_automaton_state_create(temp_id);
331      nfa->init_state  = temp_state;
332      s_automaton_add_state(nfa,temp_state);
333      alist_add(L,temp_state);
334    /* 2: while \exist state \in state_list */    /* 2: while \exist state \in state_list */
335    while (plist)    while (! alist_is_empty(L))
336      {      {
337        state = state_list[--plist];        current_state = (astate)alist_pop_first_value(L);
338        PDBG(fprintf(stdout,"** traitement état 0x%08x\n",state));        DMSG(printf("** current state = %s\n",s_automaton_id_to_str(current_state->id)));
339        memset(used_letter,0,sizeof(used_letter));        memset(used_letter,0,sizeof(used_letter));
340        /* 3: \foreach l in \sigma | l \neq # */        /* 3: \foreach l in \sigma | l \neq # */
341        for(l=1; l < PS[0]; l++)        for(p=1; p < maxpos; p++)
342          {          {
343            letter = ptl[l];            int current_letter = ptl[p];
344            if (used_letter[letter] == 0)            if (used_letter[current_letter] == 0)
345              {              {
346                /* 4: int ens = \cup { PS(pos) | pos \in state \wedge pos == l } */                /* 4: int set = \cup { PS(pos) | pos \in state \wedge pos == l } */
347                ens = 0;                int pos, ens = 0;
348                for(pos = 1; pos <= PS[0]; pos++)                for(pos = 1; pos <= maxpos; pos++)
349                  {                  {
350                    if (ptl[pos] == letter && (state & (1 << (pos - 1))))                    if (ptl[pos] == current_letter &&
351                          (int)alist_elt_get_value(alist_get_first(current_state->id)) & (1 << (pos - 1)))
352                      ens |= PS[pos];                      ens |= PS[pos];
353                  }                  }
354                /* 5: */                /* 5: transition from current_state to temp_state */
355                if (ens && a->marque[ens] == 0)                if (ens)
356                  {                  {
357                    state_list[plist++] = ens;                    temp_id    = s_automaton_id_create(ens);
358                    a->Dtrans[state][letter] = ens;                    temp_state = s_automaton_get_state(nfa,temp_id);
359                    PDBG(fprintf(stdout,"  adding %x +",state));                    if (temp_state == NULL)
                   PDBG(regexp_print_letter(stdout,letter));  
                   PDBG(fprintf(stdout,"> %x (queue %x)\n",ens,ens));  
                   if (ens != state)  
360                      {                      {
361                        a->nstate = a->nstate + 1;                        temp_state = s_automaton_state_create(temp_id);
362                          s_automaton_add_state     (nfa,temp_state);
363                          current_state->next[current_letter] = temp_state;
364                          alist_add(L,temp_state);
365                        }
366                      else
367                        {
368                          alist_delete(temp_id);
369                          current_state->next[current_letter] = temp_state;
370                      }                      }
371                  }                  }
372                /* 6: */                used_letter[current_letter] = 1;
               if (ens && a->marque[ens] == 1)  
                 {  
                   a->Dtrans[state][letter] = ens;  
                   PDBG(fprintf(stdout,"  adding %x -",state));  
                   PDBG(regexp_print_letter(stdout,letter));  
                   PDBG(fprintf(stdout,"> %x\n",ens));  
                 }  
               a->marque[state] = 1;  
               used_letter[letter] = 1;  
373              }              }
374          }          }
375      }      }
376    
377    PDBG(fprintf(stdout,"** accept : "));    alist_delete(L);
378    for(i=0; i < (1 << PS[0]); i++)  
379      for(ptr = alist_get_first(nfa->states); ptr ; ptr = alist_get_next(nfa->states,ptr))
380        {
381          astate s = (astate)alist_elt_get_value(ptr);
382          if ((int)alist_elt_get_value(alist_get_first(s->id)) & (1 << (maxpos - 1)))
383            s->accept = 1;
384        }
385    
386      return nfa;
387    }
388    
389    /* ************************************************** *
390     * ************************************************** *
391     * ************************************************** */
392    
393    static alist
394    s_automaton_successor(alist S, int letter, Automaton nfa, struct search_RegE_list_t *list)
395    {
396      alist R,r;
397      alist_elt ptr;
398      R = alist_create();                                       /* R = \empty */
399                                                                /* \forall y \in S */
400      for(ptr = alist_get_first(S); ptr ; ptr = alist_get_next(S,ptr))
401      {      {
402        if (a->marque[i] && (i & (1 << (PS[0] - 1))))        int i;
403          alist t, Ry; astate y,z;
404    
405          i = (int)alist_elt_get_value(ptr);
406          t = s_automaton_id_create(i);
407          assert(y = s_automaton_get_state(nfa,t));
408          alist_delete(t);
409    
410          Ry = alist_create();                                 /* Ry = \empty             */
411    
412          if ((z = y->next[letter]) != NULL)                   /* \delta (y,z) = l        */
413            {
414              r = s_automaton_successor(z->id,RE_EPSILON,nfa, list);    
415              alist_insert(Ry,r);
416              alist_delete(r);
417              alist_insert(Ry,z->id);                          /* Ry = Ry \cup succ(z)    */
418            }
419    
420    #if 0
421          if ((z = y->next[RE_EPSILON]) != NULL)               /* \delta (y,z) = \epsilon */
422          {          {
423            a->accept[i] = 1;            r = s_automaton_successor(z->id,letter,nfa, list);    
424            PDBG(fprintf(stdout,"%x ",i));            alist_insert(Ry,r);                              /* Ry = Ry \cup succ(z)    */
425              alist_delete(r);
426          }          }
427    #endif
428    
429          if (letter < RE_FINAL_TOK)
430            {
431              for(i = 0 ; i < DIC_SEARCH_REGE_LIST ; i++)
432                if (list->valid[i])
433                  {
434                    if (list->letters[i][letter] && (z = y->next[(int)list->symbl[i]]) != NULL)
435                      {
436                        DMSG(printf("*** letter "));
437                        DMSG(regexp_print_letter(stdout,letter));
438                        DMSG(printf("is in "));
439                        DMSG(regexp_print_letter(stdout,i));
440    
441                        r = s_automaton_successor(z->id,RE_EPSILON,nfa, list);    
442                        alist_insert(Ry,r);
443                        alist_delete(r);
444                        alist_insert(Ry,z->id);
445                      }
446                  }
447            }
448    
449          //      if (alist_is_empty(Ry))                              /* Ry = \empty             */
450          //        return Ry;
451    
452          alist_insert(R,Ry);                                  /* R = R \cup Ry           */
453          alist_delete(Ry);
454      }      }
   PDBG(fprintf(stdout,"\n"));  
455    
456    free(state_list);    return R;
   return a;  
457  }  }
458    
459  //////////////////////////////////////////////////  static void
460  //////////////////////////////////////////////////  s_automaton_node_set_accept(astate s, Automaton nfa)
461    {
462      void* idx;
463      alist_elt ptr;
464    
465  void    DMSG(printf("=== setting accept for node (%s) :",s_automaton_id_to_str(s->id)));
466  automaton_delete(automaton a)    for(ptr = alist_get_first(nfa->states) ; ptr ; ptr = alist_get_next(nfa->states,ptr))
467        {
468          astate ns = (astate)alist_elt_get_value(ptr);
469          idx = alist_elt_get_value(alist_get_first(ns->id));
470          DMSG(printf("%s ",s_automaton_id_to_str(ns->id)));
471          if (ns->accept && alist_is_in(s->id,idx))
472            {
473              DMSG(printf("(ok) "));
474              s->accept = 1;
475            }
476        }
477      DMSG(printf("\n"));
478    }
479    
480    static Automaton
481    s_automaton_NFA_to_DFA(Automaton nfa, struct search_RegE_list_t *list)
482  {  {
483    int i;    Automaton dfa = NULL;
484    free(a->accept);    alist temp_id;
485    free(a->marque);    alist_elt ptr;
486    for(i=0; i < a->callocsize; i++)    astate temp_state, current_state;
487      alist L;
488      int letter;
489    
490      dfa = s_automaton_create();
491      L   = alist_create();
492    
493      temp_id         = alist_clone(nfa->init_state->id);
494      temp_state      = s_automaton_state_create(temp_id);
495      dfa->init_state = temp_state;
496      s_automaton_add_state(dfa,temp_state);
497      alist_add(L,temp_state);
498      while (! alist_is_empty(L))
499      {      {
500        free(a->Dtrans[i]);        current_state = (astate)alist_pop_first_value(L);
501          DMSG(printf("** current state = %s\n",s_automaton_id_to_str(current_state->id)));
502          for(letter = 1; letter < DIC_LETTERS; letter++)
503            {
504              //      DMSG(printf("*** start successor of %s\n",s_automaton_id_to_str(current_state->id)));
505    
506              temp_id = s_automaton_successor(current_state->id,letter,nfa,list);
507    
508              if (! alist_is_empty(temp_id))
509                {
510                  
511                  DMSG(printf("*** successor of %s for ",s_automaton_id_to_str(current_state->id)));
512                  DMSG(regexp_print_letter(stdout,letter));
513                  DMSG(printf(" = %s\n", s_automaton_id_to_str(temp_id)));
514    
515                  temp_state = s_automaton_get_state(dfa,temp_id);
516    
517                  //          DMSG(printf("*** automaton get state -%s- ok\n",s_automaton_id_to_str(temp_id)));
518                  
519                  if (temp_state == NULL)
520                    {
521                      temp_state = s_automaton_state_create(temp_id);
522                      s_automaton_add_state(dfa,temp_state);
523                      current_state->next[letter] = temp_state;
524                      alist_add(L,temp_state);
525                    }
526                  else
527                    {
528                      alist_delete(temp_id);
529                      current_state->next[letter] = temp_state;
530                    }
531                }
532              else
533                {
534                  alist_delete(temp_id);
535                }
536            }
537      }      }
538    free(a->Dtrans);  
539    free(a);    for(ptr = alist_get_first(dfa->states) ; ptr ; ptr = alist_get_next(dfa->states,ptr))
540        {
541          astate s = (astate)alist_elt_get_value(ptr);
542          s_automaton_node_set_accept(s,nfa);
543        }
544      
545      alist_delete(L);
546      return dfa;
547  }  }
548    
549  //////////////////////////////////////////////////  /* ************************************************** *
550  //////////////////////////////////////////////////   * ************************************************** *
551     * ************************************************** */
552    
553  #if 0  static automaton
554  void  s_automaton_finalize(Automaton a)
 automaton_minimize(automaton a, automaton b)  
555  {  {
556    int i;    int i,l;
557    b->nterm  = a->nterm;    automaton fa = NULL;
558    b->nstate = a->nstate;    alist_elt ptr;
559    b->init   = a->init;    astate s;
560    b->accept = (int*) calloc(a->nstate, sizeof(int ));  // #{etats}  
561    b->marque = (int*) calloc(a->nstate, sizeof(int ));  // #{etats}    if (a == NULL)
562    b->Dtrans = (int**)calloc(a->nstate, sizeof(int*));  // #{etats} * #{lettres}      return NULL;
563    for(i=0; i < a->nstate; i++)  
564      /* creation */
565      fa = (automaton)malloc(sizeof(struct automaton_t));
566      fa->nstates = a->nstates;
567      fa->accept  = (int*) malloc((fa->nstates + 1)*sizeof(int));
568      memset(fa->accept,0,(fa->nstates + 1)*sizeof(int));
569      fa->trans   = (int**)malloc((fa->nstates + 1)*sizeof(int*));
570      for(i=0; i <= fa->nstates; i++)
571      {      {
572        b->Dtrans[i] = (int*)calloc(256, sizeof(int));        fa->trans[i] = (int*)malloc(MAX_TRANSITION_LETTERS * sizeof(int));
573          memset(fa->trans[i],0,MAX_TRANSITION_LETTERS * sizeof(int));
574      }      }
575      
576    /* NOT DONE */    /* create new id for states */
577      for(i = 1 , ptr = alist_get_first(a->states); ptr ; ptr = alist_get_next(a->states,ptr), i++)
578        {
579          s = (astate)alist_elt_get_value(ptr);
580          s->id_static = i;
581        }
582    
583      /* build new automaton */
584      for(ptr = alist_get_first(a->states); ptr ; ptr = alist_get_next(a->states,ptr))
585        {
586          s = (astate)alist_elt_get_value(ptr);
587          i = s->id_static;
588    
589          if (s == a->init_state)
590            fa->init = i;
591          if (s->accept == 1)    
592            fa->accept[i] = 1;
593    
594          for(l=0; l < MAX_TRANSITION_LETTERS; l++)
595            if (s->next[l])
596              fa->trans[i][l] = s->next[l]->id_static;
597        }
598    
599      return fa;
600  }  }
 #endif  
601    
 //////////////////////////////////////////////////  
 //////////////////////////////////////////////////  
602    
603  #ifdef DEBUG_RE  /* ************************************************** *
604     * ************************************************** *
605     * ************************************************** */
606    
607  static void  static void
608  print_automaton_nodes(FILE* f, automaton a)  s_automaton_print_nodes(FILE* f, Automaton a)
609  {  {
610    int state;    char * sid;
611    for(state=0; state < (1 << a->nterm); state++)    astate s;
612      alist_elt ptr;
613      for(ptr = alist_get_first(a->states) ; ptr != NULL ; ptr = alist_get_next(a->states,ptr))
614      {      {
615        if (a->marque[state])        s = alist_elt_get_value(ptr);
616          {        sid = s_automaton_id_to_str(s->id);
617            fprintf(f,"\t%d [label = \"%x\"",state,state);        fprintf(f,"\t\"%s\" [label = \"%s\"",sid,sid);
618            if (a->init == state)        if (s == a->init_state)
619              {              {
620                fprintf(f,", style = filled, color=lightgrey");                fprintf(f,", style = filled, color=lightgrey");
621              }              }
622            if (a->accept[state])        if (s->accept)
623              {          {
624                fprintf(f,", shape = doublecircle");            fprintf(f,", shape = doublecircle");
             }  
           fprintf(f,"];\n");  
625          }          }
626          fprintf(f,"];\n");
627      }      }
628    fprintf(f,"\n");    fprintf(f,"\n");
629  }  }
 #endif  
630    
 #ifdef DEBUG_RE  
631  static void  static void
632  print_automaton_edges(FILE* f, automaton a)  s_automaton_print_edges(FILE* f, Automaton a)
633  {  {
634    int state,letter;    int letter;
635    for(state=0; state < (1 << a->nterm); state++)    char * sid;
636      astate s;
637      alist_elt ptr;
638      for(ptr = alist_get_first(a->states) ; ptr != NULL ; ptr = alist_get_next(a->states,ptr))
639      {      {
640        if (a->marque[state])        s = (astate)alist_elt_get_value(ptr);
641          for(letter=0; letter < 255; letter++)
642          {          {
643            for(letter=0; letter < 255; letter++)            if (s->next[letter])
644              {              {
645                if (a->Dtrans[state][letter])                sid = s_automaton_id_to_str(s->id);
646                  {                fprintf(f,"\t\"%s\" -> ",sid);
647                    fprintf(f,"\t%d -> %d [label = \"",state,a->Dtrans[state][letter]);                sid = s_automaton_id_to_str(s->next[letter]->id);
648                    regexp_print_letter(f,letter);                fprintf(f,"\"%s\" [label = \"",sid);
649                    fprintf(f,"\"];\n");                regexp_print_letter(f,letter);
650                  }                fprintf(f,"\"];\n");
651              }              }
652          }          }
653      }      }
654  }  }
 #endif  
655    
656  #ifdef DEBUG_RE  static void
657  void  s_automaton_dump(Automaton a, char* filename)
 automaton_dump(automaton a, char* filename)  
658  {  {
659    FILE* f;    FILE* f;
660    pid_t   pid;    pid_t   pid;
661    
662      if (a == NULL)
663        return;
664    f=fopen(filename,"w");    f=fopen(filename,"w");
665    fprintf(f,"digraph automaton {\n");    fprintf(f,"digraph automaton {\n");
666    print_automaton_nodes(f,a);    s_automaton_print_nodes(f,a);
667    print_automaton_edges(f,a);    s_automaton_print_edges(f,a);
668    fprintf(f,"fontsize=20;\n");    fprintf(f,"fontsize=20;\n");
669    fprintf(f,"}\n");    fprintf(f,"}\n");
670    fclose(f);    fclose(f);
# Line 251  automaton_dump(automaton a, char* filena Line 680  automaton_dump(automaton a, char* filena
680    }    }
681  #endif  #endif
682  }  }
 #endif  
683    
684  //////////////////////////////////////////////////  /* ************************************************** *
685  //////////////////////////////////////////////////   * ************************************************** *
686     * ************************************************** */
687    

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26