Need to unset the final state status of the start state in kleene star.
[external/ragel.git] / ragel / fsmgraph.cpp
index 41c4b44..b37c4dc 100644 (file)
@@ -293,7 +293,7 @@ void FsmAp::optionalRepeatOp( int times )
                /* Make a duplicate for concating and set the fin bits to graph 2 so we
                 * can pick out it's final states after the optional style concat. */
                FsmAp *dup = new FsmAp( *copyFrom );
-               dup->setFinBits( SB_GRAPH2 );
+               dup->setFinBits( STB_GRAPH2 );
                doConcat( dup, &lastFinSet, true );
 
                /* Clear the last final state set and make the new one by taking only
@@ -303,9 +303,9 @@ void FsmAp::optionalRepeatOp( int times )
                        /* If the state came from graph 2, add it to the last set and clear
                         * the bits. */
                        StateAp *fs = finStateSet[i];
-                       if ( fs->stateBits & SB_GRAPH2 ) {
+                       if ( fs->stateBits & STB_GRAPH2 ) {
                                lastFinSet.insert( fs );
-                               fs->stateBits &= ~SB_GRAPH2;
+                               fs->stateBits &= ~STB_GRAPH2;
                        }
                }
        }
@@ -455,8 +455,8 @@ void FsmAp::intersectOp( FsmAp *other )
        other->setMisfitAccounting( true );
 
        /* Set the fin bits on this and other to want each other. */
-       setFinBits( SB_GRAPH1 );
-       other->setFinBits( SB_GRAPH2 );
+       setFinBits( STB_GRAPH1 );
+       other->setFinBits( STB_GRAPH2 );
 
        /* Call worker Or routine. */
        doOr( other );
@@ -481,7 +481,7 @@ void FsmAp::subtractOp( FsmAp *other )
        other->setMisfitAccounting( true );
 
        /* Set the fin bits of other to be killers. */
-       other->setFinBits( SB_GRAPH1 );
+       other->setFinBits( STB_GRAPH1 );
 
        /* Call worker Or routine. */
        doOr( other );
@@ -725,7 +725,7 @@ void FsmAp::joinOp( int startId, int finalId, FsmAp **others, int numOthers )
        /* Invoke the relinquish final callback on any states that did not get
         * final state status back. */
        for ( StateSet::Iter st = finStateSetCopy; st.lte(); st++ ) {
-               if ( !((*st)->stateBits & SB_ISFINAL) )
+               if ( !((*st)->stateBits & STB_ISFINAL) )
                        clearOutData( *st );
        }
 
@@ -818,14 +818,14 @@ void FsmAp::unsetKilledFinals()
        for ( int s = 0; s < fin.length(); s++ ) {
                /* Check for killing bit. */
                StateAp *state = fin.data[s];
-               if ( state->stateBits & SB_GRAPH1 ) {
+               if ( state->stateBits & STB_GRAPH1 ) {
                        /* One final state is a killer, set to non-final. */
                        unsetFinState( state );
                }
 
                /* Clear all killing bits. Non final states should never have had those
                 * state bits set in the first place. */
-               state->stateBits &= ~SB_GRAPH1;
+               state->stateBits &= ~STB_GRAPH1;
        }
 }
 
@@ -838,8 +838,8 @@ void FsmAp::unsetIncompleteFinals()
        for ( int s = 0; s < fin.length(); s++ ) {
                /* Check for one set but not the other. */
                StateAp *state = fin.data[s];
-               if ( state->stateBits & SB_BOTH && 
-                               (state->stateBits & SB_BOTH) != SB_BOTH )
+               if ( state->stateBits & STB_BOTH && 
+                               (state->stateBits & STB_BOTH) != STB_BOTH )
                {
                        /* One state wants the other but it is not there. */
                        unsetFinState( state );
@@ -847,7 +847,7 @@ void FsmAp::unsetIncompleteFinals()
 
                /* Clear wanting bits. Non final states should never have had those
                 * state bits set in the first place. */
-               state->stateBits &= ~SB_BOTH;
+               state->stateBits &= ~STB_BOTH;
        }
 }
 
@@ -1170,7 +1170,7 @@ void FsmAp::mergeStateConds( StateAp *destState, StateAp *srcState )
 }
 
 /* A state merge which represents the drawing in of leaving transitions.  If
- * there is any out data then we duplicate the souce state, transfer the out
+ * there is any out data then we duplicate the source state, transfer the out
  * data, then merge in the state. The new state will be reaped because it will
  * not be given any in transitions. */
 void FsmAp::mergeStatesLeaving( MergeData &md, StateAp *destState, StateAp *srcState )
@@ -1182,8 +1182,8 @@ void FsmAp::mergeStatesLeaving( MergeData &md, StateAp *destState, StateAp *srcS
                mergeStates( md, ssMutable, srcState );
                transferOutData( ssMutable, destState );
 
-               for ( ActionSet::Iter cond = destState->outCondSet; cond.lte(); cond++ )
-                       embedCondition( md, ssMutable, *cond );
+               for ( OutCondSet::Iter cond = destState->outCondSet; cond.lte(); cond++ )
+                       embedCondition( md, ssMutable, cond->action, cond->sense );
 
                mergeStates( md, destState, ssMutable );
        }
