eliot-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Eliot-dev] Changes to eliot/dic/automaton.c


From: eliot-dev
Subject: [Eliot-dev] Changes to eliot/dic/automaton.c
Date: Thu, 05 May 2005 19:45:05 -0400

Index: eliot/dic/automaton.c
diff -u eliot/dic/automaton.c:1.6 eliot/dic/automaton.c:1.7
--- eliot/dic/automaton.c:1.6   Tue Apr 19 20:18:32 2005
+++ eliot/dic/automaton.c       Thu May  5 23:45:04 2005
@@ -1,13 +1,14 @@
 /* Eliot                                                                     */
-/* Copyright (C) 1999  antoine.fraboulet                                     */
-/* address@hidden                                                 */
+/* Copyright (C) 2005  Antoine Fraboulet                                     */
 /*                                                                           */
-/* This program is free software; you can redistribute it and/or modify      */
+/* This file is part of Eliot.                                               */
+/*                                                                           */
+/* Eliot is free software; you can redistribute it and/or modify             */
 /* it under the terms of the GNU General Public License as published by      */
 /* the Free Software Foundation; either version 2 of the License, or         */
 /* (at your option) any later version.                                       */
 /*                                                                           */
-/* This program is distributed in the hope that it will be useful,           */
+/* Elit is distributed in the hope that it will be useful,                   */
 /* but WITHOUT ANY WARRANTY; without even the implied warranty of            */
 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
 /* GNU General Public License for more details.                              */
@@ -15,10 +16,13 @@
 /* You should have received a copy of the GNU General Public License         */
 /* along with this program; if not, write to the Free Software               */
 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
 /*
- * $Id: automaton.c,v 1.6 2005/04/19 20:18:32 afrab Exp $
+ * $Id: automaton.c,v 1.7 2005/05/05 23:45:04 afrab Exp $
  */
+
 #include "config.h"
+#include <assert.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -27,215 +31,640 @@
 #   include <sys/wait.h>
 #endif
 #include <unistd.h>
+
 #include "dic.h"
 #include "regexp.h"
+#include "alist.h"
 #include "automaton.h"
 
-#ifndef PDBG
-#ifdef DEBUG_RE2
-#   define PDBG(s) s
+#ifdef DEBUG_AUTOMATON__
+#define DMSG(a) a
 #else
-#   define PDBG(s) 
+#define DMSG(a)
 #endif
+
+#define MAX_TRANSITION_LETTERS 256
+
+typedef struct automaton_state_t *astate;
+typedef struct Automaton_t       *Automaton;
+
+/* ************************************************** *
+   exported functions for static automata
+ * ************************************************** */
+ 
+automaton automaton_build          (int init_state, int *ptl, int *PS, struct 
search_RegE_list_t *list);
+void      automaton_delete         (automaton a);
+int       automaton_get_nstate     (automaton a);
+int       automaton_get_init       (automaton a);
+int       automaton_get_accept     (automaton a, int state);
+int       automaton_get_next_state (automaton a, int start, char l);
+void      automaton_dump           (automaton a, char* filename);
+     
+
+/* ************************************************** *
+   static functions for dynamic automata
+ * ************************************************** */
+
+static Automaton s_automaton_create         ();
+static void      s_automaton_delete         (Automaton a);
+
+static alist     s_automaton_id_create      (int id);
+static char*     s_automaton_id_to_str      (alist id);
+
+static astate    s_automaton_state_create   (alist id);
+
+static void      s_automaton_add_state      (Automaton a, astate s);
+static astate    s_automaton_get_state      (Automaton a, alist id);
+
+static Automaton s_automaton_PS_to_NFA      (int init_state, int *ptl, int 
*PS);
+static Automaton s_automaton_NFA_to_DFA     (Automaton a, struct 
search_RegE_list_t *list);
+static automaton s_automaton_finalize       (Automaton a);
+#ifdef DEBUG_AUTOMATON
+static void      s_automaton_dump           (Automaton a, char* filename);
 #endif
 
