Machine preparation and code generation is now handled by two virtual functions
authorthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Thu, 1 Feb 2007 05:46:06 +0000 (05:46 +0000)
committerthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Thu, 1 Feb 2007 05:46:06 +0000 (05:46 +0000)
in FsmCodeGen: finishRagelDef and writeStatement. All interpretation of the
write statement will happen there.

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

ragel/rlscan.rl
rlcodegen/fsmcodegen.cpp
rlcodegen/fsmcodegen.h
rlcodegen/gendata.cpp
rlcodegen/gendata.h
rlcodegen/xmlparse.kh
rlcodegen/xmlparse.kl

index 0784730..004f4d0 100644 (file)
@@ -302,8 +302,11 @@ void Scanner::token( int type )
                        {
                                scan_error() << "unknown write command" << endl;
                        }
-                       output << "<write def_name=\"" << parser->sectionName << 
-                                       "\" what=\"" << tokdata << "\">";
+
+                       if ( machineSpec == 0 && machineName == 0 ) {
+                               output << "<write def_name=\"" << parser->sectionName << 
+                                               "\" what=\"" << tokdata << "\">";
+                       }
                }
        }
 
@@ -314,7 +317,7 @@ void Scanner::token( int type )
        }
        action write_close
        {
-               if ( active )
+               if ( active && machineSpec == 0 && machineName == 0 )
                        output << "</write>\n";
        }
 
index 4de1720..39c2623 100644 (file)
@@ -123,7 +123,6 @@ CodeGenData *makeCodeGen( char *fileName, char *fsmName, ostream &out, bool want
        codeGen->fileName = fileName;
        codeGen->fsmName = fsmName;
        codeGen->wantComplete = wantComplete;
-       codeGen->codeGen = codeGen;
 
        return codeGen;
 }
@@ -848,76 +847,72 @@ void FsmCodeGen::prepareMachine()
        analyzeMachine();
 
        /* Determine if we should use indicies. */
-       codeGen->calcIndexSize();
+       calcIndexSize();
 }
 
-void FsmCodeGen::generateGraphviz()
+void FsmCodeGen::finishRagelDef()
 {
-       /* Do ordering and choose state ids. */
-       redFsm->depthFirstOrdering();
-       redFsm->sequentialStateIds();
-
-       /* For dot file generation we want to pick default transitions. */
-       redFsm->chooseDefaultSpan();
+       if ( outputFormat == OutCode ) {
+               prepareMachine();
+       }
+       else if ( outputFormat == OutGraphvizDot && !graphvizDone ) {
+               graphvizDone = true;
 
-       /* Make the generator. */
-       GraphvizDotGen dotGen( fsmName, this, redFsm, out );
+               /* Do ordering and choose state ids. */
+               redFsm->depthFirstOrdering();
+               redFsm->sequentialStateIds();
 
-       /* Write out with it. */
-       dotGen.writeDotFile();
-}
+               /* For dot file generation we want to pick default transitions. */
+               redFsm->chooseDefaultSpan();
 
-void FsmCodeGen::generateCode()
-{
-       if ( writeOps & WO_NOEND )
-               hasEnd = false;
+               /* Make the generator. */
+               GraphvizDotGen dotGen( fsmName, this, redFsm, out );
 
-       if ( writeOps & WO_NOERROR )
-               writeErr = false;
-
-       if ( writeOps & WO_NOPREFIX )
-               dataPrefix = false;
-       
-       if ( writeOps & WO_NOFF )
-               writeFirstFinal = false;
+               /* Write out with it. */
+               dotGen.writeDotFile();
+       }
+}
 
