From b9d7348358a13e9f10d2125862fc29b68ddc7e5c Mon Sep 17 00:00:00 2001 From: thurston Date: Fri, 24 Oct 2008 22:37:40 +0000 Subject: [PATCH] The rest of the direct-to-backend code. Not tested yet. git-svn-id: http://svn.complang.org/ragel/trunk@496 052ea7fc-9027-0410-9066-f65837a77df0 --- ragel/main.cpp | 10 +- ragel/xmlcodegen.cpp | 283 +++++++++++++++++++++++++++++++++++++++++++++++++-- ragel/xmlcodegen.h | 18 +++- redfsm/gendata.cpp | 2 +- redfsm/gendata.h | 2 +- redfsm/redfsm.h | 2 +- 6 files changed, 300 insertions(+), 17 deletions(-) diff --git a/ragel/main.cpp b/ragel/main.cpp index b5c026c..0f76f7b 100644 --- a/ragel/main.cpp +++ b/ragel/main.cpp @@ -499,8 +499,8 @@ void process( const char *inputFileName, const char *intermed ) xmlParser.init(); /* Write the machines, then the surrounding code. */ - writeMachines( *xmlOutFile, hostData.str(), inputFileName, xmlParser ); - //generate( *xmlOutFile, hostData.str(), inputFileName, xmlParser ); + //writeMachines( *xmlOutFile, hostData.str(), inputFileName, xmlParser ); + generate( *xmlOutFile, hostData.str(), inputFileName, xmlParser ); /* Close the input and the intermediate file. */ delete xmlOutFile; @@ -510,9 +510,9 @@ void process( const char *inputFileName, const char *intermed ) if ( gblErrorCount > 0 ) exit(1); - xml_parse( *xmlInFile, xmlFileName, - outputActive, wantComplete, - xmlScanner, xmlParser ); +// xml_parse( *xmlInFile, xmlFileName, +// outputActive, wantComplete, +// xmlScanner, xmlParser ); /* If writing to a file, delete the ostream, causing it to flush. * Standard out is flushed automatically. */ diff --git a/ragel/xmlcodegen.cpp b/ragel/xmlcodegen.cpp index a445617..66bddca 100644 --- a/ragel/xmlcodegen.cpp +++ b/ragel/xmlcodegen.cpp @@ -1003,6 +1003,279 @@ void XMLCodeGen::writeXML() "\n"; } +void XMLCodeGen::makeExports() +{ + for ( ExportList::Iter exp = pd->exportList; exp.lte(); exp++ ) + xmlParser.cgd->exportList.append( new Export( exp->name, exp->key ) ); +} + +void XMLCodeGen::makeAction( Action *action ) +{ + GenInlineList *genList = new GenInlineList; + makeGenInlineList( genList, action->inlineList ); + + xmlParser.cgd->newAction( xmlParser.curAction++, action->name, + action->loc.line, action->loc.col, genList ); +} + + +void XMLCodeGen::makeActionList() +{ + /* Determine which actions to write. */ + int nextActionId = 0; + for ( ActionList::Iter act = pd->actionList; act.lte(); act++ ) { + if ( act->numRefs() > 0 || act->numCondRefs > 0 ) + act->actionId = nextActionId++; + } + + /* Write the list. */ + xmlParser.cgd->initActionList( nextActionId ); + xmlParser.curAction = 0; + + for ( ActionList::Iter act = pd->actionList; act.lte(); act++ ) { + if ( act->actionId >= 0 ) + makeAction( act ); + } +} + +void XMLCodeGen::makeActionTableList() +{ + /* Must first order the action tables based on their id. */ + int numTables = nextActionTableId; + RedActionTable **tables = new RedActionTable*[numTables]; + for ( ActionTableMap::Iter at = actionTableMap; at.lte(); at++ ) + tables[at->id] = at; + + xmlParser.cgd->initActionTableList( numTables ); + xmlParser.curActionTable = 0; + + for ( int t = 0; t < numTables; t++ ) { + long length = tables[t]->key.length(); + + /* Collect the action table. */ + RedAction *redAct = xmlParser.cgd->allActionTables + xmlParser.curActionTable; + redAct->actListId = xmlParser.curActionTable; + redAct->key.setAsNew( length ); + + for ( ActionTable::Iter atel = tables[t]->key; atel.lte(); atel++ ) { + redAct->key[atel.pos()].key = 0; + redAct->key[atel.pos()].value = xmlParser.cgd->allActions + + atel->value->actionId; + } + + xmlParser.curActionTable += 1; + } + + delete[] tables; +} + +void XMLCodeGen::makeConditions() +{ + if ( condData->condSpaceMap.length() > 0 ) { + long nextCondSpaceId = 0; + for ( CondSpaceMap::Iter cs = condData->condSpaceMap; cs.lte(); cs++ ) + cs->condSpaceId = nextCondSpaceId++; + + long listLength = condData->condSpaceMap.length(); + xmlParser.cgd->initCondSpaceList( listLength ); + xmlParser.curCondSpace = 0; + + for ( CondSpaceMap::Iter cs = condData->condSpaceMap; cs.lte(); cs++ ) { + long id = cs->condSpaceId; + xmlParser.cgd->newCondSpace( xmlParser.curCondSpace, id, cs->baseKey ); + for ( CondSet::Iter csi = cs->condSet; csi.lte(); csi++ ) + xmlParser.cgd->condSpaceItem( xmlParser.curCondSpace, (*csi)->actionId ); + xmlParser.curCondSpace += 1; + } + } +} + +bool XMLCodeGen::makeNameInst( std::string &res, NameInst *nameInst ) +{ + bool written = false; + if ( nameInst->parent != 0 ) + written = makeNameInst( res, nameInst->parent ); + + if ( nameInst->name != 0 ) { + if ( written ) + res += '_'; + res += nameInst->name; + written = true; + } + + return written; +} + +void XMLCodeGen::makeEntryPoints() +{ + /* List of entry points other than start state. */ + if ( fsm->entryPoints.length() > 0 || pd->lmRequiresErrorState ) { + if ( pd->lmRequiresErrorState ) + xmlParser.cgd->setForcedErrorState(); + + for ( EntryMap::Iter en = fsm->entryPoints; en.lte(); en++ ) { + /* Get the name instantiation from nameIndex. */ + NameInst *nameInst = pd->nameIndex[en->key]; + std::string name; + makeNameInst( name, nameInst ); + StateAp *state = en->value; + xmlParser.cgd->addEntryPoint( strdup(name.c_str()), state->alg.stateNum ); + } + } +} + +void XMLCodeGen::makeStateActions( StateAp *state ) +{ + RedActionTable *toStateActions = 0; + if ( state->toStateActionTable.length() > 0 ) + toStateActions = actionTableMap.find( state->toStateActionTable ); + + RedActionTable *fromStateActions = 0; + if ( state->fromStateActionTable.length() > 0 ) + fromStateActions = actionTableMap.find( state->fromStateActionTable ); + + /* EOF actions go out here only if the state has no eof target. If it has + * an eof target then an eof transition will be used instead. */ + RedActionTable *eofActions = 0; + if ( state->eofTarget == 0 && state->eofActionTable.length() > 0 ) + eofActions = actionTableMap.find( state->eofActionTable ); + + if ( toStateActions != 0 || fromStateActions != 0 || eofActions != 0 ) { + long to = -1; + if ( toStateActions != 0 ) + to = toStateActions->id; + + long from = -1; + if ( fromStateActions != 0 ) + from = fromStateActions->id; + + long eof = -1; + if ( eofActions != 0 ) + eof = eofActions->id; + + xmlParser.cgd->setStateActions( xmlParser.curState, to, from, eof ); + } +} + +void XMLCodeGen::makeEofTrans( StateAp *state ) +{ + RedActionTable *eofActions = 0; + if ( state->eofActionTable.length() > 0 ) + eofActions = actionTableMap.find( state->eofActionTable ); + + /* The EOF trans is used when there is an eof target, otherwise the eof + * action goes into state actions. */ + if ( state->eofTarget != 0 ) { + long targ = state->eofTarget->alg.stateNum; + long action = -1; + if ( eofActions != 0 ) + action = eofActions->id; + + xmlParser.cgd->setEofTrans( xmlParser.curState, targ, action ); + } +} + +void XMLCodeGen::makeStateConditions( StateAp *state ) +{ + if ( state->stateCondList.length() > 0 ) { + long length = state->stateCondList.length(); + xmlParser.cgd->initStateCondList( xmlParser.curState, length ); + xmlParser.curStateCond = 0; + + for ( StateCondList::Iter scdi = state->stateCondList; scdi.lte(); scdi++ ) { + xmlParser.cgd->addStateCond( xmlParser.curState, scdi->lowKey, scdi->highKey, + scdi->condSpace->condSpaceId ); + } + } +} + +void XMLCodeGen::makeTrans( Key lowKey, Key highKey, TransAp *trans ) +{ + /* First reduce the action. */ + RedActionTable *actionTable = 0; + if ( trans->actionTable.length() > 0 ) + actionTable = actionTableMap.find( trans->actionTable ); + + long targ = -1; + if ( trans->toState != 0 ) + targ = trans->toState->alg.stateNum; + + long action = -1; + if ( actionTable != 0 ) + action = actionTable->id; + + xmlParser.cgd->newTrans( xmlParser.curState, xmlParser.curTrans++, lowKey, highKey, targ, action ); +} + + +void XMLCodeGen::makeTransList( StateAp *state ) +{ + TransListVect outList; + + /* If there is only are no ranges the task is simple. */ + if ( state->outList.length() > 0 ) { + /* Loop each source range. */ + for ( TransList::Iter trans = state->outList; trans.lte(); trans++ ) { + /* Reduce the transition. If it reduced to anything then add it. */ + appendTrans( outList, trans->lowKey, trans->highKey, trans ); + } + } + + xmlParser.cgd->initTransList( xmlParser.curState, outList.length() ); + xmlParser.curTrans = 0; + + for ( TransListVect::Iter tvi = outList; tvi.lte(); tvi++ ) + makeTrans( tvi->lowKey, tvi->highKey, tvi->value ); + + xmlParser.cgd->finishTransList( xmlParser.curState ); +} + + +void XMLCodeGen::makeStateList() +{ + /* Write the list of states. */ + long length = fsm->stateList.length(); + xmlParser.cgd->initStateList( length ); + xmlParser.curState = 0; + for ( StateList::Iter st = fsm->stateList; st.lte(); st++ ) { + makeStateActions( st ); + makeEofTrans( st ); + makeStateConditions( st ); + makeTransList( st ); + + long id = st->alg.stateNum; + xmlParser.cgd->setId( xmlParser.curState, id ); + + if ( st->isFinState() ) + xmlParser.cgd->setFinal( xmlParser.curState ); + + xmlParser.curState += 1; + } +} + + +void XMLCodeGen::makeMachine() +{ + xmlParser.cgd->createMachine(); + + /* Action tables. */ + reduceActionTables(); + + makeActionList(); + makeActionTableList(); + makeConditions(); + + /* Start State. */ + xmlParser.cgd->setStartState( fsm->startState->alg.stateNum ); + + /* Error state. */ + if ( fsm->errState != 0 ) + xmlParser.cgd->setErrorState( fsm->errState->alg.stateNum ); + + makeEntryPoints(); + makeStateList(); +} + void XMLCodeGen::makeBackend() { /* Open the definition. */ @@ -1089,14 +1362,8 @@ void XMLCodeGen::makeBackend() makeGenInlineList( xmlParser.cgd->dataExpr, pd->dataExpr ); } -#if 0 - writeExports(); - - writeMachine(); - - out << - "\n"; -#endif + makeExports(); + makeMachine(); } diff --git a/ragel/xmlcodegen.h b/ragel/xmlcodegen.h index ab4d5cc..3afd4d5 100644 --- a/ragel/xmlcodegen.h +++ b/ragel/xmlcodegen.h @@ -132,9 +132,25 @@ private: void makeLmSwitch( GenInlineList *outList, InlineItem *item ); void makeSetTokend( GenInlineList *outList, long offset ); void makeSetAct( GenInlineList *outList, long lmId ); - void makeSubList( GenInlineList *outList, InlineList *inlineList, GenInlineItem::Type type ); + void makeSubList( GenInlineList *outList, InlineList *inlineList, + GenInlineItem::Type type ); void makeTargetItem( GenInlineList *outList, long targetId, GenInlineItem::Type type ); void makeExecGetTokend( GenInlineList *outList ); + void makeExports(); + void makeMachine(); + void makeActionList(); + void makeAction( Action *action ); + void makeActionTableList(); + void makeConditions(); + void makeEntryPoints(); + bool makeNameInst( std::string &out, NameInst *nameInst ); + void makeStateList(); + + void makeStateActions( StateAp *state ); + void makeEofTrans( StateAp *state ); + void makeStateConditions( StateAp *state ); + void makeTransList( StateAp *state ); + void makeTrans( Key lowKey, Key highKey, TransAp *trans ); char *fsmName; ParseData *pd; diff --git a/redfsm/gendata.cpp b/redfsm/gendata.cpp index f1f8bec..b544a60 100644 --- a/redfsm/gendata.cpp +++ b/redfsm/gendata.cpp @@ -78,7 +78,7 @@ void CodeGenData::initActionList( unsigned long length ) actionList.append( allActions+a ); } -void CodeGenData::newAction( int anum, char *name, int line, +void CodeGenData::newAction( int anum, const char *name, int line, int col, GenInlineList *inlineList ) { allActions[anum].actionId = anum; diff --git a/redfsm/gendata.h b/redfsm/gendata.h index 81dde1c..4036cc7 100644 --- a/redfsm/gendata.h +++ b/redfsm/gendata.h @@ -149,7 +149,7 @@ struct CodeGenData void createMachine(); void initActionList( unsigned long length ); - void newAction( int anum, char *name, int line, int col, GenInlineList *inlineList ); + void newAction( int anum, const char *name, int line, int col, GenInlineList *inlineList ); void initActionTableList( unsigned long length ); void initStateList( unsigned long length ); void setStartState( unsigned long startState ); diff --git a/redfsm/redfsm.h b/redfsm/redfsm.h index 654cafb..257d581 100644 --- a/redfsm/redfsm.h +++ b/redfsm/redfsm.h @@ -110,7 +110,7 @@ struct GenAction /* Data collected during parse. */ GenInputLoc loc; - char *name; + const char *name; GenInlineList *inlineList; int actionId; -- 2.7.4