2 * Copyright 2002-2004 Adrian Thurston <thurston@cs.queensu.ca>
5 /* This file is part of Ragel.
7 * Ragel is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * Ragel is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Ragel; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 CondData *condData = 0;
30 /* Insert an action into an action table. */
31 void ActionTable::setAction( int ordering, Action *action )
33 /* Multi-insert in case specific instances of an action appear in a
34 * transition more than once. */
35 insertMulti( ordering, action );
38 /* Set all the action from another action table in this table. */
39 void ActionTable::setActions( const ActionTable &other )
41 for ( ActionTable::Iter action = other; action.lte(); action++ )
42 insertMulti( action->key, action->value );
45 void ActionTable::setActions( int *orderings, Action **actions, int nActs )
47 for ( int a = 0; a < nActs; a++ )
48 insertMulti( orderings[a], actions[a] );
51 bool ActionTable::hasAction( Action *action )
53 for ( int a = 0; a < length(); a++ ) {
54 if ( data[a].value == action )
60 /* Insert an action into an action table. */
61 void LmActionTable::setAction( int ordering, LongestMatchPart *action )
63 /* Multi-insert in case specific instances of an action appear in a
64 * transition more than once. */
65 insertMulti( ordering, action );
68 /* Set all the action from another action table in this table. */
69 void LmActionTable::setActions( const LmActionTable &other )
71 for ( LmActionTable::Iter action = other; action.lte(); action++ )
72 insertMulti( action->key, action->value );
75 void ErrActionTable::setAction( int ordering, Action *action, int transferPoint )
77 insertMulti( ErrActionTableEl( action, ordering, transferPoint ) );
80 void ErrActionTable::setActions( const ErrActionTable &other )
82 for ( ErrActionTable::Iter act = other; act.lte(); act++ )
83 insertMulti( ErrActionTableEl( act->action, act->ordering, act->transferPoint ) );
86 /* Insert a priority into this priority table. Looks out for priorities on
88 void PriorTable::setPrior( int ordering, PriorDesc *desc )
91 PriorEl *insed = insert( PriorEl(ordering, desc), &lastHit );
93 /* This already has a priority on the same key as desc. Overwrite the
94 * priority if the ordering is larger (later in time). */
95 if ( ordering >= lastHit->ordering )
96 *lastHit = PriorEl( ordering, desc );
100 /* Set all the priorities from a priorTable in this table. */
101 void PriorTable::setPriors( const PriorTable &other )
103 /* Loop src priorities once to overwrite duplicates. */
104 PriorTable::Iter priorIt = other;
105 for ( ; priorIt.lte(); priorIt++ )
106 setPrior( priorIt->ordering, priorIt->desc );
109 /* Set the priority of starting transitions. Isolates the start state so it has
110 * no other entry points, then sets the priorities of all the transitions out
111 * of the start state. If the start state is final, then the outPrior of the
112 * start state is also set. The idea is that a machine that accepts the null
113 * string can still specify the starting trans prior for when it accepts the
115 void FsmAp::startFsmPrior( int ordering, PriorDesc *prior )
117 /* Make sure the start state has no other entry points. */
120 /* Walk all transitions out of the start state. */
121 for ( TransList::Iter trans = startState->outList; trans.lte(); trans++ ) {
122 if ( trans->toState != 0 )
123 trans->priorTable.setPrior( ordering, prior );
127 /* Set the priority of all transitions in a graph. Walks all transition lists
128 * and all def transitions. */
129 void FsmAp::allTransPrior( int ordering, PriorDesc *prior )
131 /* Walk the list of all states. */
132 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
133 /* Walk the out list of the state. */
134 for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) {
135 if ( trans->toState != 0 )
136 trans->priorTable.setPrior( ordering, prior );
141 /* Set the priority of all transitions that go into a final state. Note that if
142 * any entry states are final, we will not be setting the priority of any
143 * transitions that may go into those states in the future. The graph does not
144 * support pending in transitions in the same way pending out transitions are
146 void FsmAp::finishFsmPrior( int ordering, PriorDesc *prior )
148 /* Walk all final states. */
149 for ( StateSet::Iter state = finStateSet; state.lte(); state++ ) {
150 /* Walk all in transitions of the final state. */
151 for ( TransInList::Iter trans = (*state)->inList; trans.lte(); trans++ )
152 trans->priorTable.setPrior( ordering, prior );
156 /* Set the priority of any future out transitions that may be made going out of
157 * this state machine. */
158 void FsmAp::leaveFsmPrior( int ordering, PriorDesc *prior )
160 /* Set priority in all final states. */
161 for ( StateSet::Iter state = finStateSet; state.lte(); state++ )
162 (*state)->outPriorTable.setPrior( ordering, prior );
166 /* Set actions to execute on starting transitions. Isolates the start state
167 * so it has no other entry points, then adds to the transition functions
168 * of all the transitions out of the start state. If the start state is final,
169 * then the func is also added to the start state's out func list. The idea is
170 * that a machine that accepts the null string can execute a start func when it
171 * matches the null word, which can only be done when leaving the start/final
173 void FsmAp::startFsmAction( int ordering, Action *action )
175 /* Make sure the start state has no other entry points. */
178 /* Walk the start state's transitions, setting functions. */
179 for ( TransList::Iter trans = startState->outList; trans.lte(); trans++ ) {
180 if ( trans->toState != 0 )
181 trans->actionTable.setAction( ordering, action );
185 /* Set functions to execute on all transitions. Walks the out lists of all
187 void FsmAp::allTransAction( int ordering, Action *action )
189 /* Walk all states. */
190 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
191 /* Walk the out list of the state. */
192 for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) {
193 if ( trans->toState != 0 )
194 trans->actionTable.setAction( ordering, action );
199 /* Specify functions to execute upon entering final states. If the start state
200 * is final we can't really specify a function to execute upon entering that
201 * final state the first time. So function really means whenever entering a
202 * final state from within the same fsm. */
203 void FsmAp::finishFsmAction( int ordering, Action *action )
205 /* Walk all final states. */
206 for ( StateSet::Iter state = finStateSet; state.lte(); state++ ) {
207 /* Walk the final state's in list. */
208 for ( TransInList::Iter trans = (*state)->inList; trans.lte(); trans++ )
209 trans->actionTable.setAction( ordering, action );
213 /* Add functions to any future out transitions that may be made going out of
214 * this state machine. */
215 void FsmAp::leaveFsmAction( int ordering, Action *action )
217 /* Insert the action in the outActionTable of all final states. */
218 for ( StateSet::Iter state = finStateSet; state.lte(); state++ )
219 (*state)->outActionTable.setAction( ordering, action );
222 /* Add functions to the longest match action table for constructing scanners. */
223 void FsmAp::longMatchAction( int ordering, LongestMatchPart *lmPart )
225 /* Walk all final states. */
226 for ( StateSet::Iter state = finStateSet; state.lte(); state++ ) {
227 /* Walk the final state's in list. */
228 for ( TransInList::Iter trans = (*state)->inList; trans.lte(); trans++ )
229 trans->lmActionTable.setAction( ordering, lmPart );
233 void FsmAp::fillGaps( StateAp *state )
235 if ( state->outList.length() == 0 ) {
236 /* Add the range on the lower and upper bound. */
237 attachNewTrans( state, 0, keyOps->minKey, keyOps->maxKey );
241 srcList.transfer( state->outList );
243 /* Check for a gap at the beginning. */
244 TransList::Iter trans = srcList, next;
245 if ( keyOps->minKey < trans->lowKey ) {
246 /* Make the high key and append. */
247 Key highKey = trans->lowKey;
250 attachNewTrans( state, 0, keyOps->minKey, highKey );
253 /* Write the transition. */
255 state->outList.append( trans );
257 /* Keep the last high end. */
258 Key lastHigh = trans->highKey;
260 /* Loop each source range. */
261 for ( trans = next; trans.lte(); trans = next ) {
262 /* Make the next key following the last range. */
263 Key nextKey = lastHigh;
266 /* Check for a gap from last up to here. */
267 if ( nextKey < trans->lowKey ) {
268 /* Make the high end of the range that fills the gap. */
269 Key highKey = trans->lowKey;
272 attachNewTrans( state, 0, nextKey, highKey );
275 /* Reduce the transition. If it reduced to anything then add it. */
277 state->outList.append( trans );
279 /* Keep the last high end. */
280 lastHigh = trans->highKey;
283 /* Now check for a gap on the end to fill. */
284 if ( lastHigh < keyOps->maxKey ) {
285 /* Get a copy of the default. */
286 lastHigh.increment();
288 attachNewTrans( state, 0, lastHigh, keyOps->maxKey );
293 void FsmAp::setErrorAction( StateAp *state, int ordering, Action *action )
295 /* Fill any gaps in the out list with an error transition. */
298 /* Set error transitions in the transitions that go to error. */
299 for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) {
300 if ( trans->toState == 0 )
301 trans->actionTable.setAction( ordering, action );
306 /* Give a target state for error transitions. */
307 void FsmAp::setErrorTarget( StateAp *state, StateAp *target, int *orderings,
308 Action **actions, int nActs )
310 /* Fill any gaps in the out list with an error transition. */
313 /* Set error target in the transitions that go to error. */
314 for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) {
315 if ( trans->toState == 0 ) {
316 /* The trans goes to error, redirect it. */
317 redirectErrorTrans( trans->fromState, target, trans );
318 trans->actionTable.setActions( orderings, actions, nActs );
323 void FsmAp::transferErrorActions( StateAp *state, int transferPoint )
325 for ( int i = 0; i < state->errActionTable.length(); ) {
326 ErrActionTableEl *act = state->errActionTable.data + i;
327 if ( act->transferPoint == transferPoint ) {
328 /* Transfer the error action and remove it. */
329 setErrorAction( state, act->ordering, act->action );
330 state->errActionTable.vremove( i );
333 /* Not transfering and deleting, skip over the item. */
339 /* Set error actions in the start state. */
340 void FsmAp::startErrorAction( int ordering, Action *action, int transferPoint )
342 /* Make sure the start state has no other entry points. */
345 /* Add the actions. */
346 startState->errActionTable.setAction( ordering, action, transferPoint );
349 /* Set error actions in all states where there is a transition out. */
350 void FsmAp::allErrorAction( int ordering, Action *action, int transferPoint )
352 /* Insert actions in the error action table of all states. */
353 for ( StateList::Iter state = stateList; state.lte(); state++ )
354 state->errActionTable.setAction( ordering, action, transferPoint );
357 /* Set error actions in final states. */
358 void FsmAp::finalErrorAction( int ordering, Action *action, int transferPoint )
360 /* Add the action to the error table of final states. */
361 for ( StateSet::Iter state = finStateSet; state.lte(); state++ )
362 (*state)->errActionTable.setAction( ordering, action, transferPoint );
365 void FsmAp::notStartErrorAction( int ordering, Action *action, int transferPoint )
367 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
368 if ( state != startState )
369 state->errActionTable.setAction( ordering, action, transferPoint );
373 void FsmAp::notFinalErrorAction( int ordering, Action *action, int transferPoint )
375 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
376 if ( ! state->isFinState() )
377 state->errActionTable.setAction( ordering, action, transferPoint );
381 /* Set error actions in the states that have transitions into a final state. */
382 void FsmAp::middleErrorAction( int ordering, Action *action, int transferPoint )
384 /* Isolate the start state in case it is reachable from in inside the
385 * machine, in which case we don't want it set. */
386 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
387 if ( state != startState && ! state->isFinState() )
388 state->errActionTable.setAction( ordering, action, transferPoint );
392 /* Set EOF actions in the start state. */
393 void FsmAp::startEOFAction( int ordering, Action *action )
395 /* Make sure the start state has no other entry points. */
398 /* Add the actions. */
399 startState->eofActionTable.setAction( ordering, action );
402 /* Set EOF actions in all states where there is a transition out. */
403 void FsmAp::allEOFAction( int ordering, Action *action )
405 /* Insert actions in the EOF action table of all states. */
406 for ( StateList::Iter state = stateList; state.lte(); state++ )
407 state->eofActionTable.setAction( ordering, action );
410 /* Set EOF actions in final states. */
411 void FsmAp::finalEOFAction( int ordering, Action *action )
413 /* Add the action to the error table of final states. */
414 for ( StateSet::Iter state = finStateSet; state.lte(); state++ )
415 (*state)->eofActionTable.setAction( ordering, action );
418 void FsmAp::notStartEOFAction( int ordering, Action *action )
420 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
421 if ( state != startState )
422 state->eofActionTable.setAction( ordering, action );
426 void FsmAp::notFinalEOFAction( int ordering, Action *action )
428 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
429 if ( ! state->isFinState() )
430 state->eofActionTable.setAction( ordering, action );
434 /* Set EOF actions in the states that have transitions into a final state. */
435 void FsmAp::middleEOFAction( int ordering, Action *action )
437 /* Set the actions in all states that are not the start state and not final. */
438 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
439 if ( state != startState && ! state->isFinState() )
440 state->eofActionTable.setAction( ordering, action );
445 * Set To State Actions.
448 /* Set to state actions in the start state. */
449 void FsmAp::startToStateAction( int ordering, Action *action )
451 /* Make sure the start state has no other entry points. */
453 startState->toStateActionTable.setAction( ordering, action );
456 /* Set to state actions in all states. */
457 void FsmAp::allToStateAction( int ordering, Action *action )
459 /* Insert the action on all states. */
460 for ( StateList::Iter state = stateList; state.lte(); state++ )
461 state->toStateActionTable.setAction( ordering, action );
464 /* Set to state actions in final states. */
465 void FsmAp::finalToStateAction( int ordering, Action *action )
467 /* Add the action to the error table of final states. */
468 for ( StateSet::Iter state = finStateSet; state.lte(); state++ )
469 (*state)->toStateActionTable.setAction( ordering, action );
472 void FsmAp::notStartToStateAction( int ordering, Action *action )
474 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
475 if ( state != startState )
476 state->toStateActionTable.setAction( ordering, action );
480 void FsmAp::notFinalToStateAction( int ordering, Action *action )
482 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
483 if ( ! state->isFinState() )
484 state->toStateActionTable.setAction( ordering, action );
488 /* Set to state actions in states that are not final and not the start state. */
489 void FsmAp::middleToStateAction( int ordering, Action *action )
491 /* Set the action in all states that are not the start state and not final. */
492 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
493 if ( state != startState && ! state->isFinState() )
494 state->toStateActionTable.setAction( ordering, action );
499 * Set From State Actions.
502 void FsmAp::startFromStateAction( int ordering, Action *action )
504 /* Make sure the start state has no other entry points. */
506 startState->fromStateActionTable.setAction( ordering, action );
509 void FsmAp::allFromStateAction( int ordering, Action *action )
511 /* Insert the action on all states. */
512 for ( StateList::Iter state = stateList; state.lte(); state++ )
513 state->fromStateActionTable.setAction( ordering, action );
516 void FsmAp::finalFromStateAction( int ordering, Action *action )
518 /* Add the action to the error table of final states. */
519 for ( StateSet::Iter state = finStateSet; state.lte(); state++ )
520 (*state)->fromStateActionTable.setAction( ordering, action );
523 void FsmAp::notStartFromStateAction( int ordering, Action *action )
525 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
526 if ( state != startState )
527 state->fromStateActionTable.setAction( ordering, action );
531 void FsmAp::notFinalFromStateAction( int ordering, Action *action )
533 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
534 if ( ! state->isFinState() )
535 state->fromStateActionTable.setAction( ordering, action );
539 void FsmAp::middleFromStateAction( int ordering, Action *action )
541 /* Set the action in all states that are not the start state and not final. */
542 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
543 if ( state != startState && ! state->isFinState() )
544 state->fromStateActionTable.setAction( ordering, action );
548 /* Shift the function ordering of the start transitions to start
549 * at fromOrder and increase in units of 1. Useful before staring.
550 * Returns the maximum number of order numbers used. */
551 int FsmAp::shiftStartActionOrder( int fromOrder )
555 /* Walk the start state's transitions, shifting function ordering. */
556 for ( TransList::Iter trans = startState->outList; trans.lte(); trans++ ) {
557 /* Walk the function data for the transition and set the keys to
558 * increasing values starting at fromOrder. */
559 int curFromOrder = fromOrder;
560 ActionTable::Iter action = trans->actionTable;
561 for ( ; action.lte(); action++ )
562 action->key = curFromOrder++;
564 /* Keep track of the max number of orders used. */
565 if ( curFromOrder - fromOrder > maxUsed )
566 maxUsed = curFromOrder - fromOrder;
572 /* Remove all priorities. */
573 void FsmAp::clearAllPriorities()
575 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
576 /* Clear out priority data. */
577 state->outPriorTable.empty();
579 /* Clear transition data from the out transitions. */
580 for ( TransList::Iter trans = state->outList; trans.lte(); trans++ )
581 trans->priorTable.empty();
585 /* Zeros out the function ordering keys. This may be called before minimization
586 * when it is known that no more fsm operations are going to be done. This
587 * will achieve greater reduction as states will not be separated on the basis
588 * of function ordering. */
589 void FsmAp::nullActionKeys( )
591 /* For each state... */
592 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
593 /* Walk the transitions for the state. */
594 for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) {
595 /* Walk the action table for the transition. */
596 for ( ActionTable::Iter action = trans->actionTable;
597 action.lte(); action++ )
600 /* Walk the action table for the transition. */
601 for ( LmActionTable::Iter action = trans->lmActionTable;
602 action.lte(); action++ )
606 /* Null the action keys of the to state action table. */
607 for ( ActionTable::Iter action = state->toStateActionTable;
608 action.lte(); action++ )
611 /* Null the action keys of the from state action table. */
612 for ( ActionTable::Iter action = state->fromStateActionTable;
613 action.lte(); action++ )
616 /* Null the action keys of the out transtions. */
617 for ( ActionTable::Iter action = state->outActionTable;
618 action.lte(); action++ )
621 /* Null the action keys of the error action table. */
622 for ( ErrActionTable::Iter action = state->errActionTable;
623 action.lte(); action++ )
624 action->ordering = 0;
626 /* Null the action keys eof action table. */
627 for ( ActionTable::Iter action = state->eofActionTable;
628 action.lte(); action++ )
633 /* Walk the list of states and verify that non final states do not have out
634 * data, that all stateBits are cleared, and that there are no states with
635 * zero foreign in transitions. */
636 void FsmAp::verifyStates()
638 for ( StateList::Iter state = stateList; state.lte(); state++ ) {
639 /* Non final states should not have leaving data. */
640 if ( ! (state->stateBits & SB_ISFINAL) ) {
641 assert( state->outActionTable.length() == 0 );
642 assert( state->outCondSet.length() == 0 );
643 assert( state->outPriorTable.length() == 0 );
646 /* Data used in algorithms should be cleared. */
647 assert( (state->stateBits & SB_BOTH) == 0 );
648 assert( state->foreignInTrans > 0 );
652 /* Compare two transitions according to their relative priority. Since the
653 * base transition has no priority associated with it, the default is to
655 int FsmAp::comparePrior( const PriorTable &priorTable1, const PriorTable &priorTable2 )
657 /* Looking for differing priorities on same keys. Need to concurrently
658 * scan the priority lists. */
659 PriorTable::Iter pd1 = priorTable1;
660 PriorTable::Iter pd2 = priorTable2;
661 while ( pd1.lte() && pd2.lte() ) {
663 if ( pd1->desc->key < pd2->desc->key )
665 else if ( pd1->desc->key > pd2->desc->key )
667 /* Keys are the same, check priorities. */
668 else if ( pd1->desc->priority < pd2->desc->priority )
670 else if ( pd1->desc->priority > pd2->desc->priority )
673 /* Keys and priorities are equal, advance both. */
679 /* No differing priorities on the same key. */
683 /* Compares two transitions according to priority and functions. Pointers
684 * should not be null. Does not consider to state or from state. Compare two
685 * transitions according to the data contained in the transitions. Data means
686 * any properties added to user transitions that may differentiate them. Since
687 * the base transition has no data, the default is to return equal. */
688 int FsmAp::compareTransData( TransAp *trans1, TransAp *trans2 )
690 /* Compare the prior table. */
691 int cmpRes = CmpPriorTable::compare( trans1->priorTable,
692 trans2->priorTable );
696 /* Compare longest match action tables. */
697 cmpRes = CmpLmActionTable::compare(trans1->lmActionTable,
698 trans2->lmActionTable);
702 /* Compare action tables. */
703 return CmpActionTable::compare(trans1->actionTable,
704 trans2->actionTable);
707 /* Callback invoked when another trans (or possibly this) is added into this
708 * transition during the merging process. Draw in any properties of srcTrans
709 * into this transition. AddInTrans is called when a new transitions is made
710 * that will be a duplicate of another transition or a combination of several
711 * other transitions. AddInTrans will be called for each transition that the
712 * new transition is to represent. */
713 void FsmAp::addInTrans( TransAp *destTrans, TransAp *srcTrans )
715 /* Protect against adding in from ourselves. */
716 if ( srcTrans == destTrans ) {
717 /* Adding in ourselves, need to make a copy of the source transitions.
718 * The priorities are not copied in as that would have no effect. */
719 destTrans->lmActionTable.setActions( LmActionTable(srcTrans->lmActionTable) );
720 destTrans->actionTable.setActions( ActionTable(srcTrans->actionTable) );
723 /* Not a copy of ourself, get the functions and priorities. */
724 destTrans->lmActionTable.setActions( srcTrans->lmActionTable );
725 destTrans->actionTable.setActions( srcTrans->actionTable );
726 destTrans->priorTable.setPriors( srcTrans->priorTable );
730 /* Compare the properties of states that are embedded by users. Compares out
731 * priorities, out transitions, to, from, out, error and eof action tables. */
732 int FsmAp::compareStateData( const StateAp *state1, const StateAp *state2 )
734 /* Compare the out priority table. */
735 int cmpRes = CmpPriorTable::
736 compare( state1->outPriorTable, state2->outPriorTable );
740 /* Test to state action tables. */
741 cmpRes = CmpActionTable::compare( state1->toStateActionTable,
742 state2->toStateActionTable );
746 /* Test from state action tables. */
747 cmpRes = CmpActionTable::compare( state1->fromStateActionTable,
748 state2->fromStateActionTable );
752 /* Test out action tables. */
753 cmpRes = CmpActionTable::compare( state1->outActionTable,
754 state2->outActionTable );
758 /* Test out condition sets. */
759 cmpRes = CmpOutCondSet::compare( state1->outCondSet,
760 state2->outCondSet );
764 /* Test out error action tables. */
765 cmpRes = CmpErrActionTable::compare( state1->errActionTable,
766 state2->errActionTable );
770 /* Test eof action tables. */
771 return CmpActionTable::compare( state1->eofActionTable,
772 state2->eofActionTable );
776 /* Invoked when a state looses its final state status and the leaving
777 * transition embedding data should be deleted. */
778 void FsmAp::clearOutData( StateAp *state )
780 /* Kill the out actions and priorities. */
781 state->outActionTable.empty();
782 state->outCondSet.empty();
783 state->outPriorTable.empty();
786 bool FsmAp::hasOutData( StateAp *state )
788 return ( state->outActionTable.length() > 0 ||
789 state->outCondSet.length() > 0 ||
790 state->outPriorTable.length() > 0 );
794 * Setting Conditions.
798 void logNewExpansion( Expansion *exp );
799 void logCondSpace( CondSpace *condSpace );
801 CondSpace *FsmAp::addCondSpace( const CondSet &condSet )
803 CondSpace *condSpace = condData->condSpaceMap.find( condSet );
804 if ( condSpace == 0 ) {
805 Key baseKey = condData->nextCondKey;
806 condData->nextCondKey += (1 << condSet.length() ) * keyOps->alphSize();
808 condSpace = new CondSpace( condSet );
809 condSpace->baseKey = baseKey;
810 condData->condSpaceMap.insert( condSpace );
813 cerr << "adding new condition space" << endl;
814 cerr << " condition set: ";
815 logCondSpace( condSpace );
817 cerr << " baseKey: " << baseKey.getVal() << endl;
823 void FsmAp::startFsmCondition( Action *condAction, bool sense )
825 /* Make sure the start state has no other entry points. */
827 embedCondition( startState, condAction, sense );
830 void FsmAp::allTransCondition( Action *condAction, bool sense )
832 for ( StateList::Iter state = stateList; state.lte(); state++ )
833 embedCondition( state, condAction, sense );
836 void FsmAp::leaveFsmCondition( Action *condAction, bool sense )
838 for ( StateSet::Iter state = finStateSet; state.lte(); state++ )
839 (*state)->outCondSet.insert( OutCond( condAction, sense ) );