Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

FSM Class Reference

#include <FSM.hpp>

List of all members.

Public Methods

void * operator new (size_t size, MemStreamer *mem)
void operator delete (void *ptr)
FSMStateCreateState (FSMStateSetItem *list)
FSMEdgeCreateLabelEdge (FSMState *fromstate, FSMState *tostate, TLabelID labelid)
FSMEdgeCreateNegEdge (FSMState *fromstate, FSMState *tostate, FSMLabel *labellist=NULL)
FSMEdgeCreateEmptyEdge (FSMState *fromstate, FSMState *tostate)
void SetStartState (FSMState *mystartstate)
FSMStateGetStartState ()
FSMStateGetStateList ()
FSM * MakeDeterministic ()
FSM * Minimize ()
void AddFSM (FSMState *fromstate, FSMState *tostate, FSM *fsm)
void EliminateRedundantPoundEdges ()
void ComputeOutCompleteness ()
void FindAcceptingStates ()
void ComputeStatesHasPoundsAhead ()
FSM * CreateReverseFSM ()


Member Function Documentation

void FSM::AddFSM FSMState   fromstate,
FSMState   tostate,
FSM *    fsm
 

Definition at line 1508 of file FSM.cpp.

01510 {
01511    FSMState *curstate=fsm->GetStateList(),*newstate;
01512 
01513    // First, we create all the states and
01514    // we set 'curstate->data' to the new state
01515    while(curstate!=NULL)
01516    {
01517       // For the start state, we simply use the 'fromstate' state
01518       if(curstate==fsm->GetStartState())
01519          curstate=fromstate;
01520       else
01521       {
01522          newstate=CreateState((char)0);
01523          curstate->data=newstate;
01524       }
01525       if(curstate->IsFinal())
01526          // For final states, we create an empty edge to 'tostate'
01527          CreateEmptyEdge((FSMState *)(curstate->data),tostate);
01528 
01529       curstate=curstate->next;
01530    }
01531 
01532    // Now, we can take care of the edges
01533    curstate=fsm->GetStateList();
01534 
01535    FSMEdge  *outedge;
01536 
01537    // We only need to copy the edges
01538 
01539    while(curstate!=NULL)
01540    {
01541       outedge=curstate->GetOutEdges();
01542       while(outedge!=NULL)
01543       {
01544          switch(outedge->GetType())
01545          {
01546          case EDGETYPE_LABEL:
01547             CreateLabelEdge((FSMState *)(curstate->data),
01548                             (FSMState *)(outedge->GetNextState()->data),
01549                             outedge->labelid);
01550             break;
01551 
01552          case EDGETYPE_NEGLABELLIST:
01553          {
01554             FSMLabel *newlabellist=NULL;
01555 
01556             DupLabelList(outedge->labellist,&newlabellist);
01557 
01558             CreateNegEdge((FSMState *)(curstate->data),
01559                               (FSMState *)(outedge->GetNextState()->data),
01560                               newlabellist);
01561             break;
01562          }
01563 
01564          case EDGETYPE_EMPTY:
01565             CreateEmptyEdge((FSMState *)(curstate->data),
01566                               (FSMState *)(outedge->GetNextState()->data));
01567             break;
01568          }
01569 
01570          outedge=outedge->next;
01571       }
01572       curstate=curstate->next;
01573    }
01574 }

void FSM::ComputeOutCompleteness  
 

Definition at line 1216 of file FSM.cpp.

01219 {
01220    FSMState *curstate=statelist;
01221 
01222    while(curstate!=NULL)
01223    {
01224       curstate->ComputeOutCompleteness();
01225       curstate=curstate->next;
01226    }
01227 }

void FSM::ComputeStatesHasPoundsAhead  
 

Definition at line 1328 of file FSM.cpp.

01329 {
01330    FSMState *curstate=statelist;
01331 
01332    // We initialize the 'tmpval' elements to '0'
01333    while(curstate!=NULL)
01334    {
01335       curstate->tmpval=0;
01336       curstate=curstate->next;
01337    }
01338    // We compute the accepting status, starting with 'startstate'
01339    startstate->HasPoundsAheadRecurs();
01340 }

