Get ragel working again while the direct-to-backend code is being written.
[external/ragel.git] / ragel / fsmap.cpp
index c9e673a..12d9e56 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2002-2004 Adrian Thurston <thurston@cs.queensu.ca>
+ *  Copyright 2002-2004 Adrian Thurston <thurston@complang.org>
  */
 
 /*  This file is part of Ragel.
@@ -122,6 +122,12 @@ void FsmAp::startFsmPrior( int ordering, PriorDesc *prior )
                if ( trans->toState != 0 )
                        trans->priorTable.setPrior( ordering, prior );
        }
+
+       /* If the new start state is final then set the out priority. This follows
+        * the same convention as setting start action in the out action table of
+        * a final start state. */
+       if ( startState->stateBits & STB_ISFINAL )
+               startState->outPriorTable.setPrior( ordering, prior );
 }
 
 /* Set the priority of all transitions in a graph. Walks all transition lists
@@ -180,6 +186,12 @@ void FsmAp::startFsmAction( int ordering, Action *action )
                if ( trans->toState != 0 )
                        trans->actionTable.setAction( ordering, action );
        }
+
+       /* If start state is final then add the action to the out action table.
+        * This means that when the null string is accepted the start action will
+        * not be bypassed. */
+       if ( startState->stateBits & STB_ISFINAL )
+               startState->outActionTable.setAction( ordering, action );
 }
 
 /* Set functions to execute on all transitions. Walks the out lists of all
@@ -290,6 +302,18 @@ void FsmAp::fillGaps( StateAp *state )
        }
 }
 
+void FsmAp::setErrorActions( StateAp *state, const ActionTable &other )
+{
+       /* Fill any gaps in the out list with an error transition. */
+       fillGaps( state );
+
+       /* Set error transitions in the transitions that go to error. */
+       for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) {
+               if ( trans->toState == 0 )
+                       trans->actionTable.setActions( other );
+       }
+}
+
 void FsmAp::setErrorAction( StateAp *state, int ordering, Action *action )
 {
        /* Fill any gaps in the out list with an error transition. */
@@ -320,6 +344,13 @@ void FsmAp::setErrorTarget( StateAp *state, StateAp *target, int *orderings,
        }
 }
 
+void FsmAp::transferOutActions( StateAp *state )
+{
+       for ( ActionTable::Iter act = state->outActionTable; act.lte(); act++ )
+               state->eofActionTable.setAction( act->key, act->value ); 
+       state->outActionTable.empty();
+}
+
 void FsmAp::transferErrorActions( StateAp *state, int transferPoint )
 {
        for ( int i = 0; i < state->errActionTable.length(); ) {
@@ -327,6 +358,8 @@ void FsmAp::transferErrorActions( StateAp *state, int transferPoint )
                if ( act->transferPoint == transferPoint ) {
                        /* Transfer the error action and remove it. */
                        setErrorAction( state, act->ordering, act->action );
+                       if ( ! state->isFinState() )
+                               state->eofActionTable.setAction( act->ordering, act->action );
                        state->errActionTable.vremove( i );
                }
                else {
@@ -637,14 +670,14 @@ void FsmAp::verifyStates()
 {
        for ( StateList::Iter state = stateList; state.lte(); state++ ) {
                /* Non final states should not have leaving data. */
-               if ( ! (state->stateBits & SB_ISFINAL) ) {
+               if ( ! (state->stateBits & STB_ISFINAL) ) {
                        assert( state->outActionTable.length() == 0 );
                        assert( state->outCondSet.length() == 0 );
                        assert( state->outPriorTable.length() == 0 );
                }
 
                /* Data used in algorithms should be cleared. */
-               assert( (state->stateBits & SB_BOTH) == 0 );
+               assert( (state->stateBits & STB_BOTH) == 0 );
                assert( state->foreignInTrans > 0 );
        }
 }