Пример #1
0
    void StateStorage::dupState( State orig, State dup )
    {
      if( isInitialState(orig) )
        addInitialState(dup);

      if( isFinalState(orig) )
        addFinalState(dup);
    }
Пример #2
0
 void StateStorage::addAllFinalStates( const StateStorage & stateSet )
 {
   for( const_iterator it = stateSet.beginFinalStates();
        it != stateSet.endFinalStates(); it++ )
   {
     addFinalState(*it);
   }
 }
Пример #3
0
//Returns Start State for the NFA of the input REGEX.
//This builds an individual NFA for the input REGEX and stores the start and final state.
//'$' represents EPSILON transition.
void buildIndividualNFA(char pattern[], char POSTFIX[])
{
	int i = 0;
	char ch;
	Stack starts, ends;
	init(&starts);
	init(&ends);
	
	while(ch = POSTFIX[i++])
	{
		if(ch == '|')//Union
		{
			STATE start1 = pop(&starts), start2 = pop(&starts);
			STATE end1 = pop(&ends), end2 = pop(&ends);
			STATE newStart = nextAvailableState++, newEnd = nextAvailableState++;
			addTransition(newStart, start1, '$');
			addTransition(newStart, start2, '$');
			addTransition(end1, newEnd, '$');
			addTransition(end2, newEnd, '$');
			
			push(&starts, newStart);push(&ends, newEnd);			
		}
		else if(ch == '#')//Kleene Closure
		{
			STATE start = pop(&starts), end = pop(&ends);
			STATE newStart = nextAvailableState++, newEnd = nextAvailableState++;
			addTransition(end, start, '$');
			addTransition(newStart, newEnd, '$');
			addTransition(newStart, start, '$');
			addTransition(end, newEnd, '$');
			
			push(&starts, newStart);push(&ends, newEnd);			
		}
		else if(ch == '&')
		{
			STATE start1 = pop(&starts), start2 = pop(&starts);
			STATE end1 = pop(&ends), end2 = pop(&ends);
			addTransition(end2, start1, '$');
			
			push(&starts, start2);push(&ends, end1);
		}
		else if(ch == '@')
		{
			char a = POSTFIX[i++], b = POSTFIX[i++];
			int j;
			STATE start = nextAvailableState++, end = nextAvailableState++;
			for(j=a;j<=b;++j)			
			addTransition(start, end, j);
			
			push(&starts, start);push(&ends, end);			
		}
		else
		{
			STATE start = nextAvailableState++, end = nextAvailableState++;
			addTransition(start, end, ch);
			
			push(&starts, start);push(&ends, end);
		}		
	}
	addStartState(pop(&starts));
	addFinalState(pop(&ends), pattern);
}
Пример #4
0
  void Nwa::_private_star_( Nwa const & first )
  {
    State newStart = getKey("kleeneStarStart");
    assert(!first.isState(newStart));
      
    //TODO: ponder the following ... 
    //Q: how do we prevent the stuck state from being the same as any of the states that we
    //      generate as a part of this process?
    //A: check against all possible overlaps?  this might be expensive, but it would work

    //Q: How should clientInfos be generated for the star NWA?
    //A: The clientInfos from the component machine are copied to both the direct copies of
    //    states and the primed copies of states and added to the star NWA.

    //Clear all states(except the stuck state) and transitions from this machine.
    clear();

    //Somehow mark unmatched nesting edges as if they are pending (tag its state so that 
    //at a return the states labeling the incident nesting edges are ignored).
    State prime = wali::getKey("prime");

    //The state-space of A* is Q + Q'.
    states.addAll(first.states); //Note: This includes copying clientInfo information over.    
    for( StateIterator sit = first.beginStates(); sit != first.endStates(); sit++ )
    {
      State sp = wali::getKey(*sit,prime);
      states.addState(sp);

      //Note: The clientInfos for the states in Q' are copies of the clientInfos for the 
      //      corresponding states from Q.
      //Set the clientInfo of this state.
      ClientInfoRefPtr ci = first.getClientInfo(*sit);
      if (ci.is_valid()) {
        states.setClientInfo(sp, ci->cloneRp());
      }
    }

     

    //The initial and final state of A* is newStart
    clearInitialStates();
    clearFinalStates();
    addInitialState(newStart);
    addFinalState(newStart);

    // Add newStart->q0 transitions
    for( StateIterator sit = first.beginInitialStates(); sit != first.endInitialStates(); sit++ ) {
      State target = getKey(*sit, prime);
      // INTERNAL (inference rule in TR)
      addInternalTrans(newStart, EPSILON, target);
    }
    for( StateIterator sit = first.beginFinalStates(); sit != first.endFinalStates(); sit++ ) {
      State f = *sit;
      State fp = getKey(*sit, prime);

      // RESTART (inference rule in TR)
      addInternalTrans(f, EPSILON, newStart);
      addInternalTrans(fp, EPSILON, newStart);
    }
      

    //Transitions of A*:

    //Internal: for each (q,a,p) in delta_i, A* gets (q,a,p) and (q',a,p')
    for( InternalIterator iit = first.beginInternalTrans();
         iit != first.endInternalTrans(); iit++ )
    {
      State q = Trans::getSource(*iit);
      Symbol a = Trans::getInternalSym(*iit);
      State p = Trans::getTarget(*iit);

      //(q,a,p)
      // INTERNAL (inference rule in TR)
      addInternalTrans(q,a,p);

      //(q',a,p')
      State qp = wali::getKey(q,prime);
      State pp = wali::getKey(p,prime);
      // INTERNAL (inference rule in TR)
      addInternalTrans(qp,a,pp);
    }

    //Call: for each(q,a,p) in delta_c, A* gets (q,a,p) and (q',a,p)
    for( CallIterator cit = first.beginCallTrans();
         cit != first.endCallTrans(); cit++ )
    {
      State q = Trans::getCallSite(*cit);
      Symbol a = Trans::getCallSym(*cit);
      State p = Trans::getEntry(*cit);

      //(q,a,p)
      // CALL (inference rule in TR)
      addCallTrans(q,a,p);

      //(q',a,p)
      State qp = wali::getKey(q,prime);
      // CALL (inference rule in TR)
      addCallTrans(qp,a,p);
    }

    //Return: for each (q,r,a,p) in delta_r, A* gets (q,r,a,p) and (q,r',a,p'), 
    //          For each (q,r,a,p) in delra_r with r in Q0, 
    //            A* gets (q',s,a,p') for each s in Q union Q' and (q',newStart,a,p')
    for( ReturnIterator rit = first.beginReturnTrans();
         rit != first.endReturnTrans(); rit++ )
    {
      State q = Trans::getExit(*rit);
      State r = Trans::getCallSite(*rit);
      Symbol a = Trans::getReturnSym(*rit);
      State p = Trans::getReturnSite(*rit);

      State qp = wali::getKey(q,prime);

      //(q,r,a,p)
      // RETURN (inference rule in TR)
      addReturnTrans(q,r,a,p);

      //(q,r',a,p')
      State rp = wali::getKey(r,prime);
      State pp = wali::getKey(p,prime);
      // RETURN (inference rule in TR)
      addReturnTrans(q,rp,a,pp);

      //if r in Q0
      if( first.isInitialState(r) )
      {
        // (q',newStart,a,p')
        // GLOBALLY-PENDING (inference rule in TR)
        addReturnTrans(qp,newStart,a,pp);
          
        //for each s in Q
        for( StateIterator sit = first.beginStates();
             sit != first.endStates(); sit++ )
        {
          State s = *sit;

          //Handle s
          //(q',s,a,p')
          // LOCALLY_PENDING (inference rule in TR)
          addReturnTrans(qp,s,a,pp);

          //Handle corresponding s'
          //(q',s',a,p')
          // LOCALLY_PENDING (inference rule in TR)
          State sp = wali::getKey(s,prime);
          addReturnTrans(qp,sp,a,pp);
        }
      }
    }
  }