@@ -1220,7 +1220,7 @@ void FsmAp::mergeStates( MergeData &md, StateAp *destState, StateAp *srcState )
        expList2.empty();
 
        /* Get its bits and final state status. */
-       destState->stateBits |= ( srcState->stateBits & ~SB_ISFINAL );
+       destState->stateBits |= ( srcState->stateBits & ~STB_ISFINAL );
        if ( srcState->isFinState() )
                setFinState( destState );
 
@@ -1237,7 +1237,7 @@ void FsmAp::mergeStates( MergeData &md, StateAp *destState, StateAp *srcState )
                destState->fromStateActionTable.setActions( 
                                ActionTable( srcState->fromStateActionTable ) );
                destState->outActionTable.setActions( ActionTable( srcState->outActionTable ) );
-               destState->outCondSet.insert( ActionSet( srcState->outCondSet ) );
+               destState->outCondSet.insert( OutCondSet( srcState->outCondSet ) );
                destState->errActionTable.setActions( ErrActionTable( srcState->errActionTable ) );
                destState->eofActionTable.setActions( ActionTable( srcState->eofActionTable ) );
        }
@@ -1283,7 +1283,7 @@ void FsmAp::fillInStates( MergeData &md )
 }
 
 void FsmAp::findEmbedExpansions( ExpansionList &expansionList, 
-               StateAp *destState, Action *condAction )
+               StateAp *destState, Action *condAction, bool sense )
 {
        StateCondList destList;
        PairIter<TransAp, StateCond> transCond( destState->outList.head,
@@ -1309,7 +1309,7 @@ void FsmAp::findEmbedExpansions( ExpansionList &expansionList,
                                        expansion->fromCondSpace = 0;
                                        expansion->fromVals = 0;
                                        expansion->toCondSpace = newStateCond->condSpace;
-                                       expansion->toValsList.append( 1 );
+                                       expansion->toValsList.append( sense?1:0 );
                                        #ifdef LOG_CONDS
                                        logNewExpansion( expansion );
                                        #endif
@@ -1347,7 +1347,7 @@ void FsmAp::findEmbedExpansions( ExpansionList &expansionList,
                                        long targVals = basicVals;
                                        Action **cim = mergedCS.find( condAction );
                                        long bitPos = (cim - mergedCS.data);
-                                       targVals |= 1 << bitPos;
+                                       targVals |= (sense?1:0) << bitPos;
                                        
                                        LongVect expandToVals( targVals );
                                        findCondExpInTrans( expansionList, destState, 
@@ -1369,7 +1369,7 @@ void FsmAp::findEmbedExpansions( ExpansionList &expansionList,
        destState->stateCondList.transfer( destList );
 }
 
-void FsmAp::embedCondition( StateAp *state, Action *condAction )
+void FsmAp::embedCondition( StateAp *state, Action *condAction, bool sense )
 {
        MergeData md;
        ExpansionList expList;
@@ -1378,7 +1378,7 @@ void FsmAp::embedCondition( StateAp *state, Action *condAction )
        setMisfitAccounting( true );
 
        /* Worker. */
-       embedCondition( md, state, condAction );
+       embedCondition( md, state, condAction, sense );
 
        /* Fill in any states that were newed up as combinations of others. */
        fillInStates( md );
@@ -1388,12 +1388,39 @@ void FsmAp::embedCondition( StateAp *state, Action *condAction )
        setMisfitAccounting( false );
 }
 
-void FsmAp::embedCondition( MergeData &md, StateAp *state, Action *condAction )
+void FsmAp::embedCondition( MergeData &md, StateAp *state, Action *condAction, bool sense )
 {
        ExpansionList expList;
 
-       findEmbedExpansions( expList, state, condAction );
+       findEmbedExpansions( expList, state, condAction, sense );
        doExpand( md, state, expList );
        doRemove( md, state, expList );
        expList.empty();
 }
+
+/* Check if a machine defines a single character. This is useful in validating
+ * ranges and machines to export. */
+bool FsmAp::checkSingleCharMachine()
+{
+       /* Must have two states. */
+       if ( stateList.length() != 2 )
+               return false;
+       /* The start state cannot be final. */
+       if ( startState->isFinState() )
+               return false;
+       /* There should be only one final state. */
+       if ( finStateSet.length() != 1 )
+               return false;
+       /* The final state cannot have any transitions out. */
+       if ( finStateSet[0]->outList.length() != 0 )
+               return false;
+       /* The start state should have only one transition out. */
+       if ( startState->outList.length() != 1 )
+               return false;
+       /* The singe transition out of the start state should not be a range. */
+       TransAp *startTrans = startState->outList.head;
+       if ( startTrans->lowKey != startTrans->highKey )
+               return false;
+       return true;
+}
+