FSMEdge * FSM::CreateEmptyEdge FSMState   fromstate,
FSMState   tostate
 

Definition at line 252 of file FSM.cpp.

00254 {
00255    FSMEdge *edge=new(fsmmem) FSMEdge(tostate);
00256 
00257    edge->next=fromstate->outedges;
00258    fromstate->outedges=edge;
00259    return edge;
00260 }

FSMEdge * FSM::CreateLabelEdge FSMState   fromstate,
FSMState   tostate,
TLabelID    labelid
 

Definition at line 232 of file FSM.cpp.

Referenced by ConsiderLabelIDAtState().

00234 {
00235    FSMEdge *edge=new(fsmmem) FSMEdge(tostate,labelid);
00236 
00237    edge->next=fromstate->outedges;
00238    fromstate->outedges=edge;
00239    return edge;
00240 }

FSMEdge * FSM::CreateNegEdge FSMState   fromstate,
FSMState   tostate,
FSMLabel   labellist = NULL
 

Definition at line 242 of file FSM.cpp.

Referenced by ConsiderNegEdgeAtState().

00244 {
00245    FSMEdge *edge=new(fsmmem) FSMEdge(tostate,labellist);
00246 
00247    edge->next=fromstate->outedges;
00248    fromstate->outedges=edge;
00249    return edge;
00250 }

FSM * FSM::CreateReverseFSM  
 

Definition at line 1580 of file FSM.cpp.

01583 {
01584    FSMState *newstate;
01585    FSMEdge  *edge;
01586 
01587    FSM *newfsm=new(fsmmem) FSM();
01588 
01589    // We create a new start state
01590    // This start state will be connected to all final states 
01591    // of the original FSM
01592    FSMState *newstartstate=newfsm->CreateState();
01593 
01594    newfsm->SetStartState(newstartstate);
01595 
01596    FSMState *curstate=statelist;
01597 
01598    // First, we copy all the states
01599    // The start state becomes the new final state
01600    // Furthermore, if the original state is final, then it becomes
01601    // a new start state - we simulate this by creating an empty edge
01602    // between 'newstartstate' and 'newstate'
01603    while(curstate!=NULL)
01604    {
01605       newstate=newfsm->CreateState(curstate==startstate);
01606 
01607       if(curstate->IsFinal())
01608          newfsm->CreateEmptyEdge(newstartstate,newstate);
01609 
01610       curstate->data=newstate;
01611       curstate=curstate->next;
01612    }
01613 
01614    // Now, we consider all states and we create the edges
01615    curstate=statelist;
01616    
01617    while(curstate!=NULL)
01618    {
01619       edge=curstate->GetOutEdges();
01620       while(edge!=NULL)
01621       {
01622          switch(edge->GetType())
01623          {
01624          case EDGETYPE_LABEL:
01625             newfsm->CreateLabelEdge((FSMState *)(edge->GetNextState()->data),
01626                                     (FSMState *)(curstate->data),
01627                                     edge->GetLabelID());
01628             break;
01629 
01630          case EDGETYPE_NEGLABELLIST:
01631          {
01632             FSMLabel *newlabellist=NULL;
01633 
01634             DupLabelList(edge->GetLabelList(),&newlabellist);
01635 
01636             newfsm->CreateNegEdge(  (FSMState *)(edge->GetNextState()->data),
01637                                     (FSMState *)(curstate->data),
01638                                     newlabellist);
01639             break;
01640          }
01641          case EDGETYPE_EMPTY:
01642             newfsm->CreateEmptyEdge((FSMState *)(edge->GetNextState()->data),
01643                                     (FSMState *)(curstate->data));
01644             break;
01645          }
01646          edge=edge->next;
01647       }
01648       curstate=curstate->next;
01649    }
01650    return newfsm;
01651 }

FSMState * FSM::CreateState FSMStateSetItem   list [inline]
 

