" FIXME: Enable the range keyword post 5.17.
" syntax keyword rlKeywords machine action context include range contained
syntax keyword rlKeywords machine action context include import export contained
-syntax keyword rlExprKeywords when err lerr eof from to contained
+syntax keyword rlExprKeywords when inwhen outwhen err lerr eof from to contained
" Case Labels
syntax keyword caseLabelKeyword case contained
return cmpRes;
/* Test out condition sets. */
- cmpRes = CmpActionSet::compare( state1->outCondSet,
+ cmpRes = CmpOutCondSet::compare( state1->outCondSet,
state2->outCondSet );
if ( cmpRes != 0 )
return cmpRes;
return condSpace;
}
-void FsmAp::startFsmCondition( Action *condAction )
+void FsmAp::startFsmCondition( Action *condAction, bool sense )
{
/* Make sure the start state has no other entry points. */
isolateStartState();
- embedCondition( startState, condAction );
+ embedCondition( startState, condAction, sense );
}
-void FsmAp::allTransCondition( Action *condAction )
+void FsmAp::allTransCondition( Action *condAction, bool sense )
{
for ( StateList::Iter state = stateList; state.lte(); state++ )
- embedCondition( state, condAction );
+ embedCondition( state, condAction, sense );
}
-void FsmAp::leaveFsmCondition( Action *condAction )
+void FsmAp::leaveFsmCondition( Action *condAction, bool sense )
{
for ( StateSet::Iter state = finStateSet; state.lte(); state++ )
- (*state)->outCondSet.insert( condAction );
+ (*state)->outCondSet.insert( OutCond( condAction, sense ) );
}
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 );
}
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 ) );
}
}
void FsmAp::findEmbedExpansions( ExpansionList &expansionList,
- StateAp *destState, Action *condAction )
+ StateAp *destState, Action *condAction, bool sense )
{
StateCondList destList;
PairIter<TransAp, StateCond> transCond( destState->outList.head,
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
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,
destState->stateCondList.transfer( destList );
}
-void FsmAp::embedCondition( StateAp *state, Action *condAction )
+void FsmAp::embedCondition( StateAp *state, Action *condAction, bool sense )
{
MergeData md;
ExpansionList expList;
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 );
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();
/* Set of longest match items that may be active in a given state. */
typedef BstSet<LongestMatchPart*> LmItemSet;
+/* A Conditions which is to be
+ * transfered on pending out transitions. */
+struct OutCond
+{
+ OutCond( Action *action, bool sense )
+ : action(action), sense(sense) {}
+
+ Action *action;
+ bool sense;
+};
+
+struct CmpOutCond
+{
+ static int compare( const OutCond &outCond1, const OutCond &outCond2 )
+ {
+ if ( outCond1.action < outCond2.action )
+ return -1;
+ else if ( outCond1.action > outCond2.action )
+ return 1;
+ else if ( outCond1.sense < outCond2.sense )
+ return -1;
+ else if ( outCond1.sense > outCond2.sense )
+ return 1;
+ return 0;
+ }
+};
+
+/* Set of conditions to be transfered to on pending out transitions. */
+typedef SBstSet< OutCond, CmpOutCond > OutCondSet;
+typedef CmpSTable< OutCond, CmpOutCond > CmpOutCondSet;
+
/* Conditions. */
typedef BstSet< Action*, CmpCondId > CondSet;
typedef CmpTable< Action*, CmpCondId > CmpCondSet;
ActionTable outActionTable;
/* Conditions to add to any future transiions that leave via this sttate. */
- ActionSet outCondSet;
+ OutCondSet outCondSet;
/* Error action tables. */
ErrActionTable errActionTable;
CondSpace *addCondSpace( const CondSet &condSet );
void findEmbedExpansions( ExpansionList &expansionList,
- StateAp *destState, Action *condAction );
- void embedCondition( MergeData &md, StateAp *state, Action *condAction );
- void embedCondition( StateAp *state, Action *condAction );
+ StateAp *destState, Action *condAction, bool sense );
+ void embedCondition( MergeData &md, StateAp *state, Action *condAction, bool sense );
+ void embedCondition( StateAp *state, Action *condAction, bool sense );
- void startFsmCondition( Action *condAction );
- void allTransCondition( Action *condAction );
- void leaveFsmCondition( Action *condAction );
+ void startFsmCondition( Action *condAction, bool sense );
+ void allTransCondition( Action *condAction, bool sense );
+ void leaveFsmCondition( Action *condAction, bool sense );
/* Set error actions to execute. */
void startErrorAction( int ordering, Action *action, int transferPoint );
switch ( conditions[i].type ) {
/* Transition actions. */
case at_start:
- graph->startFsmCondition( conditions[i].action );
+ graph->startFsmCondition( conditions[i].action, conditions[i].sense );
afterOpMinimize( graph );
break;
case at_all:
- graph->allTransCondition( conditions[i].action );
+ graph->allTransCondition( conditions[i].action, conditions[i].sense );
break;
case at_leave:
- graph->leaveFsmCondition( conditions[i].action );
+ graph->leaveFsmCondition( conditions[i].action, conditions[i].sense );
break;
default:
break;
Action *action;
};
+struct ConditionTest
+{
+ ConditionTest( const InputLoc &loc, AugType type, Action *action, bool sense ) :
+ loc(loc), type(type), action(action), sense(sense) { }
+
+ InputLoc loc;
+ AugType type;
+ Action *action;
+ bool sense;
+};
+
struct Token
{
char *data;
PriorDesc *priorDescs;
Vector<Label> labels;
Vector<EpsilonLink> epsilonLinks;
- Vector<ParserAction> conditions;
+ Vector<ConditionTest> conditions;
FactorWithRep *factorWithRep;
};
parser Parser;
# General tokens.
- token TK_Word, TK_Literal, TK_Number, TK_Reference, TK_ColonEquals,
- TK_EndSection, TK_UInt, TK_Hex, TK_Word, TK_Literal, TK_DotDot,
- TK_ColonGt, TK_ColonGtGt, TK_LtColon, TK_Arrow, TK_DoubleArrow,
- TK_StarStar, TK_ColonEquals, TK_NameSep, TK_BarStar, TK_DashDash;
+ token TK_Word, TK_Literal, TK_Number, TK_EndSection, TK_UInt, TK_Hex,
+ TK_Word, TK_Literal, TK_DotDot, TK_ColonGt, TK_ColonGtGt, TK_LtColon,
+ TK_Arrow, TK_DoubleArrow, TK_StarStar, TK_ColonEquals, TK_NameSep,
+ TK_BarStar, TK_DashDash;
# Conditions.
token TK_StartCond, TK_AllCond, TK_LeavingCond;
+ # State embedding actions.
token TK_Middle;
# Global error actions.
# Keywords.
token KW_Machine, KW_Include, KW_Import, KW_Write, KW_Action, KW_AlphType,
- KW_Range, KW_GetKey, KW_Include, KW_Write, KW_Machine, KW_When, KW_Eof,
- KW_Err, KW_Lerr, KW_To, KW_From, KW_Export;
+ KW_Range, KW_GetKey, KW_Include, KW_Write, KW_Machine, KW_InWhen,
+ KW_When, KW_OutWhen, KW_Eof, KW_Err, KW_Lerr, KW_To, KW_From,
+ KW_Export;
# Specials in code blocks.
token KW_Break, KW_Exec, KW_Hold, KW_PChar, KW_Char, KW_Goto, KW_Call,
KW_Ret, KW_CurState, KW_TargState, KW_Entry, KW_Next, KW_Exec,
KW_Variable, KW_Access;
-
- # Special token for terminating semi-terminated code blocks. Needed because
- # semi is sent as a token in the code block rather than as a generic
- # symbol.
- token TK_Semi;
}%%
%% write instance_data;
};
factor_with_aug:
factor_with_aug aug_type_cond action_embed final {
- $1->factorWithAug->conditions.append( ParserAction( $2->loc,
- $2->augType, 0, $3->action ) );
+ $1->factorWithAug->conditions.append( ConditionTest( $2->loc,
+ $2->augType, $3->action, true ) );
+ $$->factorWithAug = $1->factorWithAug;
+ };
+factor_with_aug:
+ factor_with_aug aug_type_cond '!' action_embed final {
+ $1->factorWithAug->conditions.append( ConditionTest( $2->loc,
+ $2->augType, $4->action, false ) );
$$->factorWithAug = $1->factorWithAug;
};
factor_with_aug:
aug_type_cond: TK_LeavingCond final { $$->loc = $1->loc; $$->augType = at_leave; };
aug_type_cond: '%' KW_When final { $$->loc = $1->loc; $$->augType = at_leave; };
aug_type_cond: KW_When final { $$->loc = $1->loc; $$->augType = at_all; };
+aug_type_cond: KW_InWhen final { $$->loc = $1->loc; $$->augType = at_start; };
+aug_type_cond: KW_OutWhen final { $$->loc = $1->loc; $$->augType = at_leave; };
#
# To state actions.
fcall inline_code;
};
'when' => { token( KW_When ); };
+ 'inwhen' => { token( KW_InWhen ); };
+ 'outwhen' => { token( KW_OutWhen ); };
'eof' => { token( KW_Eof ); };
'err' => { token( KW_Err ); };
'lerr' => { token( KW_Lerr ); };