/*
- * Copyright 2002-2004 Adrian Thurston <thurston@cs.queensu.ca>
+ * Copyright 2002-2004 Adrian Thurston <thurston@complang.org>
*/
/* This file is part of Ragel.
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
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
}
}
+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. */
}
}
+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(); ) {
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 {
{
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 );
}
}
{
CondSpace *condSpace = condData->condSpaceMap.find( condSet );
if ( condSpace == 0 ) {
- Key baseKey = condData->nextCondKey;
- condData->nextCondKey += (1 << condSet.length() ) * keyOps->alphSize();
+ /* Do we have enough keyspace left? */
+ Size availableSpace = condData->lastCondKey.availableSpace();
+ Size neededSpace = (1 << condSet.length() ) * keyOps->alphSize();
+ if ( neededSpace > availableSpace )
+ throw FsmConstructFail( FsmConstructFail::CondNoKeySpace );
+
+ Key baseKey = condData->lastCondKey;
+ baseKey.increment();
+ condData->lastCondKey += (1 << condSet.length() ) * keyOps->alphSize();
condSpace = new CondSpace( condSet );
condSpace->baseKey = baseKey;