From 3ff2c43e413ed94f4b1debc11c60fe04341faba0 Mon Sep 17 00:00:00 2001 From: thurston Date: Tue, 30 Jan 2007 05:20:52 +0000 Subject: [PATCH] Moved analysis code from FsmCodeGen into CodeGenData. git-svn-id: http://svn.complang.org/ragel/trunk@34 052ea7fc-9027-0410-9066-f65837a77df0 --- rlcodegen/fsmcodegen.cpp | 174 ---------------------------------------------- rlcodegen/fsmcodegen.h | 5 -- rlcodegen/gendata.cpp | 177 ++++++++++++++++++++++++++++++++++++++++++++++- rlcodegen/gendata.h | 6 ++ 4 files changed, 182 insertions(+), 180 deletions(-) diff --git a/rlcodegen/fsmcodegen.cpp b/rlcodegen/fsmcodegen.cpp index 1d07ad9..4917c90 100644 --- a/rlcodegen/fsmcodegen.cpp +++ b/rlcodegen/fsmcodegen.cpp @@ -79,57 +79,6 @@ bool FsmCodeGen::anyActions() return redFsm->actionMap.length() > 0; } -void FsmCodeGen::findFinalActionRefs() -{ - for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { - /* Rerence count out of single transitions. */ - for ( RedTransList::Iter rtel = st->outSingle; rtel.lte(); rtel++ ) { - if ( rtel->value->action != 0 ) { - rtel->value->action->numTransRefs += 1; - for ( ActionTable::Iter item = rtel->value->action->key; item.lte(); item++ ) - item->value->numTransRefs += 1; - } - } - - /* Reference count out of range transitions. */ - for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { - if ( rtel->value->action != 0 ) { - rtel->value->action->numTransRefs += 1; - for ( ActionTable::Iter item = rtel->value->action->key; item.lte(); item++ ) - item->value->numTransRefs += 1; - } - } - - /* Reference count default transition. */ - if ( st->defTrans != 0 && st->defTrans->action != 0 ) { - st->defTrans->action->numTransRefs += 1; - for ( ActionTable::Iter item = st->defTrans->action->key; item.lte(); item++ ) - item->value->numTransRefs += 1; - } - - /* Reference count to state actions. */ - if ( st->toStateAction != 0 ) { - st->toStateAction->numToStateRefs += 1; - for ( ActionTable::Iter item = st->toStateAction->key; item.lte(); item++ ) - item->value->numToStateRefs += 1; - } - - /* Reference count from state actions. */ - if ( st->fromStateAction != 0 ) { - st->fromStateAction->numFromStateRefs += 1; - for ( ActionTable::Iter item = st->fromStateAction->key; item.lte(); item++ ) - item->value->numFromStateRefs += 1; - } - - /* Reference count EOF actions. */ - if ( st->eofAction != 0 ) { - st->eofAction->numEofRefs += 1; - for ( ActionTable::Iter item = st->eofAction->key; item.lte(); item++ ) - item->value->numEofRefs += 1; - } - } -} - /* Assign ids to referenced actions. */ void FsmCodeGen::assignActionIds() { @@ -238,129 +187,6 @@ void FsmCodeGen::setValueLimits() } } -void FsmCodeGen::analyzeAction( Action *act, InlineList *inlineList ) -{ - for ( InlineList::Iter item = *inlineList; item.lte(); item++ ) { - /* Only consider actions that are referenced. */ - if ( act->numRefs() > 0 ) { - if ( item->type == InlineItem::Goto || item->type == InlineItem::GotoExpr ) - bAnyActionGotos = true; - else if ( item->type == InlineItem::Call || item->type == InlineItem::CallExpr ) - bAnyActionCalls = true; - else if ( item->type == InlineItem::Ret ) - bAnyActionRets = true; - } - - /* Check for various things in regular actions. */ - if ( act->numTransRefs > 0 || act->numToStateRefs > 0 || act->numFromStateRefs > 0 ) { - /* Any returns in regular actions? */ - if ( item->type == InlineItem::Ret ) - bAnyRegActionRets = true; - - /* Any next statements in the regular actions? */ - if ( item->type == InlineItem::Next || item->type == InlineItem::NextExpr ) - bAnyRegNextStmt = true; - - /* Any by value control in regular actions? */ - if ( item->type == InlineItem::CallExpr || item->type == InlineItem::GotoExpr ) - bAnyRegActionByValControl = true; - - /* Any references to the current state in regular actions? */ - if ( item->type == InlineItem::Curs ) - bAnyRegCurStateRef = true; - - if ( item->type == InlineItem::Break ) - bAnyRegBreak = true; - - if ( item->type == InlineItem::LmSwitch && item->handlesError ) - bAnyLmSwitchError = true; - } - - if ( item->children != 0 ) - analyzeAction( act, item->children ); - } -} - -void FsmCodeGen::analyzeActionList( RedAction *redAct, InlineList *inlineList ) -{ - for ( InlineList::Iter item = *inlineList; item.lte(); item++ ) { - /* Any next statements in the action table? */ - if ( item->type == InlineItem::Next || item->type == InlineItem::NextExpr ) - redAct->bAnyNextStmt = true; - - /* Any references to the current state. */ - if ( item->type == InlineItem::Curs ) - redAct->bAnyCurStateRef = true; - - if ( item->type == InlineItem::Break ) - redAct->bAnyBreakStmt = true; - - if ( item->children != 0 ) - analyzeActionList( redAct, item->children ); - } -} - -/* Gather various info on the machine. */ -void FsmCodeGen::analyzeMachine() -{ - /* Find the true count of action references. */ - findFinalActionRefs(); - - /* Check if there are any calls in action code. */ - for ( ActionList::Iter act = cgd->actionList; act.lte(); act++ ) { - /* Record the occurrence of various kinds of actions. */ - if ( act->numToStateRefs > 0 ) - bAnyToStateActions = true; - if ( act->numFromStateRefs > 0 ) - bAnyFromStateActions = true; - if ( act->numEofRefs > 0 ) - bAnyEofActions = true; - if ( act->numTransRefs > 0 ) - bAnyRegActions = true; - - /* Recurse through the action's parse tree looking for various things. */ - analyzeAction( act, act->inlineList ); - } - - /* Analyze reduced action lists. */ - for ( ActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { - for ( ActionTable::Iter act = redAct->key; act.lte(); act++ ) - analyzeActionList( redAct, act->value->inlineList ); - } - - /* Find states that have transitions with actions that have next - * statements. */ - for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { - /* Check any actions out of outSinge. */ - for ( RedTransList::Iter rtel = st->outSingle; rtel.lte(); rtel++ ) { - if ( rtel->value->action != 0 && rtel->value->action->anyCurStateRef() ) - st->bAnyRegCurStateRef = true; - } - - /* Check any actions out of outRange. */ - for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { - if ( rtel->value->action != 0 && rtel->value->action->anyCurStateRef() ) - st->bAnyRegCurStateRef = true; - } - - /* Check any action out of default. */ - if ( st->defTrans != 0 && st->defTrans->action != 0 && - st->defTrans->action->anyCurStateRef() ) - st->bAnyRegCurStateRef = true; - - if ( st->stateCondList.length() > 0 ) - bAnyConditions = true; - } - - /* Assign ids to actions that are referenced. */ - assignActionIds(); - - /* Set the maximums of various values used for deciding types. */ - setValueLimits(); - - /* Determine if we should use indicies. */ - calcIndexSize(); -} unsigned int FsmCodeGen::arrayTypeSize( unsigned long maxVal ) { diff --git a/rlcodegen/fsmcodegen.h b/rlcodegen/fsmcodegen.h index 0fec982..1d15a88 100644 --- a/rlcodegen/fsmcodegen.h +++ b/rlcodegen/fsmcodegen.h @@ -68,10 +68,6 @@ public: virtual void writeOutExec() = 0; virtual void writeOutEOF() = 0; - /* Gather various info on the machine. */ - void analyzeAction( Action *act, InlineList *inlineList ); - void analyzeActionList( RedAction *redAct, InlineList *inlineList ); - void analyzeMachine(); protected: friend struct CodeGenData; @@ -193,7 +189,6 @@ protected: /* Determine if we should use indicies. */ virtual void calcIndexSize() {} - void findFinalActionRefs(); void assignActionIds(); void setValueLimits(); diff --git a/rlcodegen/gendata.cpp b/rlcodegen/gendata.cpp index efaaa4b..ee14c43 100644 --- a/rlcodegen/gendata.cpp +++ b/rlcodegen/gendata.cpp @@ -402,6 +402,181 @@ Key CodeGenData::findMaxKey() return maxKey; } +void CodeGenData::findFinalActionRefs() +{ + for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { + /* Rerence count out of single transitions. */ + for ( RedTransList::Iter rtel = st->outSingle; rtel.lte(); rtel++ ) { + if ( rtel->value->action != 0 ) { + rtel->value->action->numTransRefs += 1; + for ( ActionTable::Iter item = rtel->value->action->key; item.lte(); item++ ) + item->value->numTransRefs += 1; + } + } + + /* Reference count out of range transitions. */ + for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { + if ( rtel->value->action != 0 ) { + rtel->value->action->numTransRefs += 1; + for ( ActionTable::Iter item = rtel->value->action->key; item.lte(); item++ ) + item->value->numTransRefs += 1; + } + } + + /* Reference count default transition. */ + if ( st->defTrans != 0 && st->defTrans->action != 0 ) { + st->defTrans->action->numTransRefs += 1; + for ( ActionTable::Iter item = st->defTrans->action->key; item.lte(); item++ ) + item->value->numTransRefs += 1; + } + + /* Reference count to state actions. */ + if ( st->toStateAction != 0 ) { + st->toStateAction->numToStateRefs += 1; + for ( ActionTable::Iter item = st->toStateAction->key; item.lte(); item++ ) + item->value->numToStateRefs += 1; + } + + /* Reference count from state actions. */ + if ( st->fromStateAction != 0 ) { + st->fromStateAction->numFromStateRefs += 1; + for ( ActionTable::Iter item = st->fromStateAction->key; item.lte(); item++ ) + item->value->numFromStateRefs += 1; + } + + /* Reference count EOF actions. */ + if ( st->eofAction != 0 ) { + st->eofAction->numEofRefs += 1; + for ( ActionTable::Iter item = st->eofAction->key; item.lte(); item++ ) + item->value->numEofRefs += 1; + } + } +} + +void CodeGenData::analyzeAction( Action *act, InlineList *inlineList ) +{ + for ( InlineList::Iter item = *inlineList; item.lte(); item++ ) { + /* Only consider actions that are referenced. */ + if ( act->numRefs() > 0 ) { + if ( item->type == InlineItem::Goto || item->type == InlineItem::GotoExpr ) + codeGen->bAnyActionGotos = true; + else if ( item->type == InlineItem::Call || item->type == InlineItem::CallExpr ) + codeGen->bAnyActionCalls = true; + else if ( item->type == InlineItem::Ret ) + codeGen->bAnyActionRets = true; + } + + /* Check for various things in regular actions. */ + if ( act->numTransRefs > 0 || act->numToStateRefs > 0 || act->numFromStateRefs > 0 ) { + /* Any returns in regular actions? */ + if ( item->type == InlineItem::Ret ) + codeGen->bAnyRegActionRets = true; + + /* Any next statements in the regular actions? */ + if ( item->type == InlineItem::Next || item->type == InlineItem::NextExpr ) + codeGen->bAnyRegNextStmt = true; + + /* Any by value control in regular actions? */ + if ( item->type == InlineItem::CallExpr || item->type == InlineItem::GotoExpr ) + codeGen->bAnyRegActionByValControl = true; + + /* Any references to the current state in regular actions? */ + if ( item->type == InlineItem::Curs ) + codeGen->bAnyRegCurStateRef = true; + + if ( item->type == InlineItem::Break ) + codeGen->bAnyRegBreak = true; + + if ( item->type == InlineItem::LmSwitch && item->handlesError ) + codeGen->bAnyLmSwitchError = true; + } + + if ( item->children != 0 ) + analyzeAction( act, item->children ); + } +} + +void CodeGenData::analyzeActionList( RedAction *redAct, InlineList *inlineList ) +{ + for ( InlineList::Iter item = *inlineList; item.lte(); item++ ) { + /* Any next statements in the action table? */ + if ( item->type == InlineItem::Next || item->type == InlineItem::NextExpr ) + redAct->bAnyNextStmt = true; + + /* Any references to the current state. */ + if ( item->type == InlineItem::Curs ) + redAct->bAnyCurStateRef = true; + + if ( item->type == InlineItem::Break ) + redAct->bAnyBreakStmt = true; + + if ( item->children != 0 ) + analyzeActionList( redAct, item->children ); + } +} + +/* Gather various info on the machine. */ +void CodeGenData::analyzeMachine() +{ + /* Find the true count of action references. */ + findFinalActionRefs(); + + /* Check if there are any calls in action code. */ + for ( ActionList::Iter act = cgd->actionList; act.lte(); act++ ) { + /* Record the occurrence of various kinds of actions. */ + if ( act->numToStateRefs > 0 ) + codeGen->bAnyToStateActions = true; + if ( act->numFromStateRefs > 0 ) + codeGen->bAnyFromStateActions = true; + if ( act->numEofRefs > 0 ) + codeGen->bAnyEofActions = true; + if ( act->numTransRefs > 0 ) + codeGen->bAnyRegActions = true; + + /* Recurse through the action's parse tree looking for various things. */ + analyzeAction( act, act->inlineList ); + } + + /* Analyze reduced action lists. */ + for ( ActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) { + for ( ActionTable::Iter act = redAct->key; act.lte(); act++ ) + analyzeActionList( redAct, act->value->inlineList ); + } + + /* Find states that have transitions with actions that have next + * statements. */ + for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) { + /* Check any actions out of outSinge. */ + for ( RedTransList::Iter rtel = st->outSingle; rtel.lte(); rtel++ ) { + if ( rtel->value->action != 0 && rtel->value->action->anyCurStateRef() ) + st->bAnyRegCurStateRef = true; + } + + /* Check any actions out of outRange. */ + for ( RedTransList::Iter rtel = st->outRange; rtel.lte(); rtel++ ) { + if ( rtel->value->action != 0 && rtel->value->action->anyCurStateRef() ) + st->bAnyRegCurStateRef = true; + } + + /* Check any action out of default. */ + if ( st->defTrans != 0 && st->defTrans->action != 0 && + st->defTrans->action->anyCurStateRef() ) + st->bAnyRegCurStateRef = true; + + if ( st->stateCondList.length() > 0 ) + codeGen->bAnyConditions = true; + } + + /* Assign ids to actions that are referenced. */ + codeGen->assignActionIds(); + + /* Set the maximums of various values used for deciding types. */ + codeGen->setValueLimits(); + + /* Determine if we should use indicies. */ + codeGen->calcIndexSize(); +} + /* Generate the code for an fsm. Assumes parseData is set up properly. Called * by parser code. */ void CodeGenData::prepareMachine() @@ -468,7 +643,7 @@ void CodeGenData::prepareMachine() /* Anlayze Machine will find the final action reference counts, among * other things. We will use these in reporting the usage * of fsm directives in action code. */ - codeGen->analyzeMachine(); + analyzeMachine(); codeGen->maxKey = maxKey; } diff --git a/rlcodegen/gendata.h b/rlcodegen/gendata.h index 9b5ec69..4485e2d 100644 --- a/rlcodegen/gendata.h +++ b/rlcodegen/gendata.h @@ -149,6 +149,12 @@ struct CodeGenData void generate(); void generateCode(); + + /* Gather various info on the machine. */ + void analyzeActionList( RedAction *redAct, InlineList *inlineList ); + void analyzeAction( Action *act, InlineList *inlineList ); + void findFinalActionRefs(); + void analyzeMachine(); void prepareMachine(); bool hasBeenPrepared; }; -- 2.7.4