Moved code dependent on the output type and code style from CodeGenData to
authorthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Thu, 1 Feb 2007 00:02:59 +0000 (00:02 +0000)
committerthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Thu, 1 Feb 2007 00:02:59 +0000 (00:02 +0000)
FsmCodeGen.

git-svn-id: http://svn.complang.org/ragel/trunk@45 052ea7fc-9027-0410-9066-f65837a77df0

rlcodegen/fsmcodegen.cpp
rlcodegen/fsmcodegen.h
rlcodegen/gendata.cpp
rlcodegen/gendata.h

index cc2051c..4de1720 100644 (file)
@@ -25,6 +25,7 @@
 #include "fsmcodegen.h"
 #include "redfsm.h"
 #include "gendata.h"
+#include "gvdotgen.h"
 #include <sstream>
 #include <string>
 #include <assert.h>
@@ -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();
+               }
+       }
+}
+
index 007fc1f..db8f0e8 100644 (file)
@@ -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() {}
 };
index dd1ae06..be419c9 100644 (file)
@@ -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 )
 {
index 0c59db7..0dd24a3 100644 (file)
@@ -47,6 +47,7 @@ typedef AvlMapEl<char *, CodeGenData*> 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 );