-       if ( writeData || writeInit || writeExec || writeEOF ) {
-               prepareMachine();
+void FsmCodeGen::writeStatement( char *what, int nopts, char **options )
+{
+       /* Read the options. FIXME: These should be parsed according to each
+        * particualr function below. */
+       for ( int i = 0; i < nopts; i++ ) {
+               if ( strcmp( options[i], "noend" ) == 0 )
+                       hasEnd = false;
+               else if ( strcmp( options[i], "noerror" ) == 0 )
+                       writeErr = false;
+               else if ( strcmp( options[i], "noprefix" ) == 0 )
+                       dataPrefix = false;
+               else if ( strcmp( options[i], "nofinal" ) == 0 )
+                       writeFirstFinal = false;
+               else {
+                       //warning($1->loc) << "unrecognized write option" << endl;
+               }
+       }
 
+       if ( outputFormat == OutCode ) {
                /* 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();
+               if ( strcmp( what, "data" ) == 0 ) {
+                       writeOutData();
+               }
+               else if ( strcmp( what, "init" ) == 0 ) {
+                       writeOutInit();
+               }
+               else if ( strcmp( what, "exec" ) == 0 ) {
+                       /* Must set labels immediately before writing because we may depend
+                        * on the noend write option. */
+                       setLabelsNeeded();
+                       writeOutExec();
+               }
+               else if ( strcmp( what, "eof" ) == 0 ) {
+                       writeOutEOF();
+               }
+               else {
+                       /* EMIT An error here. */
                }
        }
 }
-
index db8f0e8..efb794d 100644 (file)
@@ -177,11 +177,10 @@ protected:
        bool useIndicies;
 
 public:
-       void generateGraphviz();
        void prepareMachine();
-       void generateCode();
 
-       virtual void generate();
+       virtual void finishRagelDef();
+       void writeStatement( char *what, int nopts, char **options );
 
        /* Determine if we should use indicies. */
        virtual void calcIndexSize() {}
index be419c9..7fa38f1 100644 (file)
@@ -43,13 +43,7 @@ CodeGenData::CodeGenData( ostream &out )
        getKeyExpr(0),
        accessExpr(0),
        curStateExpr(0),
-       codeGen(0),
        wantComplete(0),
-       writeOps(0),
-       writeData(false),
-       writeInit(false),
-       writeExec(false),
-       writeEOF(false),
        hasLongestMatch(false),
        hasEnd(true),
        dataPrefix(true),
@@ -227,8 +221,7 @@ void CodeGenData::resolveTargetStates( InlineList *inlineList )
        }
 }
 
-
-void CodeGenData::finishMachine()
+void CodeGenData::closeMachine()
 {
        if ( redFsm->forcedErrorState )
                redFsm->getErrorState();
@@ -245,11 +238,9 @@ void CodeGenData::finishMachine()
         * state a default transition. All machines break out of the processing
         * loop when in the error state. */
 
-       if ( codeStyle == GenGoto || codeStyle == GenFGoto || codeStyle == GenIpGoto ) {
-               for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
-                       for ( StateCondList::Iter sci = st->stateCondList; sci.lte(); sci++ )
-                               st->stateCondVect.append( sci );
-               }
+       for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+               for ( StateCondList::Iter sci = st->stateCondList; sci.lte(); sci++ )
+                       st->stateCondVect.append( sci );
        }
 }
 
index 0dd24a3..8418a8e 100644 (file)
@@ -39,11 +39,6 @@ struct CodeGenData;
 typedef AvlMap<char *, CodeGenData*, CmpStr> CodeGenMap;
 typedef AvlMapEl<char *, CodeGenData*> CodeGenMapEl;
 
