From 7c933ad4d0e7f73001eb50d98f2d8c85af791af5 Mon Sep 17 00:00:00 2001 From: thurston Date: Thu, 1 Feb 2007 00:02:59 +0000 Subject: [PATCH] Moved code dependent on the output type and code style from CodeGenData to FsmCodeGen. git-svn-id: http://svn.complang.org/ragel/trunk@45 052ea7fc-9027-0410-9066-f65837a77df0 --- rlcodegen/fsmcodegen.cpp | 138 +++++++++++++++++++++++++++++++++++++++++++++++ rlcodegen/fsmcodegen.h | 6 +++ rlcodegen/gendata.cpp | 136 ---------------------------------------------- rlcodegen/gendata.h | 8 +-- 4 files changed, 148 insertions(+), 140 deletions(-) diff --git a/rlcodegen/fsmcodegen.cpp b/rlcodegen/fsmcodegen.cpp index cc2051c..4de1720 100644 --- a/rlcodegen/fsmcodegen.cpp +++ b/rlcodegen/fsmcodegen.cpp @@ -25,6 +25,7 @@ #include "fsmcodegen.h" #include "redfsm.h" #include "gendata.h" +#include "gvdotgen.h" #include #include #include @@ -783,3 +784,140 @@ string JavaCodeGen::CTRL_FLOW() return "if (true) "; } +/* Generate the code for an fsm. Assumes parseData is set up properly. Called + * by parser code. */ +void FsmCodeGen::prepareMachine() +{ + if ( hasBeenPrepared ) + return; + hasBeenPrepared = true; + + /* Do this before distributing transitions out to singles and defaults + * makes life easier. */ + redFsm->maxKey = findMaxKey(); + + redFsm->assignActionLocs(); + + /* Order the states. */ + redFsm->depthFirstOrdering(); + + if ( codeStyle == GenGoto || codeStyle == GenFGoto || + codeStyle == GenIpGoto || codeStyle == GenSplit ) + { + /* For goto driven machines we can keep the original depth + * first ordering because it's ok if the state ids are not + * sequential. Split the the ids by final state status. */ + redFsm->sortStateIdsByFinal(); + } + else { + /* For table driven machines the location of the state is used to + * identify it so the states must be sorted by their final ids. + * Though having a deterministic ordering is important, + * specifically preserving the depth first ordering is not because + * states are stored in tables. */ + redFsm->sortStatesByFinal(); + redFsm->sequentialStateIds(); + } + + /* Find the first final state. This is the final state with the lowest + * id. */ + redFsm->findFirstFinState(); + + /* Choose default transitions and the single transition. */ + redFsm->chooseDefaultSpan(); + + /* Maybe do flat expand, otherwise choose single. */ + if ( codeStyle == GenFlat || codeStyle == GenFFlat ) + redFsm->makeFlat(); + else + redFsm->chooseSingle(); + + /* If any errors have occured in the input file then don't write anything. */ + if ( gblErrorCount > 0 ) + return; + + if ( codeStyle == GenSplit ) + redFsm->partitionFsm( numSplitPartitions ); + + if ( codeStyle == GenIpGoto || codeStyle == GenSplit ) + redFsm->setInTrans(); + + /* 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. */ + analyzeMachine(); + + /* Determine if we should use indicies. */ + codeGen->calcIndexSize(); +} + +void FsmCodeGen::generateGraphviz() +{ + /* Do ordering and choose state ids. */ + redFsm->depthFirstOrdering(); + redFsm->sequentialStateIds(); + + /* For dot file generation we want to pick default transitions. */ + redFsm->chooseDefaultSpan(); + + /* Make the generator. */ + GraphvizDotGen dotGen( fsmName, this, redFsm, out ); + + /* Write out with it. */ + dotGen.writeDotFile(); +} + +void FsmCodeGen::generateCode() +{ + if ( writeOps & WO_NOEND ) + hasEnd = false; + + if ( writeOps & WO_NOERROR ) + writeErr = false; + + if ( writeOps & WO_NOPREFIX ) + dataPrefix = false; + + if ( writeOps & WO_NOFF ) + writeFirstFinal = false; + + if ( writeData || writeInit || writeExec || writeEOF ) { + prepareMachine(); + + /* Force a newline. */ + out << "\n"; + genLineDirective( out ); + } + + + if ( writeExec ) { + /* Must set labels immediately before writing because we may depend + * on the noend write option. */ + codeGen->setLabelsNeeded(); + } + + if ( writeData ) + codeGen->writeOutData(); + + if ( writeInit ) + codeGen->writeOutInit(); + + if ( writeExec ) + codeGen->writeOutExec(); + + if ( writeEOF ) + codeGen->writeOutEOF(); +} + +void FsmCodeGen::generate() +{ + if ( redFsm != 0 ) { + if ( outputFormat == OutCode ) + generateCode(); + else if ( outputFormat == OutGraphvizDot && !graphvizDone ) { + graphvizDone = true; + generateGraphviz(); + } + } +} + diff --git a/rlcodegen/fsmcodegen.h b/rlcodegen/fsmcodegen.h index 007fc1f..db8f0e8 100644 --- a/rlcodegen/fsmcodegen.h +++ b/rlcodegen/fsmcodegen.h @@ -177,6 +177,12 @@ protected: bool useIndicies; public: + void generateGraphviz(); + void prepareMachine(); + void generateCode(); + + virtual void generate(); + /* Determine if we should use indicies. */ virtual void calcIndexSize() {} }; diff --git a/rlcodegen/gendata.cpp b/rlcodegen/gendata.cpp index dd1ae06..be419c9 100644 --- a/rlcodegen/gendata.cpp +++ b/rlcodegen/gendata.cpp @@ -625,142 +625,6 @@ void CodeGenData::analyzeMachine() setValueLimits(); } -/* Generate the code for an fsm. Assumes parseData is set up properly. Called - * by parser code. */ -void CodeGenData::prepareMachine() -{ - if ( hasBeenPrepared ) - return; - hasBeenPrepared = true; - - /* Do this before distributing transitions out to singles and defaults - * makes life easier. */ - redFsm->maxKey = findMaxKey(); - - redFsm->assignActionLocs(); - - /* Order the states. */ - redFsm->depthFirstOrdering(); - - if ( codeStyle == GenGoto || codeStyle == GenFGoto || - codeStyle == GenIpGoto || codeStyle == GenSplit ) - { - /* For goto driven machines we can keep the original depth - * first ordering because it's ok if the state ids are not - * sequential. Split the the ids by final state status. */ - redFsm->sortStateIdsByFinal(); - } - else { - /* For table driven machines the location of the state is used to - * identify it so the states must be sorted by their final ids. - * Though having a deterministic ordering is important, - * specifically preserving the depth first ordering is not because - * states are stored in tables. */ - redFsm->sortStatesByFinal(); - redFsm->sequentialStateIds(); - } - - /* Find the first final state. This is the final state with the lowest - * id. */ - redFsm->findFirstFinState(); - - /* Choose default transitions and the single transition. */ - redFsm->chooseDefaultSpan(); - - /* Maybe do flat expand, otherwise choose single. */ - if ( codeStyle == GenFlat || codeStyle == GenFFlat ) - redFsm->makeFlat(); - else - redFsm->chooseSingle(); - - /* If any errors have occured in the input file then don't write anything. */ - if ( gblErrorCount > 0 ) - return; - - if ( codeStyle == GenSplit ) - redFsm->partitionFsm( numSplitPartitions ); - - if ( codeStyle == GenIpGoto || codeStyle == GenSplit ) - redFsm->setInTrans(); - - /* 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. */ - analyzeMachine(); - - /* Determine if we should use indicies. */ - codeGen->calcIndexSize(); -} - -void CodeGenData::generateGraphviz() -{ - /* Do ordering and choose state ids. */ - redFsm->depthFirstOrdering(); - redFsm->sequentialStateIds(); - - /* For dot file generation we want to pick default transitions. */ - redFsm->chooseDefaultSpan(); - - /* Make the generator. */ - GraphvizDotGen dotGen( fsmName, this, redFsm, out ); - - /* Write out with it. */ - dotGen.writeDotFile(); -} - -void CodeGenData::generateCode() -{ - if ( writeOps & WO_NOEND ) - hasEnd = false; - - if ( writeOps & WO_NOERROR ) - writeErr = false; - - if ( writeOps & WO_NOPREFIX ) - dataPrefix = false; - - if ( writeOps & WO_NOFF ) - writeFirstFinal = false; - - if ( writeData || writeInit || writeExec || writeEOF ) { - prepareMachine(); - - /* Force a newline. */ - out << "\n"; - genLineDirective( out ); - } - - - if ( writeExec ) { - /* Must set labels immediately before writing because we may depend - * on the noend write option. */ - codeGen->setLabelsNeeded(); - } - - if ( writeData ) - codeGen->writeOutData(); - - if ( writeInit ) - codeGen->writeOutInit(); - - if ( writeExec ) - codeGen->writeOutExec(); - - if ( writeEOF ) - codeGen->writeOutEOF(); -} - -void CodeGenData::generate() -{ - if ( redFsm != 0 ) { - if ( outputFormat == OutCode ) - generateCode(); - else if ( outputFormat == OutGraphvizDot && !graphvizDone ) { - graphvizDone = true; - generateGraphviz(); - } - } -} void lineDirective( ostream &out, char *fileName, int line ) { diff --git a/rlcodegen/gendata.h b/rlcodegen/gendata.h index 0c59db7..0dd24a3 100644 --- a/rlcodegen/gendata.h +++ b/rlcodegen/gendata.h @@ -47,6 +47,7 @@ typedef AvlMapEl CodeGenMapEl; struct CodeGenData { CodeGenData( ostream &out ); + virtual ~CodeGenData() {} /* * Collecting the machine. @@ -117,13 +118,9 @@ struct CodeGenData bool setAlphType( char *data ); - void generateGraphviz(); void resolveTargetStates( InlineList *inlineList ); Key findMaxKey(); - void generate(); - void generateCode(); - /* Gather various info on the machine. */ void analyzeActionList( RedAction *redAct, InlineList *inlineList ); void analyzeAction( Action *act, InlineList *inlineList ); @@ -134,6 +131,9 @@ struct CodeGenData void assignActionIds(); void prepareMachine(); bool hasBeenPrepared; + + /* The interface to the code generator. */ + virtual void generate() {} }; void lineDirective( ostream &out, char *fileName, int line ); -- 2.7.4