-automaton
-automaton_build(int init_state, int *ptl, int *PS)
+/* ************************************************** *
+   data types
+ * ************************************************** */
+
+struct automaton_state_t {
+  alist    id;                     // alist of int
+  int      accept;
+  int      id_static;
+  astate   next[MAX_TRANSITION_LETTERS];
+};
+
+struct Automaton_t {
+  int      nstates;
+  astate   init_state;
+  alist    states;                 // alist of alist of int
+};
+
+struct automaton_t {
+  int   nstates;
+  int   init;
+  int  *accept;
+  int **trans;
+};
+
+/* ************************************************** *
+   exported functions for static automata
+ * ************************************************** */
+
+automaton 
+automaton_build(int init_state, int *ptl, int *PS, struct search_RegE_list_t 
*list)
 {
-  /* int init_state; == root->PP           */
-  /* int *ptl; mapping postition -> lettre */
-  /* 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;
+  Automaton nfa,dfa;
+  automaton final;
 
-  a = (automaton)malloc(sizeof(struct _automaton));
-  
-  a->nterm  = PS[0];
-  a->nstate = 1;
-  a->init   = init_state;
-  a->accept = (int*) calloc(1 << PS[0], sizeof(int));   // #{states}
-  a->marque = (int*) calloc(1 << PS[0], sizeof(int));   // #{states}
-  a->Dtrans = (int**)calloc(1 << PS[0], sizeof(int*));  // #{states} * 
#{letters}
-  a->callocsize = 1 << PS[0];
+  nfa = s_automaton_PS_to_NFA(init_state,ptl,PS);
+  DMSG(printf("\n non deterministic automaton OK \n\n"));
+  DMSG(s_automaton_dump(nfa,"auto_nfa"));
+
+  dfa = s_automaton_NFA_to_DFA(nfa, list);
+  DMSG(printf("\n deterministic automaton OK \n\n"));
+  DMSG(s_automaton_dump(dfa,"auto_dfa"));
+
+  final = s_automaton_finalize(dfa);
+  DMSG(printf("\n final automaton OK \n\n"));
+  DMSG(automaton_dump(final,"auto_fin"));
+
+  s_automaton_delete(nfa);
+  s_automaton_delete(dfa);
+  return final;
+}
+
+void 
+automaton_delete(automaton a)
+{
+  int i;
+  free(a->accept);
+  for(i=0; i <= a->nstates; i++)
+    free(a->trans[i]);
+  free(a->trans);
+  free(a);
+}
+
+inline int
+automaton_get_nstates(automaton a)
+{
+  return a->nstates;
+}
+
+inline int
+automaton_get_init(automaton a)
+{
+  return a->init;
+}
+
+inline int
+automaton_get_accept(automaton a, int state)
+{
+  assert(0 <= state && state <= a->nstates);
+  return a->accept[state];
+}
+
+inline int
+automaton_get_next_state(automaton a, int state, char l)
+{
+  assert(0 <= state && state <= a->nstates);
+  return a->trans[state][(int)l];
+}
+
+void 
+automaton_dump(automaton a, char* filename)
+{
+  int i,l;
+  FILE* f;
+  pid_t   pid;
+  if (a == NULL)
+    return ;
+  f=fopen(filename,"w");
+  fprintf(f,"digraph automaton {\n");
+  for(i=1; i<=a->nstates; i++)
+    {
+      fprintf(f,"\t%d [label = \"%d\"",i,i);
+      if (i == a->init)
+       fprintf(f,", style = filled, color=lightgrey");
+      if (a->accept[i])
+       fprintf(f,", shape = doublecircle");
+      fprintf(f,"];\n");
+    }
+  fprintf(f,"\n");
+  for(i=1; i<=a->nstates; i++)
+    for(l=0; l < MAX_TRANSITION_LETTERS; l++)
+      if (a->trans[i][l])
+       {
+         fprintf(f,"\t%d -> %d [label = \"",i,a->trans[i][l]);
+         regexp_print_letter(f,l);
+         fprintf(f,"\"];\n");
+       }
+  fprintf(f,"fontsize=20;\n");
+  fprintf(f,"}\n");
+  fclose(f);
+
+#ifdef HAVE_SYS_WAIT_H
+  pid = fork ();
+  if (pid > 0) {
+    wait(NULL);
+  } else if (pid == 0) {
+    execlp("dotty","dotty",filename,NULL);
+    printf("exec dotty failed\n");
+    exit(1);
+  }
+#endif
+}
+
+/* ************************************************** *
+ * ************************************************** *
+ * ************************************************** */
+
+void
+state_delete_fun(void* ps)
+{
+  astate s = ps;
+  alist_delete(s->id);
+  free(s);
+}
+
+static Automaton
+s_automaton_create()
+{  
+  Automaton a; 
+  a = (Automaton)malloc(sizeof(struct Automaton_t));
+  a->nstates      = 0;
+  a->init_state   = NULL;
+  a->states       = alist_create();
+  alist_set_delete(a->states,state_delete_fun);
+  return a;
+}
+
+
+static void
+s_automaton_delete(Automaton a)
+{
+  alist_delete(a->states);
+  free(a);
+}
+
+static alist
+s_automaton_id_create(int id)
+{
+  alist a = alist_create();
+  alist_add(a,(void*)id);
+  return a;
+}
 
-  for(i=0; i < (1 << PS[0]); i++)
+static char* s_automaton_id_to_str(alist id)
+{
+  static char s[250];
+  memset(s,0,sizeof(s));
+  alist_elt ptr;
+  for(ptr = alist_get_first(id); ptr ; ptr = alist_get_next(id,ptr))
     {
-      // 256 different letters max
-      a->Dtrans[i] = (int*)calloc(256, sizeof(int));    
+      char tmp[50];
+      sprintf(tmp,"%d ",(int)alist_elt_get_value(ptr));
+      strcat(s,tmp);
     }
+  return s;
+}
+
+static astate
+s_automaton_state_create(alist id)
+{
+  astate s;
+  s = (astate)malloc(sizeof(struct automaton_state_t));
+  s->id      = id;
+  s->accept  = 0;
+  memset(s->next,0,sizeof(astate)*MAX_TRANSITION_LETTERS);
+  DMSG(printf("** state %s creation\n",s_automaton_id_to_str(id)));
+  return s;
+}
+
+static void 
+s_automaton_add_state(Automaton a, astate s)
+{ 
+  a->nstates ++;
+  alist_add(a->states,(void*)s);
+  DMSG(printf("** state %s added to 
automaton\n",s_automaton_id_to_str(s->id)));
+}
+
+static astate
+s_automaton_get_state(Automaton a, alist id)
+{
+  astate s;
+  alist_elt ptr;
+  for(ptr = alist_get_first(a->states) ;  ptr ; ptr = 
alist_get_next(a->states,ptr))
+    {
+      s = alist_elt_get_value(ptr);
+      if (alist_equal(s->id,id))
+       {
+         //DMSG(printf("** get state %s ok\n",s_automaton_id_to_str(s->id)));
+         return s;
+       }
+    } 
+  return NULL;
+}
+
+/* ************************************************** *
+ * ************************************************** *
+ * ************************************************** */
 
-  state_list = (int*)calloc(1 << PS[0], sizeof(int));   // #{states} 
+Automaton
+s_automaton_PS_to_NFA(int init_state_id, int *ptl, int *PS)
+{
+  int p;
+  int maxpos = PS[0];
+  Automaton nfa = NULL;
+  alist temp_id;
+  alist_elt ptr;
+  astate temp_state,current_state;
+  alist L;
+  char used_letter[MAX_TRANSITION_LETTERS];
+
+  nfa = s_automaton_create();
+  L   = alist_create();
 
   /* 1: init_state = root->PP */
-  plist = 0;
-  state_list[plist++] = a->init;
+  temp_id          = s_automaton_id_create(init_state_id);
+  temp_state       = s_automaton_state_create(temp_id);
+  nfa->init_state  = temp_state;
+  s_automaton_add_state(nfa,temp_state);
+  alist_add(L,temp_state);
   /* 2: while \exist state \in state_list */
-  while (plist)
+  while (! alist_is_empty(L))
     {
-      state = state_list[--plist];
-      PDBG(fprintf(stdout,"** traitement état 0x%08x\n",state));
+      current_state = (astate)alist_pop_first_value(L);
+      DMSG(printf("** current state = 
%s\n",s_automaton_id_to_str(current_state->id)));
       memset(used_letter,0,sizeof(used_letter));
       /* 3: \foreach l in \sigma | l \neq # */
-      for(l=1; l < PS[0]; l++) 
+      for(p=1; p < maxpos; p++) 
        {
-         letter = ptl[l];
-         if (used_letter[letter] == 0)
+         int current_letter = ptl[p];
+         if (used_letter[current_letter] == 0)
            {
-             /* 4: int ens = \cup { PS(pos) | pos \in state \wedge pos == l } 
*/
-             ens = 0;
-             for(pos = 1; pos <= PS[0]; pos++)
+             /* 4: int set = \cup { PS(pos) | pos \in state \wedge pos == l } 
*/
+             int pos, ens = 0;
+             for(pos = 1; pos <= maxpos; pos++)
                {
-                 if (ptl[pos] == letter && (state & (1 << (pos - 1))))
+                 if (ptl[pos] == current_letter && 
+                     
(int)alist_elt_get_value(alist_get_first(current_state->id)) & (1 << (pos - 1)))
                    ens |= PS[pos];
                }
-             /* 5: */
-             if (ens && a->marque[ens] == 0)
+             /* 5: transition from current_state to temp_state */
+             if (ens)
                {
-                 state_list[plist++] = ens;
-                 a->Dtrans[state][letter] = ens;
-                 PDBG(fprintf(stdout,"  adding %x +",state));
-                 PDBG(regexp_print_letter(stdout,letter));
-                 PDBG(fprintf(stdout,"> %x (queue %x)\n",ens,ens));
-                 if (ens != state)
+                 temp_id    = s_automaton_id_create(ens);
+                 temp_state = s_automaton_get_state(nfa,temp_id);
+                 if (temp_state == NULL)
                    {
-                     a->nstate = a->nstate + 1;
+                     temp_state = s_automaton_state_create(temp_id);
+                     s_automaton_add_state     (nfa,temp_state);
+                     current_state->next[current_letter] = temp_state;
+                     alist_add(L,temp_state);
+                   }
+                 else 
+                   {
+                     alist_delete(temp_id);
+                     current_state->next[current_letter] = temp_state;
                    }
                }
-             /* 6: */
-             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;
+             used_letter[current_letter] = 1;
            }
        }
     }
 
-  PDBG(fprintf(stdout,"** accept : "));
-  for(i=0; i < (1 << PS[0]); i++)
+  alist_delete(L);
+
+  for(ptr = alist_get_first(nfa->states); ptr ; ptr = 
alist_get_next(nfa->states,ptr))
+    {
+      astate s = (astate)alist_elt_get_value(ptr);
+      if ((int)alist_elt_get_value(alist_get_first(s->id)) & (1 << (maxpos - 
1)))
+       s->accept = 1;
+    }
+
+  return nfa;
+}
+
+/* ************************************************** *
+ * ************************************************** *
+ * ************************************************** */
+
+static alist
+s_automaton_successor(alist S, int letter, Automaton nfa, struct 
search_RegE_list_t *list)
+{
+  alist R,r;
+  alist_elt ptr;
+  R = alist_create();                                       /* R = \empty */
+                                                            /* \forall y \in S 
*/
+  for(ptr = alist_get_first(S); ptr ; ptr = alist_get_next(S,ptr))
     {
-      if (a->marque[i] && (i & (1 << (PS[0] - 1))))
+      int i;
+      alist t, Ry; astate y,z;
+
+      i = (int)alist_elt_get_value(ptr);
+      t = s_automaton_id_create(i);
+      assert(y = s_automaton_get_state(nfa,t));
+      alist_delete(t);
+
+      Ry = alist_create();                                 /* Ry = \empty      
       */
+
+      if ((z = y->next[letter]) != NULL)                   /* \delta (y,z) = l 
       */
+       {
+         r = s_automaton_successor(z->id,RE_EPSILON,nfa, list);    
+         alist_insert(Ry,r);
+         alist_delete(r);
+         alist_insert(Ry,z->id);                          /* Ry = Ry \cup 
succ(z)    */
+       }
+
+#if 0
+      if ((z = y->next[RE_EPSILON]) != NULL)               /* \delta (y,z) = 
\epsilon */
        {
-         a->accept[i] = 1;
-         PDBG(fprintf(stdout,"%x ",i));
+         r = s_automaton_successor(z->id,letter,nfa, list);    
+         alist_insert(Ry,r);                              /* Ry = Ry \cup 
succ(z)    */
+         alist_delete(r);
        }
+#endif
+
+      if (letter < RE_FINAL_TOK)
+       {
+         for(i = 0 ; i < DIC_SEARCH_REGE_LIST ; i++)
+           if (list->valid[i])
+             {
+               if (list->letters[i][letter] && (z = 
y->next[(int)list->symbl[i]]) != NULL)
+                 {
+                   DMSG(printf("*** letter "));
+                   DMSG(regexp_print_letter(stdout,letter));
+                   DMSG(printf("is in "));
+                   DMSG(regexp_print_letter(stdout,i));
+
+                   r = s_automaton_successor(z->id,RE_EPSILON,nfa, list);    
+                   alist_insert(Ry,r);
+                   alist_delete(r);
+                   alist_insert(Ry,z->id);
+                 }
+             }
+       }
+
+      //      if (alist_is_empty(Ry))                              /* Ry = 
\empty             */
+      //       return Ry;
+
+      alist_insert(R,Ry);                                  /* R = R \cup Ry    
       */
+      alist_delete(Ry);
     }
-  PDBG(fprintf(stdout,"\n"));
 
-  free(state_list);
-  return a;
+  return R;
 }
 
-//////////////////////////////////////////////////
-//////////////////////////////////////////////////
+static void
+s_automaton_node_set_accept(astate s, Automaton nfa)
+{
+  void* idx;
+  alist_elt ptr;
 
-void 
-automaton_delete(automaton a)
+  DMSG(printf("=== setting accept for node (%s) 
:",s_automaton_id_to_str(s->id)));
+  for(ptr = alist_get_first(nfa->states) ; ptr ; ptr = 
alist_get_next(nfa->states,ptr))
+    {
+      astate ns = (astate)alist_elt_get_value(ptr);
+      idx = alist_elt_get_value(alist_get_first(ns->id));
+      DMSG(printf("%s ",s_automaton_id_to_str(ns->id)));
+      if (ns->accept && alist_is_in(s->id,idx))
+       {
+         DMSG(printf("(ok) ")); 
+         s->accept = 1;
+       }
+    }
+  DMSG(printf("\n"));
+}
+
+static Automaton 
+s_automaton_NFA_to_DFA(Automaton nfa, struct search_RegE_list_t *list)
 {
-  int i;
-  free(a->accept);
-  free(a->marque);
-  for(i=0; i < a->callocsize; i++)
+  Automaton dfa = NULL;
+  alist temp_id;
+  alist_elt ptr;
+  astate temp_state, current_state;
+  alist L;
+  int letter;
+
+  dfa = s_automaton_create();
+  L   = alist_create();
+
+  temp_id         = alist_clone(nfa->init_state->id);
+  temp_state      = s_automaton_state_create(temp_id);
+  dfa->init_state = temp_state;
+  s_automaton_add_state(dfa,temp_state);
+  alist_add(L,temp_state);
+  while (! alist_is_empty(L))
     {
-      free(a->Dtrans[i]);
+      current_state = (astate)alist_pop_first_value(L);
+      DMSG(printf("** current state = 
%s\n",s_automaton_id_to_str(current_state->id)));
+      for(letter = 1; letter < DIC_LETTERS; letter++)
+       {
+         //      DMSG(printf("*** start successor of 
%s\n",s_automaton_id_to_str(current_state->id)));
+
+         temp_id = s_automaton_successor(current_state->id,letter,nfa,list);
+
+         if (! alist_is_empty(temp_id))
+           {
+             
+             DMSG(printf("*** successor of %s for 
",s_automaton_id_to_str(current_state->id)));
+             DMSG(regexp_print_letter(stdout,letter));
+             DMSG(printf(" = %s\n", s_automaton_id_to_str(temp_id)));
+
+             temp_state = s_automaton_get_state(dfa,temp_id);
+
+             //          DMSG(printf("*** automaton get state -%s- 
ok\n",s_automaton_id_to_str(temp_id)));
+             
+             if (temp_state == NULL)
+               {
+                 temp_state = s_automaton_state_create(temp_id);
+                 s_automaton_add_state(dfa,temp_state);
+                 current_state->next[letter] = temp_state;
+                 alist_add(L,temp_state);
+               }
+             else
+               {
+                 alist_delete(temp_id);
+                 current_state->next[letter] = temp_state;
+               }
+           }
+         else
+           {
+             alist_delete(temp_id);
+           }
+       } 
     }
-  free(a->Dtrans);
-  free(a);
+
+  for(ptr = alist_get_first(dfa->states) ; ptr ; ptr = 
alist_get_next(dfa->states,ptr))
+    {
+      astate s = (astate)alist_elt_get_value(ptr);
+      s_automaton_node_set_accept(s,nfa);
+    }
+  
+  alist_delete(L);
+  return dfa;
 }
 
-//////////////////////////////////////////////////
-//////////////////////////////////////////////////
+/* ************************************************** *
+ * ************************************************** *
+ * ************************************************** */
 
-#if 0
-void 
-automaton_minimize(automaton a, automaton b)
+static automaton 
+s_automaton_finalize(Automaton a)
 {
-  int i;
-  b->nterm  = a->nterm;
-  b->nstate = a->nstate;
-  b->init   = a->init;
-  b->accept = (int*) calloc(a->nstate, sizeof(int ));  // #{etats}
-  b->marque = (int*) calloc(a->nstate, sizeof(int ));  // #{etats}
-  b->Dtrans = (int**)calloc(a->nstate, sizeof(int*));  // #{etats} * #{lettres}
-  for(i=0; i < a->nstate; i++)
+  int i,l;
+  automaton fa = NULL; 
+  alist_elt ptr;
+  astate s;
+
+  if (a == NULL)
+    return NULL;
+
+  /* creation */
+  fa = (automaton)malloc(sizeof(struct automaton_t));
+  fa->nstates = a->nstates;
+  fa->accept  = (int*) malloc((fa->nstates + 1)*sizeof(int));
+  memset(fa->accept,0,(fa->nstates + 1)*sizeof(int));
+  fa->trans   = (int**)malloc((fa->nstates + 1)*sizeof(int*));
+  for(i=0; i <= fa->nstates; i++)
     {
-      b->Dtrans[i] = (int*)calloc(256, sizeof(int));
+      fa->trans[i] = (int*)malloc(MAX_TRANSITION_LETTERS * sizeof(int));
+      memset(fa->trans[i],0,MAX_TRANSITION_LETTERS * sizeof(int));
     }
-  
-  /* NOT DONE */
+
+  /* create new id for states */
+  for(i = 1 , ptr = alist_get_first(a->states); ptr ; ptr = 
alist_get_next(a->states,ptr), i++)
+    {
+      s = (astate)alist_elt_get_value(ptr);
+      s->id_static = i;
+    }
+
+  /* build new automaton */
+  for(ptr = alist_get_first(a->states); ptr ; ptr = 
alist_get_next(a->states,ptr))
+    {
+      s = (astate)alist_elt_get_value(ptr);
+      i = s->id_static;
+
+      if (s == a->init_state) 
+       fa->init = i;
+      if (s->accept == 1)    
+       fa->accept[i] = 1;
+
+      for(l=0; l < MAX_TRANSITION_LETTERS; l++)
+       if (s->next[l])
+         fa->trans[i][l] = s->next[l]->id_static;
+    }
+
+  return fa;
 }
-#endif 
 
-//////////////////////////////////////////////////
-//////////////////////////////////////////////////
 
-#ifdef DEBUG_RE
+/* ************************************************** *
+ * ************************************************** *
+ * ************************************************** */
+
 static void 
-print_automaton_nodes(FILE* f, automaton a)
+s_automaton_print_nodes(FILE* f, Automaton a)
 {
-  int state;
-  for(state=0; state < (1 << a->nterm); state++)
+  char * sid;
+  astate s;
+  alist_elt ptr;
+  for(ptr = alist_get_first(a->states) ; ptr != NULL ; ptr = 
alist_get_next(a->states,ptr))
     {
-      if (a->marque[state])
-       {
-         fprintf(f,"\t%d [label = \"%x\"",state,state);
-         if (a->init == state)
+      s = alist_elt_get_value(ptr);
+      sid = s_automaton_id_to_str(s->id);
+      fprintf(f,"\t\"%s\" [label = \"%s\"",sid,sid);
+      if (s == a->init_state)
            {
              fprintf(f,", style = filled, color=lightgrey");
            }
-         if (a->accept[state])
-           {
-             fprintf(f,", shape = doublecircle");
-           }
-         fprintf(f,"];\n");
+      if (s->accept)
+       {
+         fprintf(f,", shape = doublecircle");
        }
+      fprintf(f,"];\n");
     }
   fprintf(f,"\n");
 }
-#endif
 
-#ifdef DEBUG_RE
 static void 
-print_automaton_edges(FILE* f, automaton a)
+s_automaton_print_edges(FILE* f, Automaton a)
 {
-  int state,letter;
-  for(state=0; state < (1 << a->nterm); state++)
+  int letter;
+  char * sid;
+  astate s;
+  alist_elt ptr;
+  for(ptr = alist_get_first(a->states) ; ptr != NULL ; ptr = 
alist_get_next(a->states,ptr))
     {
-      if (a->marque[state]) 
+      s = (astate)alist_elt_get_value(ptr);
+      for(letter=0; letter < 255; letter++)
        {
-         for(letter=0; letter < 255; letter++)
+         if (s->next[letter])
            {
-             if (a->Dtrans[state][letter])
-               {
-                 fprintf(f,"\t%d -> %d [label = 
\"",state,a->Dtrans[state][letter]);
-                 regexp_print_letter(f,letter);
-                 fprintf(f,"\"];\n");
-               }
+             sid = s_automaton_id_to_str(s->id);
+             fprintf(f,"\t\"%s\" -> ",sid);
+             sid = s_automaton_id_to_str(s->next[letter]->id);
+             fprintf(f,"\"%s\" [label = \"",sid);
+             regexp_print_letter(f,letter);
+             fprintf(f,"\"];\n");
            }
        }
     }
 }
-#endif
 
-#ifdef DEBUG_RE
-void 
-automaton_dump(automaton a, char* filename)
+static void 
+s_automaton_dump(Automaton a, char* filename)
 {
   FILE* f;
   pid_t   pid;
 
+  if (a == NULL)
+    return;
   f=fopen(filename,"w");
   fprintf(f,"digraph automaton {\n");
-  print_automaton_nodes(f,a);
-  print_automaton_edges(f,a);
+  s_automaton_print_nodes(f,a);
+  s_automaton_print_edges(f,a);
   fprintf(f,"fontsize=20;\n");
   fprintf(f,"}\n");
   fclose(f);
@@ -251,8 +680,8 @@
   }
 #endif
 }
-#endif
 
-//////////////////////////////////////////////////
-//////////////////////////////////////////////////
+/* ************************************************** *
+ * ************************************************** *
+ * ************************************************** */
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]