-#define WO_NOEND    0x01
-#define WO_NOERROR  0x02
-#define WO_NOPREFIX 0x04
-#define WO_NOFF     0x08
-
 struct CodeGenData
 {
        CodeGenData( ostream &out );
@@ -70,14 +65,8 @@ struct CodeGenData
        InlineList *getKeyExpr;
        InlineList *accessExpr;
        InlineList *curStateExpr;
-       FsmCodeGen *codeGen;
        KeyOps thisKeyOps;
        bool wantComplete;
-       int writeOps;
-       bool writeData;
-       bool writeInit;
-       bool writeExec;
-       bool writeEOF;
        EntryIdVect entryPointIds;
        EntryNameVect entryPointNames;
        bool hasLongestMatch;
@@ -102,9 +91,9 @@ struct CodeGenData
        void finishTransList( int snum );
        void setStateActions( int snum, long toStateAction, 
                        long fromStateAction, long eofAction );
-       void finishMachine();
        void setForcedErrorState()
                { redFsm->forcedErrorState = true; }
+
        
        void initCondSpaceList( ulong length );
        void condSpaceItem( int cnum, long condActionId );
@@ -127,13 +116,15 @@ struct CodeGenData
        void findFinalActionRefs();
        void analyzeMachine();
 
+       void closeMachine();
        void setValueLimits();
        void assignActionIds();
        void prepareMachine();
        bool hasBeenPrepared;
 
        /* The interface to the code generator. */
-       virtual void generate() {}
+       virtual void finishRagelDef() {}
+       virtual void writeStatement( char *what, int nopts, char **options ) {}
 };
 
 void lineDirective( ostream &out, char *fileName, int line );
index 45c41b8..ffaf8f8 100644 (file)
@@ -111,6 +111,8 @@ struct Parser
 
        CodeGenData *cgd;
        CodeGenMap codeGenMap;
+
+       Vector <char*> writeOptions;
 };
 
 %% write token_defs;
index 386b7df..5ae28a0 100644 (file)
@@ -113,7 +113,11 @@ tag_host:
                        *outStream << $3->tag->content;
        };
 
-ragel_def: tag_ragel_def_head ragel_def_item_list '/' TAG_ragel_def;
+ragel_def: 
+       tag_ragel_def_head ragel_def_item_list '/' TAG_ragel_def
+       final {
+               cgd->finishRagelDef();
+       };
 
 tag_ragel_def_head: TAG_ragel_def 
        final {
@@ -174,17 +178,9 @@ tag_write: tag_write_head write_option_list '/' TAG_write
                        error($1->loc) << "tag <write> requires a what attribute" << endl;
                }
                else {
-                       if ( strcmp( what->value, "data" ) == 0 )
-                               cgd->writeData = true;
-                       else if ( strcmp( what->value, "init" ) == 0 )
-                               cgd->writeInit = true;
-                       else if ( strcmp( what->value, "exec" ) == 0 )
-                               cgd->writeExec = true;
-                       else if ( strcmp( what->value, "eof" ) == 0 )
-                               cgd->writeEOF = true;
-
-                       if ( gblErrorCount == 0 )
-                               cgd->generate();
+                       writeOptions.append(0);
+                       cgd->writeStatement( what->value, writeOptions.length()-1, writeOptions.data );
+                       writeOptions.empty();
                }
        };
 
@@ -206,10 +202,6 @@ tag_write_head: TAG_write
                        cgd = mapEl->value;
                }
 
-               cgd->writeData = false;
-               cgd->writeInit = false;
-               cgd->writeExec = false;
-               cgd->writeEOF = false;
                ::keyOps = &cgd->thisKeyOps;
 
                $$->tag = $1->tag;
@@ -220,25 +212,19 @@ tag_write_head: TAG_write
 write_option_list: write_option_list tag_option;
 write_option_list: ;
 
+nonterm tag_option
+{
+       char *option;
+};
+
 tag_option: TAG_option '/' TAG_option
        final {
-               char *content = $3->tag->content;
-               if ( strcmp( content, "noend" ) == 0 )
-                       cgd->writeOps |= WO_NOEND;
-               else if ( strcmp( content, "noerror" ) == 0 )
-                       cgd->writeOps |= WO_NOERROR;
-               else if ( strcmp( content, "noprefix" ) == 0 )
-                       cgd->writeOps |= WO_NOPREFIX;
-               else if ( strcmp( content, "nofinal" ) == 0 )
-                       cgd->writeOps |= WO_NOFF;
-               else {
-                       warning($1->loc) << "unrecognized write option" << endl;
-               }
+               writeOptions.append( $3->tag->content );
        };
 
 tag_machine: tag_machine_head machine_item_list '/' TAG_machine
        final {
-               cgd->finishMachine();
+               cgd->closeMachine();
        };
 
 tag_machine_head: TAG_machine