[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Eliot-dev] eliot/dic automaton.cpp automaton.h [cppdic]
From: |
eliot-dev |
Subject: |
[Eliot-dev] eliot/dic automaton.cpp automaton.h [cppdic] |
Date: |
Sat, 21 Oct 2006 19:07:10 +0000 |
CVSROOT: /sources/eliot
Module name: eliot
Branch: cppdic
Changes by: Olivier Teulière <ipkiss> 06/10/21 19:07:10
Modified files:
dic : automaton.cpp automaton.h
Log message:
The AutomatonHelper is now a class too
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/automaton.cpp?cvsroot=eliot&only_with_tag=cppdic&r1=1.1.2.1&r2=1.1.2.2
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/automaton.h?cvsroot=eliot&only_with_tag=cppdic&r1=1.11.2.1&r2=1.11.2.2
Patches:
Index: automaton.cpp
===================================================================
RCS file: /sources/eliot/eliot/dic/Attic/automaton.cpp,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -b -r1.1.2.1 -r1.1.2.2
--- automaton.cpp 15 Oct 2006 11:07:54 -0000 1.1.2.1
+++ automaton.cpp 21 Oct 2006 19:07:09 -0000 1.1.2.2
@@ -44,7 +44,7 @@
using namespace std;
#ifdef DEBUG_AUTOMATON
-#define DMSG(a) a
+#define DMSG(a) (a)
#else
#define DMSG(a)
#endif
@@ -52,46 +52,51 @@
#define MAX_TRANSITION_LETTERS 256
typedef struct automaton_state_t *astate;
-typedef struct Automaton_t *AutomatonHelper;
-
-/* ************************************************** *
- exported functions for static automata
- * ************************************************** */
-
-automaton automaton_build (int init_state, int *ptl, int *PS, struct
search_RegE_list_t *iList);
-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
+ Helper class, allowing to build a NFA, then a DFA
* ************************************************** */
-static AutomatonHelper s_automaton_create ();
-static void s_automaton_delete (AutomatonHelper a);
-
-static set<int> s_automaton_id_create (int id);
-static char* s_automaton_id_to_str (const set<int> &iId);
-
-static astate s_automaton_state_create (const set<int> &iId);
-
-static void s_automaton_add_state (AutomatonHelper a, astate s);
-static astate s_automaton_get_state (AutomatonHelper a, const set<int>
&iId);
+class AutomatonHelper
+{
+public:
+ AutomatonHelper(astate iInitState);
+ ~AutomatonHelper();
-static AutomatonHelper s_automaton_PS_to_NFA (int init_state, int *ptl,
int *PS);
-static AutomatonHelper s_automaton_NFA_to_DFA (AutomatonHelper a, struct
search_RegE_list_t *iList);
+ astate getInitState() const { return m_initState; }
#ifdef DEBUG_AUTOMATON
-static void s_automaton_dump (AutomatonHelper a, char*
filename);
+ void dump(const string &iFileName) const;
#endif
+ static AutomatonHelper *ps2nfa(int iInitState, int *ptl, int *PS);
+ static AutomatonHelper *nfa2dfa(const AutomatonHelper &iNfa,
+ struct search_RegE_list_t *iList);
+
+ /// List of states
+ list<astate> m_states;
+
+private:
+ /// Initial state of the automaton
+ astate m_initState;
+
+ void addState(astate s);
+ astate getState(const set<int> &iId) const;
+ void printNodes(FILE* f) const;
+ void printEdges(FILE* f) const;
+ void setAccept(astate s) const;
+ set<int> getSuccessor(const set<int> &S, int letter, struct
search_RegE_list_t *iList) const;
+};
+
+
/* ************************************************** *
- data types
+ State handling
* ************************************************** */
+static set<int> s_state_id_create(int id);
+static string s_state_id_to_str(const set<int> &iId);
+static astate s_state_create (const set<int> &iId);
+
struct automaton_state_t
{
set<int> id;
@@ -100,41 +105,27 @@
astate next[MAX_TRANSITION_LETTERS];
};
-struct Automaton_t
-{
- int nstates;
- astate init_state;
- list<astate> states;
-};
-
-struct automaton_t
-{
- int nstates;
- int init;
- int *accept;
- int **trans;
-};
/* ************************************************** *
- exported functions for static automata
+ Definition of the Automaton class
* ************************************************** */
-Automaton::Automaton(int init_state, int *ptl, int *PS, struct
search_RegE_list_t *iList)
+Automaton::Automaton(int iInitState, int *ptl, int *PS, struct
search_RegE_list_t *iList)
{
- AutomatonHelper nfa = s_automaton_PS_to_NFA(init_state, ptl, PS);
+ AutomatonHelper *nfa = AutomatonHelper::ps2nfa(iInitState, ptl, PS);
DMSG(printf("\n non deterministic automaton OK \n\n"));
- DMSG(s_automaton_dump(nfa, "auto_nfa"));
+ DMSG(nfa->dump("auto_nfa"));
- AutomatonHelper dfa = s_automaton_NFA_to_DFA(nfa, iList);
+ AutomatonHelper *dfa = AutomatonHelper::nfa2dfa(*nfa, iList);
DMSG(printf("\n deterministic automaton OK \n\n"));
- DMSG(s_automaton_dump(dfa, "auto_dfa"));
+ DMSG(dfa->dump("auto_dfa"));
- finalize(dfa);
+ finalize(*dfa);
DMSG(printf("\n final automaton OK \n\n"));
- DMSG(automaton_dump(final, "auto_fin"));
+ DMSG(automaton_dump("auto_fin"));
- s_automaton_delete(nfa);
- s_automaton_delete(dfa);
+ delete nfa;
+ delete dfa;
}
@@ -149,7 +140,49 @@
}
-void Automaton::dump(const string &iFileName)
+void Automaton::finalize(const AutomatonHelper &iHelper)
+{
+ /* Creation */
+ m_nbStates = iHelper.m_states.size();
+ m_acceptors = new bool[m_nbStates + 1];
+ memset(m_acceptors, 0, (m_nbStates + 1) * sizeof(bool));
+ m_transitions = new int*[m_nbStates + 1];
+ for (int i = 0; i <= m_nbStates; i++)
+ {
+ m_transitions[i] = new int[MAX_TRANSITION_LETTERS];
+ memset(m_transitions[i], 0, MAX_TRANSITION_LETTERS * sizeof(int));
+ }
+
+ /* Create new id for states */
+ list<astate>::const_iterator it;
+ int i;
+ for (i = 1, it = iHelper.m_states.begin();
+ it != iHelper.m_states.end(); it++, i++)
+ {
+ (*it)->id_static = i;
+ }
+
+ /* Build new automaton */
+ for (it = iHelper.m_states.begin(); it != iHelper.m_states.end(); it++)
+ {
+ astate s = *it;
+ int i = s->id_static;
+
+ if (s == iHelper.getInitState())
+ m_init = i;
+ if (s->accept == 1)
+ m_acceptors[i] = true;
+
+ for (int l = 0; l < MAX_TRANSITION_LETTERS; l++)
+ {
+ if (s->next[l])
+ m_transitions[i][l] = s->next[l]->id_static;
+ }
+ }
+}
+
+
+void Automaton::dump(const string &iFileName) const
{
FILE *f = fopen(iFileName.c_str(), "w");
fprintf(f, "digraph automaton {\n");
@@ -194,31 +227,12 @@
#endif
}
+
/* ************************************************** *
- * ************************************************** *
+ Definition of the state handling methods
* ************************************************** */
-static AutomatonHelper s_automaton_create()
-{
- AutomatonHelper a = new struct Automaton_t();
- a->nstates = 0;
- a->init_state = NULL;
- return a;
-}
-
-
-static void s_automaton_delete(AutomatonHelper a)
-{
- list<astate>::const_iterator it;
- for (it = a->states.begin(); it != a->states.end(); it++)
- {
- delete *it;
- }
- delete a;
-}
-
-
-static set<int> s_automaton_id_create(int id)
+static set<int> s_state_id_create(int id)
{
set<int> l;
l.insert(id);
@@ -226,50 +240,68 @@
}
-static char* s_automaton_id_to_str(const set<int> &iId)
+static string s_state_id_to_str(const set<int> &iId)
{
- static char s[250];
- memset(s, 0, sizeof(s));
+ string s;
set<int>::const_iterator it;
for (it = iId.begin(); it != iId.end(); it++)
{
char tmp[50];
sprintf(tmp, "%d ", *it);
- strcat(s, tmp);
+ s += tmp;
}
return s;
}
-static astate s_automaton_state_create(const set<int> &iId)
+static astate s_state_create(const set<int> &iId)
{
astate s = new automaton_state_t();
// TODO: use copy constructor
s->id = iId;
s->accept = 0;
memset(s->next, 0, sizeof(astate)*MAX_TRANSITION_LETTERS);
- DMSG(printf("** state %s creation\n", s_automaton_id_to_str(iId)));
+ DMSG(printf("** state %s creation\n", s_state_id_to_str(iId).c_str()));
return s;
}
-static void s_automaton_add_state(AutomatonHelper a, astate s)
+/* ************************************************** *
+ Definition of the AutomatonHelper class
+ * ************************************************** */
+
+AutomatonHelper::AutomatonHelper(astate iInitState)
+ : m_initState(iInitState)
+{
+}
+
+
+AutomatonHelper::~AutomatonHelper()
+{
+ list<astate>::const_iterator it;
+ for (it = m_states.begin(); it != m_states.end(); it++)
+ {
+ delete *it;
+ }
+}
+
+
+void AutomatonHelper::addState(astate s)
{
- a->nstates++;
- a->states.push_front(s);
- DMSG(printf("** state %s added to automaton\n",
s_automaton_id_to_str(s->id)));
+ m_states.push_front(s);
+ DMSG(printf("** state %s added to automaton\n",
s_state_id_to_str(s->id).c_str()));
}
-static astate s_automaton_get_state(AutomatonHelper a, const set<int> &iId)
+astate AutomatonHelper::getState(const set<int> &iId) const
{
list<astate>::const_iterator it;
- for (it = a->states.begin(); it != a->states.end(); it++)
+ for (it = m_states.begin(); it != m_states.end(); it++)
{
astate s = *it;
if (s->id == iId)
{
- //DMSG(printf("** get state %s ok\n",
s_automaton_id_to_str(s->id)));
+ //DMSG(printf("** get state %s ok\n",
s_state_id_to_str(s->id).c_str()));
return s;
}
}
@@ -280,19 +312,18 @@
* ************************************************** *
* ************************************************** */
-AutomatonHelper s_automaton_PS_to_NFA(int init_state_id, int *ptl, int *PS)
+AutomatonHelper *AutomatonHelper::ps2nfa(int init_state_id, int *ptl, int *PS)
{
int maxpos = PS[0];
astate current_state;
char used_letter[MAX_TRANSITION_LETTERS];
- AutomatonHelper nfa = s_automaton_create();
/* 1: init_state = root->PP */
- set<int> temp_id0 = s_automaton_id_create(init_state_id);
- astate temp_state = s_automaton_state_create(temp_id0);
- nfa->init_state = temp_state;
- s_automaton_add_state(nfa, temp_state);
+ set<int> temp_id0 = s_state_id_create(init_state_id);
+ astate temp_state = s_state_create(temp_id0);
+ AutomatonHelper *nfa = new AutomatonHelper(temp_state);
+ nfa->addState(temp_state);
list<astate> L;
L.push_front(temp_state);
/* 2: while \exist state \in state_list */
@@ -300,7 +331,7 @@
{
current_state = L.front();
L.pop_front();
- DMSG(printf("** current state = %s\n",
s_automaton_id_to_str(current_state->id)));
+ DMSG(printf("** current state = %s\n",
s_state_id_to_str(current_state->id).c_str()));
memset(used_letter, 0, sizeof(used_letter));
/* 3: \foreach l in \sigma | l \neq # */
for (int p = 1; p < maxpos; p++)
@@ -319,12 +350,12 @@
/* 5: transition from current_state to temp_state */
if (ens)
{
- set<int> temp_id = s_automaton_id_create(ens);
- temp_state = s_automaton_get_state(nfa, temp_id);
+ set<int> temp_id = s_state_id_create(ens);
+ temp_state = nfa->getState(temp_id);
if (temp_state == NULL)
{
- temp_state = s_automaton_state_create(temp_id);
- s_automaton_add_state(nfa, temp_state);
+ temp_state = s_state_create(temp_id);
+ nfa->addState(temp_state);
current_state->next[current_letter] = temp_state;
L.push_front(temp_state);
}
@@ -339,7 +370,7 @@
}
list<astate>::const_iterator it;
- for (it = nfa->states.begin(); it != nfa->states.end(); it++)
+ for (it = nfa->m_states.begin(); it != nfa->m_states.end(); it++)
{
astate s = *it;
if (*(s->id.begin()) & (1 << (maxpos - 1)))
@@ -353,7 +384,9 @@
* ************************************************** *
* ************************************************** */
-static set<int> s_automaton_successor(const set<int> &S, int letter,
AutomatonHelper nfa, struct search_RegE_list_t *iList)
+set<int> AutomatonHelper::getSuccessor(const set<int> &S,
+ int letter,
+ struct search_RegE_list_t *iList) const
{
set<int> R, r;
set<int>::const_iterator it;
@@ -361,14 +394,14 @@
{
astate y, z;
- set<int> t = s_automaton_id_create(*it);
- assert(y = s_automaton_get_state(nfa, t));
+ set<int> t = s_state_id_create(*it);
+ assert(y = getState(t));
set<int> Ry; /* Ry = \empty
*/
if ((z = y->next[letter]) != NULL) /* \delta (y,z) =
l */
{
- r = s_automaton_successor(z->id, RE_EPSILON, nfa, iList);
+ r = getSuccessor(z->id, RE_EPSILON, iList);
Ry.insert(r.begin(), r.end());
Ry.insert(z->id.begin(), z->id.end()); /* Ry = Ry \cup succ(z)
*/
}
@@ -376,7 +409,7 @@
/* \epsilon transition from start node */
if ((z = y->next[RE_EPSILON]) != NULL) /* \delta (y,z) =
\epsilon */
{
- r = s_automaton_successor(z->id, letter, nfa, iList);
+ r = getSuccessor(z->id, letter, iList);
Ry.insert(r.begin(), r.end()); /* Ry = Ry \cup succ(z) */
}
@@ -393,7 +426,7 @@
DMSG(printf("is in "));
DMSG(regexp_print_letter(stdout, i));
- r = s_automaton_successor(z->id, RE_EPSILON, nfa,
iList);
+ r = getSuccessor(z->id, RE_EPSILON, iList);
Ry.insert(r.begin(), r.end());
Ry.insert(z->id.begin(), z->id.end());
}
@@ -413,15 +446,15 @@
}
-static void s_automaton_node_set_accept(astate s, AutomatonHelper nfa)
+void AutomatonHelper::setAccept(astate s) const
{
- DMSG(printf("=== setting accept for node (%s) :",
s_automaton_id_to_str(s->id)));
+ DMSG(printf("=== setting accept for node (%s) :",
s_state_id_to_str(s->id).c_str()));
list<astate>::const_iterator it;
- for (it = nfa->states.begin(); it != nfa->states.end(); it++)
+ for (it = m_states.begin(); it != m_states.end(); it++)
{
astate ns = *it;
int idx = *(ns->id.begin());
- DMSG(printf("%s ", s_automaton_id_to_str(ns->id)));
+ DMSG(printf("%s ", s_state_id_to_str(ns->id).c_str()));
if (ns->accept && (find(s->id.begin(), s->id.end(), idx) !=
s->id.end()))
{
DMSG(printf("(ok) "));
@@ -432,45 +465,45 @@
}
-static AutomatonHelper s_automaton_NFA_to_DFA(AutomatonHelper nfa, struct
search_RegE_list_t *iList)
+AutomatonHelper *AutomatonHelper::nfa2dfa(const AutomatonHelper &iNfa,
+ struct search_RegE_list_t *iList)
{
astate current_state;
- AutomatonHelper dfa = s_automaton_create();
list<astate> L;
// Clone the list
- set<int> temp_id0 = nfa->init_state->id;
- astate temp_state = s_automaton_state_create(temp_id0);
- dfa->init_state = temp_state;
- s_automaton_add_state(dfa, temp_state);
+ set<int> temp_id0 = iNfa.m_initState->id;
+ astate temp_state = s_state_create(temp_id0);
+ AutomatonHelper *dfa = new AutomatonHelper(temp_state);
+ dfa->addState(temp_state);
L.push_front(temp_state);
while (! L.empty())
{
current_state = L.front();
L.pop_front();
- DMSG(printf("** current state = %s\n",
s_automaton_id_to_str(current_state->id)));
+ DMSG(printf("** current state = %s\n",
s_state_id_to_str(current_state->id).c_str()));
for (int letter = 1; letter < DIC_LETTERS; letter++)
{
- // DMSG(printf("*** start successor of %s\n",
s_automaton_id_to_str(current_state->id)));
+ // DMSG(printf("*** start successor of %s\n",
s_state_id_to_str(current_state->id).c_str()));
- set<int> temp_id = s_automaton_successor(current_state->id,
letter, nfa, iList);
+ set<int> temp_id = iNfa.getSuccessor(current_state->id, letter,
iList);
if (! temp_id.empty())
{
- DMSG(printf("*** successor of %s for ",
s_automaton_id_to_str(current_state->id)));
+ DMSG(printf("*** successor of %s for ",
s_state_id_to_str(current_state->id).c_str()));
DMSG(regexp_print_letter(stdout, letter));
- DMSG(printf(" = %s\n", s_automaton_id_to_str(temp_id)));
+ DMSG(printf(" = %s\n", s_state_id_to_str(temp_id).c_str()));
- temp_state = s_automaton_get_state(dfa, temp_id);
+ temp_state = dfa->getState(temp_id);
- // DMSG(printf("*** automaton get state -%s- ok\n",
s_automaton_id_to_str(temp_id)));
+ // DMSG(printf("*** automaton get state -%s- ok\n",
s_state_id_to_str(temp_id).c_str()));
if (temp_state == NULL)
{
- temp_state = s_automaton_state_create(temp_id);
- s_automaton_add_state(dfa, temp_state);
+ temp_state = s_state_create(temp_id);
+ dfa->addState(temp_state);
current_state->next[letter] = temp_state;
L.push_front(temp_state);
}
@@ -483,9 +516,9 @@
}
list<astate>::const_iterator it;
- for (it = dfa->states.begin(); it != dfa->states.end(); it++)
+ for (it = dfa->m_states.begin(); it != dfa->m_states.end(); it++)
{
- s_automaton_node_set_accept(*it, nfa);
+ iNfa.setAccept(*it);
}
return dfa;
@@ -495,60 +528,15 @@
* ************************************************** *
* ************************************************** */
-void Automaton::finalize(AutomatonHelper a)
+void AutomatonHelper::printNodes(FILE* f) const
{
- /* Creation */
- m_nbStates = a->nstates;
- m_acceptors = new bool[m_nbStates + 1];
- memset(m_acceptors, 0, (m_nbStates + 1) * sizeof(bool));
- m_transitions = new int*[m_nbStates + 1];
- for (int i = 0; i <= m_nbStates; i++)
- {
- m_transitions[i] = new int[MAX_TRANSITION_LETTERS];
- memset(m_transitions[i], 0, MAX_TRANSITION_LETTERS * sizeof(int));
- }
-
- /* Create new id for states */
list<astate>::const_iterator it;
- int i;
- for (i = 1, it = a->states.begin(); it != a->states.end(); it++, i++)
- {
- (*it)->id_static = i;
- }
-
- /* Build new automaton */
- for (it = a->states.begin(); it != a->states.end(); it++)
- {
- astate s = *it;
- int i = s->id_static;
-
- if (s == a->init_state)
- m_init = i;
- if (s->accept == 1)
- m_acceptors[i] = true;
-
- for (int l = 0; l < MAX_TRANSITION_LETTERS; l++)
- {
- if (s->next[l])
- m_transitions[i][l] = s->next[l]->id_static;
- }
- }
-}
-
-
-/* ************************************************** *
- * ************************************************** *
- * ************************************************** */
-
-static void s_automaton_print_nodes(FILE* f, AutomatonHelper a)
-{
- list<astate>::const_iterator it;
- for (it = a->states.begin(); it != a->states.end(); it++)
+ for (it = m_states.begin(); it != m_states.end(); it++)
{
astate s = *it;
- char *sid = s_automaton_id_to_str(s->id);
- fprintf(f, "\t\"%s\" [label = \"%s\"", sid, sid);
- if (s == a->init_state)
+ string sid = s_state_id_to_str(s->id);
+ fprintf(f, "\t\"%s\" [label = \"%s\"", sid.c_str(), sid.c_str());
+ if (s == m_initState)
{
fprintf(f, ", style = filled, color=lightgrey");
}
@@ -562,20 +550,20 @@
}
-static void s_automaton_print_edges(FILE* f, AutomatonHelper a)
+void AutomatonHelper::printEdges(FILE* f) const
{
list<astate>::const_iterator it;
- for (it = a->states.begin(); it != a->states.end(); it++)
+ for (it = m_states.begin(); it != m_states.end(); it++)
{
astate s = *it;
for (int letter = 0; letter < 255; letter++)
{
if (s->next[letter])
{
- char * 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);
+ string sid = s_state_id_to_str(s->id);
+ fprintf(f, "\t\"%s\" -> ", sid.c_str());
+ sid = s_state_id_to_str(s->next[letter]->id);
+ fprintf(f, "\"%s\" [label = \"", sid.c_str());
regexp_print_letter(f, letter);
fprintf(f, "\"];\n");
}
@@ -584,14 +572,13 @@
}
-static void s_automaton_dump(AutomatonHelper a, char* filename)
+#ifdef DEBUG_AUTOMATON
+void AutomatonHelper::dump(const string &iFileName) const
{
- if (a == NULL)
- return;
- FILE *f = fopen(filename, "w");
+ FILE *f = fopen(iFileName.c_str(), "w");
fprintf(f, "digraph automaton {\n");
- s_automaton_print_nodes(f, a);
- s_automaton_print_edges(f, a);
+ printNodes(f);
+ printEdges(f);
fprintf(f, "fontsize=20;\n");
fprintf(f, "}\n");
fclose(f);
@@ -604,14 +591,11 @@
}
else if (pid == 0)
{
- execlp("dotty", "dotty", filename, NULL);
+ execlp("dotty", "dotty", iFileName.c_str(), NULL);
printf("exec dotty failed\n");
exit(1);
}
#endif
}
-
-/* ************************************************** *
- * ************************************************** *
- * ************************************************** */
+#endif
Index: automaton.h
===================================================================
RCS file: /sources/eliot/eliot/dic/automaton.h,v
retrieving revision 1.11.2.1
retrieving revision 1.11.2.2
diff -u -b -r1.11.2.1 -r1.11.2.2
--- automaton.h 15 Oct 2006 11:07:55 -0000 1.11.2.1
+++ automaton.h 21 Oct 2006 19:07:09 -0000 1.11.2.2
@@ -27,8 +27,7 @@
#ifndef _DIC_AUTOMATON_H_
#define _DIC_AUTOMATON_H_
-typedef struct automaton_t *automaton;
-typedef struct Automaton_t *AutomatonHelper;
+class AutomatonHelper;
class Automaton
{
@@ -71,9 +70,9 @@
}
/**
- * Dump the automaton into a file
+ * Dump the automaton into a file (for debugging purposes)
*/
- void dump(const string &iFileName);
+ void dump(const string &iFileName) const;
private:
/// Number of states
@@ -88,7 +87,7 @@
/// Matrix of transitions
int **m_transitions;
- void finalize(AutomatonHelper a);
+ void finalize(const AutomatonHelper &a);
};
#endif /* _DIC_AUTOMATON_H_ */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Eliot-dev] eliot/dic automaton.cpp automaton.h [cppdic],
eliot-dev <=