Definition at line 319 of file FSM.cpp.

Referenced by VRegExpr::CreateNonDetFSM().

00321 {
00322   FSMState *newstate=new(fsmmem) FSMState(curidx,list);
00323 
00324   curidx++;
00325   *laststatelistref=newstate;
00326   laststatelistref=&((*laststatelistref)->next);
00327 
00328   return newstate;
00329 }

void FSM::EliminateRedundantPoundEdges  
 

Definition at line 1112 of file FSM.cpp.

01116 {
01117    FSMState *state=statelist;
01118    while(state!=NULL)
01119    {
01120       state->EliminateRedundantPoundEdges();
01121       state=state->next;
01122    }
01123 }

void FSM::FindAcceptingStates  
 

Definition at line 1264 of file FSM.cpp.

01267                     : all following states are final states
01268 {
01269    FSMState *curstate=statelist;
01270 
01271    // First, let's compute the out-completeness of all states
01272    // States that are not out-complete can never be accepting
01273    ComputeOutCompleteness();
01274 
01275    // We initialize the 'tmpval' elements to '0'
01276    while(curstate!=NULL)
01277    {
01278       curstate->tmpval=0;
01279       curstate=curstate->next;
01280    }
01281    // We compute the accepting status, starting with 'startstate'
01282    startstate->FindAcceptingStatesRecurs();
01283 }

FSMState* FSM::GetStartState   [inline]
 

Definition at line 291 of file FSM.hpp.

00291 {  return startstate;   }

FSMState* FSM::GetStateList   [inline]
 

Definition at line 292 of file FSM.hpp.

00292 {  return statelist; }

FSM * FSM::MakeDeterministic  
 

Definition at line 565 of file FSM.cpp.

Referenced by VRegExpr::CreateFSM().

00567 {
00568    FSMStateSetItem   *todolist=NULL,**todoref=&todolist;
00569       // The 'todolist' contains the list of deterministic states that still
00570       // have to be considered
00571    FSMLabel          *tmplabellist,*curlabel;
00572    FSMState          *curstate,*newnextstate;
00573    FSM               *newfsm=new(fsmmem) FSM();
00574 
00575    FSMStateSetItem   *startstateset=NULL;
00576 
00577    // The start state set only contains the start state
00578    startstateset=AddToStateSet(startstateset,startstate);
00579 
00580    // We create a corresponding deterministic start state
00581    curstate=newfsm->CreateState(startstateset);
00582 
00583    newfsm->SetStartState(curstate);
00584 
00585    // We now always consider 'curstate' - the previously created deterministic state
00586    do
00587    {
00588       // First, we find all distinct outgoing labels for 'curstate'
00589       tmplabellist=NULL;
00590       FindAllOutgoingLabels(curstate->GetOrigStateSet(),&tmplabellist);
00591 
00592       // We consider the negedge for the current state
00593 
00594       if(ConsiderNegEdgeAtState(newfsm,curstate,tmplabellist,newfsm->GetStateList(),&newnextstate)==1)
00595          // A new state has been created?
00596          // ==> We add the state to the 'todo'-list
00597          todolist=new FSMStateSetItem(newnextstate,todolist);
00598 
00599       // Now, we also consider the label edges of the current state
00600 
00601       curlabel=tmplabellist;
00602       while(curlabel!=NULL)
00603       {
00604          if(ConsiderLabelIDAtState(newfsm,curstate,curlabel->labelid,newfsm->GetStateList(),&newnextstate)==1)
00605             // A new state has been created?
00606             // ==> We add the state to the 'todo'-list
00607             todolist=new FSMStateSetItem(newnextstate,todolist);
00608 
00609          curlabel=curlabel->next;
00610       }
00611 
00612       if(todolist==NULL)
00613          break;
00614 
00615       // We go to next element of todo-list
00616       curstate=todolist->state;
00617       todolist=todolist->next;
00618    }
00619    while(1);
00620 
00621    return newfsm;
00622 }

FSM * FSM::Minimize  
 

Definition at line 723 of file FSM.cpp.

Referenced by VRegExpr::CreateFSM().

00724 {
00725    int            statenum,i,j;
00726    FSMState       *curstate1,*curstate2;
00727    StateEqualPair *pairptr;
00728    FSMLabel       *tmplabellist,*curlabel;
00729 
00730    // Let's get rid of redundant states first
00731    PruneRedundantStates();
00732 
00733    // We create a NxN array where N is the number of states in the FSM
00734    // Each array field represents a state-pair and we keep track of when
00735    // two states could be equivalent.
00736 
00737    statenum=GetStateCount();
00738 
00739    StateEqualPair **array=(StateEqualPair **)fsmtmpmem->GetByteBlock(statenum*sizeof(StateEqualPair *));
00740 
00741    curstate1=statelist;
00742 
00743    // We initialize the array of states
00744    // Two states can definitely not be equal, if one of them is a final state and the other not
00745    // Note that we only need to consider array fields [i,j] with j<i
00746    for(i=0;i<statenum;i++)
00747    {
00748       array[i]=new StateEqualPair[i];
00749 
00750       pairptr=array[i];
00751 
00752       curstate2=statelist;
00753 
00754       for(j=0;j<i;j++)
00755       {
00756          pairptr->state1      =curstate1;
00757          pairptr->state2      =curstate2;
00758          pairptr->dependlist  =NULL;
00759          pairptr->isnotequal  =(curstate1->IsFinal() != curstate2->IsFinal());
00760 
00761          pairptr++;
00762          curstate2=curstate2->next;
00763       }
00764       curstate1=curstate1->next;
00765    }
00766 
00767    curstate1=statelist;
00768 
00769    // Now we look at each state-pair separately
00770    // We only consider array fields [i,j] with j<i
00771    for(i=0;i<statenum;i++)
00772    {
00773       pairptr=array[i];
00774 
00775       curstate2=statelist;
00776 
00777       for(j=0;j<i;j++)
00778       {
00779          // We first find the labels on all outgoing edges
00780 
00781          tmplabellist=NULL;
00782          FindAllOutgoingLabels(curstate1,&tmplabellist);
00783          FindAllOutgoingLabels(curstate2,&tmplabellist);
00784 
00785          // Now, for each label in 'tmplabellist', we check whether
00786          // the states that would be reached for that label are equal.
00787          // If for some label they are not equal, then we need to add a dependency
00788          curlabel=tmplabellist;
00789          while(curlabel!=NULL)
00790          {
00791             if(CheckEqual( curstate1->GetNextState(curlabel->labelid),
00792                            curstate2->GetNextState(curlabel->labelid),array)==0)
00793                break;
00794             curlabel=curlabel->next;
00795          }
00796 
00797 
00798          if(curlabel==NULL)   // Only if all labels passed well, we try to
00799                               // look at the "EVERYTHING_ELSE" case
00800          {
00801             if(CheckEqual( curstate1->GetNextState(LABEL_UNDEFINED),
00802                            curstate2->GetNextState(LABEL_UNDEFINED),array)==0)
00803                curlabel=(FSMLabel *)1; // We set curlabel to a value!=NULL
00804          }
00805 
00806          if(curlabel!=NULL)   // Did one of the labels lead to non-equal states?
00807                               // Then the current state pair is also marked "non-equal"
00808          {
00809             // We mark the pair (and all dependent pairs) as not-equal 
00810             pairptr->isnotequal=1;
00811 
00812             if(pairptr->dependlist!=NULL)
00813                MarkDependentNotEqual(pairptr->dependlist);
00814          }
00815          else  // We don't know whether the states are equivalent
00816                // ==> We build dependency chains to each of the successor states
00817                // If the successor states become non-equal, then we change this statepair
00818          {
00819             curlabel=tmplabellist;
00820             while(curlabel!=NULL)
00821             {
00822                AddDependency( curstate1->GetNextState(curlabel->labelid),
00823                               curstate2->GetNextState(curlabel->labelid),
00824                               pairptr,
00825                               array);
00826 
00827                curlabel=curlabel->next;
00828             }
00829             AddDependency( curstate1->GetNextState(LABEL_UNDEFINED),
00830                            curstate2->GetNextState(LABEL_UNDEFINED),
00831                            pairptr,
00832                            array);
00833          }
00834          pairptr++;
00835          curstate2=curstate2->next;
00836       }
00837       curstate1=curstate1->next;
00838    }
00839 
00840    // In the final phase, we create a new automaton and copy the states
00841 
00842    FSM *newfsm=new(fsmmem) FSM();
00843    FSMEdge  *edge,*negedge;
00844 
00845    // First, we create all states
00846 
00847    curstate1=statelist;
00848 
00849    for(i=0;i<statenum;i++)
00850    {
00851       pairptr=array[i];
00852       curstate2=statelist;
00853 
00854       for(j=0;j<i;j++)
00855       {
00856          if(pairptr->isnotequal==0)
00857             // We found a previous state that is equal? ==> We store a pointer
00858             // to the corresponding state and we set array[i]=NULL
00859          {
00860             curstate1->data=curstate2->data;
00861             array[i]=NULL;
00862             break;
00863          }
00864          curstate2=curstate2->next;
00865          pairptr++;
00866       }
00867 
00868       if(i==j) // We didn't find any previous state that is equal
00869                // ==> We create a new state
00870          curstate1->data=newfsm->CreateState(curstate1->IsFinal());
00871 
00872       curstate1=curstate1->next;
00873    }
00874 
00875    // We also need to take care of the start-state
00876    newfsm->SetStartState((FSMState *)startstate->data);
00877 
00878    // Now, we need to take care of the edges
00879    curstate1=statelist;
00880    for(i=0;i<statenum;i++)
00881    {
00882       if(array[i]!=NULL)
00883       {
00884          // Let's take care of the negedge first
00885 
00886          edge=curstate1->FindNegEdge();
00887          if(edge!=NULL)
00888          {
00889             tmplabellist=NULL;
00890             DupLabelList(edge->GetLabelList(),&tmplabellist);
00891 
00892             negedge=newfsm->CreateNegEdge((FSMState *)curstate1->data,
00893                                           (FSMState *)edge->GetNextState()->data,
00894                                           tmplabellist);
00895          }
00896          else
00897             negedge=NULL;
00898 
00899          // Let's consider all outgoing edges
00900          edge=curstate1->GetOutEdges();
00901          while(edge!=NULL)
00902          {
00903             if(edge->GetType()==EDGETYPE_LABEL)
00904             {
00905                if((negedge!=NULL)&&
00906                   (negedge->GetNextState()==(FSMState *)edge->nextstate->data))
00907                   // Is the target state the same as the one of the existing negedge ?
00908                   // ==> We simply remove the element from the negedge labellist
00909                   RemoveFromLabelList(&(negedge->labellist),edge->labelid);
00910                else
00911                   newfsm->CreateLabelEdge((FSMState *)curstate1->data,
00912                                           (FSMState *)edge->GetNextState()->data,
00913                                           edge->labelid);
00914             }
00915             edge=edge->next;
00916          }
00917       }
00918       curstate1=curstate1->next;
00919    }
00920    return newfsm;
00921 }

void FSM::SetStartState FSMState   mystartstate [inline]
 

Definition at line 290 of file FSM.hpp.

Referenced by VRegExpr::CreateNonDetFSM().

00290 {  startstate=mystartstate;   }

void FSM::operator delete void *    ptr [inline]
 

Definition at line 264 of file FSM.hpp.

00264 {}

void* FSM::operator new size_t    size,
MemStreamer   mem
[inline]
 

Definition at line 259 of file FSM.hpp.

00260    {
00261       return mem->GetByteBlock(size);
00262    }


The documentation for this class was generated from the following files:
Generated on Sat Oct 13 16:08:53 2001 for XMILL by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001