Introcuded the "eof" variable for indicating the end of file. The p variable is
authorthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Mon, 24 Sep 2007 19:02:37 +0000 (19:02 +0000)
committerthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Mon, 24 Sep 2007 19:02:37 +0000 (19:02 +0000)
checked against eof when the processing loop is broken out of due to p == pe.
If p == eof at this time then the EOF actions are executed. The variable is
required only when EOF actions have been emebedded.

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

30 files changed:
rlgen-cd/fflatcodegen.cpp
rlgen-cd/fgotocodegen.cpp
rlgen-cd/flatcodegen.cpp
rlgen-cd/fsmcodegen.cpp
rlgen-cd/fsmcodegen.h
rlgen-cd/ftabcodegen.cpp
rlgen-cd/gotocodegen.cpp
rlgen-cd/ipgotocodegen.cpp
rlgen-cd/tabcodegen.cpp
rlgen-java/javacodegen.cpp
rlgen-java/javacodegen.h
rlgen-ruby/ruby-codegen.cpp
rlgen-ruby/ruby-codegen.h
rlgen-ruby/ruby-fflatcodegen.cpp
rlgen-ruby/ruby-flatcodegen.cpp
rlgen-ruby/ruby-ftabcodegen.cpp
rlgen-ruby/ruby-tabcodegen.cpp
test/checkeofact.txl [new file with mode: 0644]
test/element1.rl
test/element2.rl
test/element3.rl
test/erract3.rl
test/erract4.rl
test/high1.rl
test/langtrans_c.sh
test/langtrans_d.sh
test/langtrans_java.sh
test/langtrans_ruby.sh
test/runtests
test/testcase.txl

index 340b344..915dc8d 100644 (file)
@@ -231,6 +231,7 @@ void FFlatCodeGen::writeData()
 
 void FFlatCodeGen::writeExec()
 {
+       testEofUsed = false;
        outLabelUsed = false;
 
        out << 
@@ -259,10 +260,10 @@ void FFlatCodeGen::writeExec()
        }
 
        if ( hasEnd ) {
-               outLabelUsed = true;
+               testEofUsed = true;
                out << 
                        "       if ( " << P() << " == " << PE() << " )\n"
-                       "               goto _out;\n";
+                       "               goto _test_eof;\n";
        }
 
        if ( redFsm->errState != 0 ) {
@@ -337,16 +338,12 @@ void FFlatCodeGen::writeExec()
                        "       goto _resume;\n";
        }
 
-       if ( outLabelUsed )
-               out << "        _out: {}\n";
+       if ( testEofUsed )
+               out << "        _test_eof: {}\n";
 
-       out << "        }\n";
-}
-
-void FFlatCodeGen::writeEOF()
-{
        if ( redFsm->anyEofActions() ) {
                out <<
+                       "       if ( " << P() << " == " << EOFV() << " )\n"
                        "       {\n"
                        "       switch ( " << EA() << "[" << CS() << "] ) {\n";
                        EOF_ACTION_SWITCH();
@@ -355,4 +352,13 @@ void FFlatCodeGen::writeEOF()
                        "       }\n"
                        "\n";
        }
+
+       if ( outLabelUsed )
+               out << "        _out: {}\n";
+
+       out << "        }\n";
+}
+
+void FFlatCodeGen::writeEOF()
+{
 }
index a6b0d02..31aa5d2 100644 (file)
@@ -178,6 +178,7 @@ void FGotoCodeGen::writeData()
 
 void FGotoCodeGen::writeExec()
 {
+       testEofUsed = false;
        outLabelUsed = false;
 
        out << "        {\n";
@@ -189,10 +190,10 @@ void FGotoCodeGen::writeExec()
                out << "        " << WIDE_ALPH_TYPE() << " _widec;\n";
 
        if ( hasEnd ) {
-               outLabelUsed = true;
+               testEofUsed = true;
                out << 
                        "       if ( " << P() << " == " << PE() << " )\n"
-                       "               goto _out;\n";
+                       "               goto _test_eof;\n";
        }
 
        if ( redFsm->errState != 0 ) {
@@ -254,17 +255,12 @@ void FGotoCodeGen::writeExec()
                        "       goto _resume;\n";
        }
 
+       if ( testEofUsed )
+               out << "        _test_eof: {}\n";
 
-       if ( outLabelUsed )
-               out << "        _out: {}\n";
-
-       out << "        }\n";
-}
-
-void FGotoCodeGen::writeEOF()
-{
        if ( redFsm->anyEofActions() ) {
                out <<
+                       "       if ( " << P() << " == " << EOFV() << " )\n"
                        "       {\n"
                        "       switch ( " << EA() << "[" << CS() << "] ) {\n";
                        EOF_ACTION_SWITCH();
@@ -273,4 +269,13 @@ void FGotoCodeGen::writeEOF()
                        "       }\n"
                        "\n";
        }
+
+       if ( outLabelUsed )
+               out << "        _out: {}\n";
+
+       out << "        }\n";
+}
+
+void FGotoCodeGen::writeEOF()
+{
 }
index 36fb0d9..ad52279 100644 (file)
@@ -641,6 +641,7 @@ void FlatCodeGen::COND_TRANSLATE()
 
 void FlatCodeGen::writeExec()
 {
+       testEofUsed = false;
        outLabelUsed = false;
 
        out << 
@@ -679,10 +680,10 @@ void FlatCodeGen::writeExec()
        out << "\n";
 
        if ( hasEnd ) {
-               outLabelUsed = true;
+               testEofUsed = true;
                out << 
                        "       if ( " << P() << " == " << PE() << " )\n"
-                       "               goto _out;\n";
+                       "               goto _test_eof;\n";
        }
 
        if ( redFsm->errState != 0 ) {
@@ -770,22 +771,18 @@ void FlatCodeGen::writeExec()
                        "       goto _resume;\n";
        }
 
-       if ( outLabelUsed )
-               out << "        _out: {}\n";
+       if ( testEofUsed )
+               out << "        _test_eof: {}\n";
 
-       out << "        }\n";
-}
-
-void FlatCodeGen::writeEOF()
-{
        if ( redFsm->anyEofActions() ) {
                out << 
+                       "       if ( " << P() << " == " << EOFV() << " )\n"
                        "       {\n"
-                       "       " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << POINTER() << "_acts = " << 
+                       "       " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << POINTER() << "__acts = " << 
                                        ARR_OFF( A(), EA() + "[" + CS() + "]" ) << ";\n"
-                       "       " << UINT() << " _nacts = " << CAST(UINT()) << " *_acts++;\n"
-                       "       while ( _nacts-- > 0 ) {\n"
-                       "               switch ( *_acts++ ) {\n";
+                       "       " << UINT() << " __nacts = " << CAST(UINT()) << " *__acts++;\n"
+                       "       while ( __nacts-- > 0 ) {\n"
+                       "               switch ( *__acts++ ) {\n";
                        EOF_ACTION_SWITCH();
                        SWITCH_DEFAULT() <<
                        "               }\n"
@@ -793,4 +790,14 @@ void FlatCodeGen::writeEOF()
                        "       }\n"
                        "\n";
        }
+
+
+       if ( outLabelUsed )
+               out << "        _out: {}\n";
+
+       out << "        }\n";
+}
+
+void FlatCodeGen::writeEOF()
+{
 }
index 1fbeba5..a9bff77 100644 (file)
@@ -171,6 +171,19 @@ string FsmCodeGen::PE()
        return ret.str();
 }
 
+string FsmCodeGen::EOFV()
+{
+       ostringstream ret;
+//     if ( peExpr == 0 )
+               ret << "eof";
+//     else {
+//             ret << "(";
+//             INLINE_LIST( ret, peExpr, 0, false );
+//             ret << ")";
+//     }
+       return ret.str();
+}
+
 string FsmCodeGen::CS()
 {
        ostringstream ret;
index 1bd0a24..9a82169 100644 (file)
@@ -92,6 +92,7 @@ protected:
 
        string P();
        string PE();
+       string EOFV();
 
        string ACCESS();
        string CS();
@@ -166,6 +167,7 @@ protected:
        unsigned int arrayTypeSize( unsigned long maxVal );
 
        bool outLabelUsed;
+       bool testEofUsed;
        bool againLabelUsed;
        bool useIndicies;
 
index 9e377a3..d8e1ba8 100644 (file)
@@ -285,6 +285,7 @@ void FTabCodeGen::writeData()
 
 void FTabCodeGen::writeExec()
 {
+       testEofUsed = false;
        outLabelUsed = false;
 
        out << 
@@ -305,10 +306,10 @@ void FTabCodeGen::writeExec()
        out << "\n";
 
        if ( hasEnd ) {
-               outLabelUsed = true;
+               testEofUsed = true;
                out <<
                        "       if ( " << P() << " == " << PE() << " )\n"
-                       "               goto _out;\n";
+                       "               goto _test_eof;\n";
        }
 
        if ( redFsm->errState != 0 ) {
@@ -389,18 +390,12 @@ void FTabCodeGen::writeExec()
                        "       goto _resume;\n";
        }
 
+       if ( testEofUsed )
+               out << "        _test_eof: {}\n";
 
-       if ( outLabelUsed )
-               out << "        _out: {}\n";
-
-       out << "        }\n";
-}
-
-
-void FTabCodeGen::writeEOF()
-{
        if ( redFsm->anyEofActions() ) {
                out <<
+                       "       if ( " << P() << " == " << EOFV() << " )\n"
                        "       {\n"
                        "       switch ( " << EA() << "[" << CS() << "] ) {\n";
                        EOF_ACTION_SWITCH();
@@ -409,4 +404,14 @@ void FTabCodeGen::writeEOF()
                        "       }\n"
                        "\n";
        }
+
+       if ( outLabelUsed )
+               out << "        _out: {}\n";
+
+       out << "        }\n";
+}
+
+
+void FTabCodeGen::writeEOF()
+{
 }
index 89f3107..51a4c16 100644 (file)
@@ -659,6 +659,7 @@ void GotoCodeGen::writeData()
 
 void GotoCodeGen::writeExec()
 {
+       testEofUsed = false;
        outLabelUsed = false;
 
        out << "        {\n";
@@ -680,10 +681,10 @@ void GotoCodeGen::writeExec()
        out << "\n";
 
        if ( hasEnd ) {
-               outLabelUsed = true;
+               testEofUsed = true;
                out << 
                        "       if ( " << P() << " == " << PE() << " )\n"
-                       "               goto _out;\n";
+                       "               goto _test_eof;\n";
        }
 
        if ( redFsm->errState != 0 ) {
@@ -753,22 +754,18 @@ void GotoCodeGen::writeExec()
                        "       goto _resume;\n";
        }
 
-       if ( outLabelUsed )
-               out << "        _out: {}\n";
-
-       out << "        }\n";
-}
+       if ( testEofUsed )
+               out << "        _test_eof: {}\n";
 
-void GotoCodeGen::writeEOF()
-{
        if ( redFsm->anyEofActions() ) {
                out << 
+                       "       if ( " << P() << " == " << EOFV() << " )\n"
                        "       {\n"
-                       "       " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << POINTER() << "_acts = " << 
+                       "       " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << POINTER() << "__acts = " << 
                                        ARR_OFF( A(), EA() + "[" + CS() + "]" ) << ";\n"
-                       "       " << UINT() << " _nacts = " << CAST(UINT()) << " *_acts++;\n"
-                       "       while ( _nacts-- > 0 ) {\n"
-                       "               switch ( *_acts++ ) {\n";
+                       "       " << UINT() << " __nacts = " << CAST(UINT()) << " *__acts++;\n"
+                       "       while ( __nacts-- > 0 ) {\n"
+                       "               switch ( *__acts++ ) {\n";
                        EOF_ACTION_SWITCH();
                        SWITCH_DEFAULT() <<
                        "               }\n"
@@ -776,4 +773,13 @@ void GotoCodeGen::writeEOF()
                        "       }\n"
                        "\n";
        }
+
+       if ( outLabelUsed )
+               out << "        _out: {}\n";
+
+       out << "        }\n";
+}
+
+void GotoCodeGen::writeEOF()
+{
 }
index d7cb931..025781f 100644 (file)
@@ -112,7 +112,7 @@ void IpGotoCodeGen::TARGS( ostream &ret, bool inFinish, int targState )
 
 void IpGotoCodeGen::BREAK( ostream &ret, int targState )
 {
-       ret << CTRL_FLOW() << "goto _out" << targState << ";";
+       ret << "{" << CS() << " = " << targState << "; " << CTRL_FLOW() << "goto _out;}";
 }
 
 bool IpGotoCodeGen::IN_TRANS_ACTIONS( RedStateAp *state )
@@ -172,7 +172,7 @@ void IpGotoCodeGen::GOTO_HEADER( RedStateAp *state )
                if ( hasEnd ) {
                        out <<
                                "       if ( ++" << P() << " == " << PE() << " )\n"
-                               "               goto _out" << state->id << ";\n";
+                               "               goto _test_eof" << state->id << ";\n";
                }
                else {
                        out << 
@@ -213,7 +213,9 @@ void IpGotoCodeGen::STATE_GOTO_ERROR()
                out << "st" << state->id << ":\n";
 
        /* Break out here. */
-       out << "        goto _out" << state->id << ";\n";
+       outLabelUsed = true;
+       out << CS() << " = " << state->id << ";\n";
+       out << "        goto _out;\n";
 }
 
 
@@ -235,9 +237,9 @@ std::ostream &IpGotoCodeGen::EXIT_STATES()
 {
        for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
                if ( st->outNeeded ) {
-                       outLabelUsed = true;
-                       out << "        _out" << st->id << ": " << CS() << " = " << 
-                                       st->id << "; goto _out; \n";
+                       testEofUsed = true;
+                       out << "        _test_eof" << st->id << ": " << CS() << " = " << 
+                                       st->id << "; goto _test_eof; \n";
                }
        }
        return out;
@@ -336,18 +338,9 @@ void IpGotoCodeGen::setLabelsNeeded()
        }
 
        if ( hasEnd ) {
-               for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ )
-                       st->outNeeded = st->labelNeeded;
-       }
-       else {
-               if ( redFsm->errState != 0 )
-                       redFsm->errState->outNeeded = true;
-
-               for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ ) {
-                       /* Any state with a transition in that has a break will need an
-                        * out label. */
-                       if ( trans->action != 0 && trans->action->anyBreakStmt() )
-                               trans->targ->outNeeded = true;
+               for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
+                       if ( st != redFsm->errState )
+                               st->outNeeded = st->labelNeeded;
                }
        }
 }
@@ -362,6 +355,7 @@ void IpGotoCodeGen::writeExec()
        /* Must set labels immediately before writing because we may depend on the
         * noend write option. */
        setLabelsNeeded();
+       testEofUsed = false;
        outLabelUsed = false;
 
        out << "        {\n";
@@ -373,10 +367,10 @@ void IpGotoCodeGen::writeExec()
                out << "        " << WIDE_ALPH_TYPE() << " _widec;\n";
 
        if ( hasEnd ) {
-               outLabelUsed = true;
+               testEofUsed = true;
                out << 
                        "       if ( " << P() << " == " << PE() << " )\n"
-                       "               goto _out;\n";
+                       "               goto _test_eof;\n";
        }
 
        if ( useAgainLabel() ) {
@@ -391,10 +385,10 @@ void IpGotoCodeGen::writeExec()
                        "\n";
 
                if ( hasEnd ) {
-                       outLabelUsed = true;
+                       testEofUsed = true;
                        out << 
                                "       if ( ++" << P() << " == " << PE() << " )\n"
-                               "               goto _out;\n";
+                               "               goto _test_eof;\n";
                }
                else {
                        out << 
@@ -412,17 +406,12 @@ void IpGotoCodeGen::writeExec()
                EXIT_STATES() << 
                "\n";
 
-       if ( outLabelUsed ) 
-               out << "        _out: {}\n";
-
-       out <<
-               "       }\n";
-}
+       if ( testEofUsed ) 
+               out << "        _test_eof: {}\n";
 
-void IpGotoCodeGen::writeEOF()
-{
        if ( redFsm->anyEofActions() ) {
                out <<
+                       "       if ( " << P() << " == " << EOFV() << " )\n"
                        "       {\n"
                        "       switch ( " << CS() << " ) {\n";
                        FINISH_CASES();
@@ -431,4 +420,14 @@ void IpGotoCodeGen::writeEOF()
                        "       }\n"
                        "\n";
        }
+
+       if ( outLabelUsed ) 
+               out << "        _out: {}\n";
+
+       out <<
+               "       }\n";
+}
+
+void IpGotoCodeGen::writeEOF()
+{
 }
index 7dccb4d..78f8a26 100644 (file)
@@ -867,6 +867,7 @@ void TabCodeGen::COND_TRANSLATE()
 
 void TabCodeGen::writeExec()
 {
+       testEofUsed = false;
        outLabelUsed = false;
 
        out <<
@@ -896,10 +897,10 @@ void TabCodeGen::writeExec()
                "\n";
 
        if ( hasEnd ) {
-               outLabelUsed = true;
+               testEofUsed = true;
                out << 
                        "       if ( " << P() << " == " << PE() << " )\n"
-                       "               goto _out;\n";
+                       "               goto _test_eof;\n";
        }
 
        if ( redFsm->errState != 0 ) {
@@ -992,23 +993,18 @@ void TabCodeGen::writeExec()
                        "       goto _resume;\n";
        }
        
-       if ( outLabelUsed )
-               out << "        _out: {}\n";
-
-       out << "        }\n";
-}
-
-
-void TabCodeGen::writeEOF()
-{
+       if ( testEofUsed )
+               out << "        _test_eof: {}\n";
+       
        if ( redFsm->anyEofActions() ) {
                out << 
+                       "       if ( " << P() << " == " << EOFV() << " )\n"
                        "       {\n"
-                       "       " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << POINTER() << "_acts = " << 
-                                       ARR_OFF( A(), EA() + "[" + CS() + "]" ) << ";\n"
-                       "       " << UINT() << " _nacts = " << CAST(UINT()) << " *_acts++;\n"
-                       "       while ( _nacts-- > 0 ) {\n"
-                       "               switch ( *_acts++ ) {\n";
+                       "       " << PTR_CONST() << ARRAY_TYPE(redFsm->maxActArrItem) << 
+                                       POINTER() << "__acts = " << ARR_OFF( A(), EA() + "[" + CS() + "]" ) << ";\n"
+                       "       " << UINT() << " __nacts = " << CAST(UINT()) << " *__acts++;\n"
+                       "       while ( __nacts-- > 0 ) {\n"
+                       "               switch ( *__acts++ ) {\n";
                        EOF_ACTION_SWITCH();
                        SWITCH_DEFAULT() <<
                        "               }\n"
@@ -1016,4 +1012,14 @@ void TabCodeGen::writeEOF()
                        "       }\n"
                        "\n";
        }
+
+       if ( outLabelUsed )
+               out << "        _out: {}\n";
+
+       out << "        }\n";
+}
+
+
+void TabCodeGen::writeEOF()
+{
 }
index 9b65c95..a8d5529 100644 (file)
@@ -919,6 +919,7 @@ void JavaTabCodeGen::writeExec()
 {
        out <<
                "       {\n"
+               "       boolean testEof = false;\n"
                "       int _klen";
 
        if ( redFsm->anyRegCurStateRef() )
@@ -1019,8 +1020,10 @@ void JavaTabCodeGen::writeExec()
 
        if ( hasEnd ) {
                out << 
-                       "       if ( ++" << P() << " == " << PE() << " )\n"
-                       "               break _resume;\n";
+                       "       if ( ++" << P() << " == " << PE() << " ) {\n"
+                       "               testEof = true;\n"
+                       "               break _resume;\n"
+                       "       }\n";
        }
        else {
                out << 
@@ -1035,26 +1038,34 @@ void JavaTabCodeGen::writeExec()
                out << "        }";
 
        /* The if guarding on empty string. */
-       if ( hasEnd )
-               out << "        }\n";
-
-       /* The execute block. */
-       out << "        }\n";
-}
+       if ( hasEnd ) {
+               out << 
+                       "       }\n"
+                       "       else"
+                       "               testEof = true;\n";
+       }
 
-void JavaTabCodeGen::writeEOF()
-{
        if ( redFsm->anyEofActions() ) {
                out <<
-                       "       int _acts = " << EA() << "[" << CS() << "]" << ";\n"
-                       "       int _nacts = " << CAST("int") << " " << A() << "[_acts++];\n"
-                       "       while ( _nacts-- > 0 ) {\n"
-                       "               switch ( " << A() << "[_acts++] ) {\n";
+                       "       if ( testEof && " << P() << " == " << EOFV() << " )\n"
+                       "       {\n"
+                       "       int __acts = " << EA() << "[" << CS() << "]" << ";\n"
+                       "       int __nacts = " << CAST("int") << " " << A() << "[__acts++];\n"
+                       "       while ( __nacts-- > 0 ) {\n"
+                       "               switch ( " << A() << "[__acts++] ) {\n";
                        EOF_ACTION_SWITCH() <<
                        "               }\n"
                        "       }\n"
+                       "       }\n"
                        "\n";
        }
+
+       /* The execute block. */
+       out << "        }\n";
+}
+
+void JavaTabCodeGen::writeEOF()
+{
 }
 
 std::ostream &JavaTabCodeGen::OPEN_ARRAY( string type, string name )
@@ -1245,6 +1256,19 @@ string JavaTabCodeGen::PE()
        return ret.str();
 }
 
+string JavaTabCodeGen::EOFV()
+{
+       ostringstream ret;
+//     if ( peExpr == 0 )
+               ret << "eof";
+//     else {
+//             ret << "(";
+//             INLINE_LIST( ret, peExpr, 0, false );
+//             ret << ")";
+//     }
+       return ret.str();
+}
+
 string JavaTabCodeGen::CS()
 {
        ostringstream ret;
index c63c907..d12af94 100644 (file)
@@ -127,6 +127,8 @@ public:
 
        string P();
        string PE();
+       string EOFV();
+
        string CS();
        string STACK();
        string TOP();
index e926ca3..ad19a38 100644 (file)
@@ -127,6 +127,19 @@ string RubyCodeGen::PE()
        return ret.str();
 }
 
+string RubyCodeGen::EOFV()
+{
+       ostringstream ret;
+//     if ( peExpr == 0 )
+               ret << "eof";
+//     else {
+//             //ret << "(";
+//             INLINE_LIST( ret, peExpr, 0, false );
+//             //ret << ")";
+//     }
+       return ret.str();
+}
+
 string RubyCodeGen::CS()
 {
        ostringstream ret;
index 9f4c166..d3c3e01 100644 (file)
@@ -105,6 +105,8 @@ public:
 
        string P();
        string PE();
+       string EOFV();
+
        string CS();
        string TOP();
        string STACK();
index b8abdde..dd5ef8a 100644 (file)
@@ -218,6 +218,7 @@ void RubyFFlatCodeGen::writeExec()
 {
        out << 
                "begin # ragel fflat\n"
+               "       testEof = false\n"
                "       _slen, _trans, _keys, _inds";
        if ( redFsm->anyRegCurStateRef() )
                out << ", _ps";
@@ -294,9 +295,13 @@ void RubyFFlatCodeGen::writeExec()
 
        out << "        " << P() << " += 1\n";
 
-       if ( hasEnd )
-               out << "        break if " << P() << " == " << PE() << "\n";
-
+       if ( hasEnd ) {
+               out << 
+                       "       if " << P() << " == " << PE() << "\n"
+                       "               testEof = true\n"
+                       "               break\n"
+                       "       end\n";
+       }
        
        out << /* Close the _resume loop. */
                "       end # _resume loop\n";
@@ -305,27 +310,33 @@ void RubyFFlatCodeGen::writeExec()
                out << "        end # errstate guard\n";
 
        
-       if ( hasEnd )
-               out << "        end # pe guard\n";
-
-       out << "end # ragel fflat";
-
-}
-
+       if ( hasEnd ) {
+               out << 
+                       "       # close if guarding empty string \n"
+                       "       else\n"
+                       "               testEof = true\n"
+                       "       end\n";
+       }
 
-void RubyFFlatCodeGen::writeEOF()
-{
        if ( redFsm->anyEofActions() ) {
                out <<
+                       "       if testEof && " << P() << " == " << EOFV() << "\n"
                        "         case " << EA() << "[" << CS() << "]\n";
                EOF_ACTION_SWITCH();
                out <<
                        "         end # eof action switch \n"
+                       "       end\n"
                        "\n";
        }
+
+       out << "end # ragel fflat";
 }
 
 
+void RubyFFlatCodeGen::writeEOF()
+{
+}
+
 /*
  * Local Variables:
  * mode: c++
index 9bbed39..e29aea0 100644 (file)
@@ -622,29 +622,13 @@ void RubyFlatCodeGen::writeData()
 
 void RubyFlatCodeGen::writeEOF()
 {
-       if ( redFsm->anyEofActions() ) {
-               out << 
-                       "       begin\n"
-                       "       " << "_acts = " << EA() << "[" << CS() << "]\n"
-                       "       _nacts = " << A() << "[_acts]\n" << 
-                       "       _acts += 1\n"
-                       "       while ( _nacts > 0 ) \n"
-                       "               _nacts -= 1\n"
-                       "               _acts += 1\n"
-                       "               case ( "<< A() << "[_acts-1] ) \n";
-               EOF_ACTION_SWITCH();
-               out <<
-                       "               end # eof action switch \n"
-                       "       end\n"
-                       "       end\n"
-                       "\n";
-       }
 }
 
 void RubyFlatCodeGen::writeExec()
 {
        out << 
                "begin # ragel flat\n"
+               "       testEof = false\n"
                "       _slen, _trans, _keys, _inds";
        if ( redFsm->anyRegCurStateRef() )
                out << ", _ps";
@@ -743,9 +727,13 @@ void RubyFlatCodeGen::writeExec()
 
        out << "        " << P() << " += 1\n";
 
-       if ( hasEnd )
-               out << "        break if " << P() << " == " << PE() << "\n";
-
+       if ( hasEnd ) {
+               out << 
+                       "       if " << P() << " == " << PE() << "\n"
+                       "               testEof = true\n"
+                       "               break\n"
+                       "       end\n";
+       }
        
        out << /* Close the _resume loop. */
                "       end # _resume loop\n";
@@ -754,8 +742,33 @@ void RubyFlatCodeGen::writeExec()
                out << "        end # errstate guard\n";
 
        
-       if ( hasEnd )
-               out << "        end # pe guard\n";
+       if ( hasEnd ) {
+               out << 
+                       "       # close if guarding empty string \n"
+                       "       else\n"
+                       "               testEof = true\n"
+                       "       end\n";
+       }
+
+       if ( redFsm->anyEofActions() ) {
+               out << 
+                       "       if testEof && " << P() << " == " << EOFV() << "\n"
+                       "       begin\n"
+                       "       __acts = " << EA() << "[" << CS() << "]\n"
+                       "       __nacts = " << A() << "[__acts]\n" << 
+                       "       __acts += 1\n"
+                       "       while ( __nacts > 0 ) \n"
+                       "               __nacts -= 1\n"
+                       "               __acts += 1\n"
+                       "               case ( "<< A() << "[__acts-1] ) \n";
+               EOF_ACTION_SWITCH();
+               out <<
+                       "               end # eof action switch \n"
+                       "       end\n"
+                       "       end\n"
+                       "       end\n"
+                       "\n";
+       }
 
        out << "end # ragel flat";
 }
index fed8dad..c0a4a9f 100644 (file)
@@ -256,23 +256,14 @@ void RubyFTabCodeGen::writeData()
 
 void RubyFTabCodeGen::writeEOF()
 {
-       if ( redFsm->anyEofActions() ) {
-               out <<
-                       "       begin\n"
-                       "               case ( " << EA() << "[" << CS() << "] )\n";
-                       EOF_ACTION_SWITCH();
-               out <<
-                       "               end\n"
-                       "       end\n"
-                       "\n";
-       }
 }
 
 void RubyFTabCodeGen::writeExec()
 {
        out << 
-                "      begin # ragel ftab \n"
-               "         _klen, _trans, _keys";
+               "begin # ragel ftab\n"
+               "       testEof = false\n"
+               "       _klen, _trans, _keys";
 
        if ( redFsm->anyRegCurStateRef() )
                out << ", _ps";
@@ -362,7 +353,10 @@ void RubyFTabCodeGen::writeExec()
 
        if ( hasEnd ) {
                out << 
-                       "       break if "<< P() << " == " << PE() << " \n";
+                       "       if " << P() << " == " << PE() << "\n"
+                       "               testEof = true\n"
+                       "               break\n"
+                       "       end\n";
        }
 
        /* Close the resume loop. */
@@ -374,8 +368,26 @@ void RubyFTabCodeGen::writeExec()
                out << "        end # close if guarding error state \n";
 
        /* The if guarding on empty string. */
-       if ( hasEnd ) 
-               out << "        end # close if guarding empty string \n";
+       if ( hasEnd ) {
+               out << 
+                       "       # close if guarding empty string \n"
+                       "       else\n"
+                       "               testEof = true\n"
+                       "       end\n";
+       }
+
+       if ( redFsm->anyEofActions() ) {
+               out <<
+                       "       if testEof && " << P() << " == " << EOFV() << "\n"
+                       "       begin\n"
+                       "               case ( " << EA() << "[" << CS() << "] )\n";
+                       EOF_ACTION_SWITCH();
+               out <<
+                       "               end\n"
+                       "       end\n"
+                       "       end\n"
+                       "\n";
+       }
 
        /* Wrapping the execute block. */
        out << "        end # close execution block \n";
index c307e45..acca082 100644 (file)
@@ -229,8 +229,10 @@ void RubyTabCodeGen::LOCATE_TRANS()
 
 void RubyTabCodeGen::writeExec()
 {
-       out << "begin\n"
-               << "    _klen, _trans, _keys";
+       out << 
+               "begin\n"
+               "       testEof = false\n"
+               "       _klen, _trans, _keys";
 
        if ( redFsm->anyRegCurStateRef() )
                out << ", _ps";
@@ -330,8 +332,13 @@ void RubyTabCodeGen::writeExec()
 
        out << "        " << P() << " += 1\n";
 
-       if ( hasEnd )
-               out << "        break if " << P() << " == " << PE() << "\n";
+       if ( hasEnd ) {
+               out << 
+                       "       if " << P() << " == " << PE() << "\n"
+                       "               testEof = true\n"
+                       "               break\n"
+                       "       end\n";
+       }
 
        /* Close the resume loop. */
        out << "        end\n";
@@ -341,28 +348,35 @@ void RubyTabCodeGen::writeExec()
                out << "        end\n";
 
        /* The if guarding on empty string. */
-       if ( hasEnd ) 
-               out << "        end\n";
-
-       /* Wrapping the execute block. */
-       out << "        end\n";
-}
+       if ( hasEnd ) {
+               out << 
+                       "       else\n"
+                       "               testEof = true\n"
+                       "       end\n";
+       }
 
-void RubyTabCodeGen::writeEOF()
-{
        if ( redFsm->anyEofActions() ) {
                out << 
-                       "       _acts = " << EA() << "[" << CS() << "]\n"
-                       "       _nacts = " << " " << A() << "[_acts]\n"
-                       "       _acts += 1\n"
-                       "       while _nacts > 0\n"
-                       "               _nacts -= 1\n"
-                       "               _acts += 1\n"
-                       "               case " << A() << "[_acts - 1]\n";
+                       "       if testEof && " << P() << " == " << EOFV() << "\n"
+                       "       __acts = " << EA() << "[" << CS() << "]\n"
+                       "       __nacts = " << " " << A() << "[__acts]\n"
+                       "       __acts += 1\n"
+                       "       while __nacts > 0\n"
+                       "               __nacts -= 1\n"
+                       "               __acts += 1\n"
+                       "               case " << A() << "[__acts - 1]\n";
                EOF_ACTION_SWITCH() <<
                        "               end # eof action switch\n"
+                       "       end\n"
                        "       end\n";
        }
+
+       /* Wrapping the execute block. */
+       out << "        end\n";
+}
+
+void RubyTabCodeGen::writeEOF()
+{
 }
 
 
diff --git a/test/checkeofact.txl b/test/checkeofact.txl
new file mode 100644 (file)
index 0000000..d01f788
--- /dev/null
@@ -0,0 +1,89 @@
+include "testcase.txl"
+
+define program
+               [lang_indep]
+       |       'yes
+       |       'no
+end define
+
+rule findEof1
+       match [machine_expr_item]
+               '>/
+end rule
+
+rule findEof2
+       match [machine_expr_item]
+               '</
+end rule
+
+rule findEof3
+       match [machine_expr_item]
+               '$/
+end rule
+
+rule findEof4
+       match [machine_expr_item]
+               '%/
+end rule
+
+rule findEof5
+       match [machine_expr_item]
+               '@/
+end rule
+
+rule findEof6
+       match [machine_expr_item]
+               '<>/
+end rule
+
+rule findEof7
+       match [repeat machine_expr_item]
+               '> 'eof _ [repeat machine_expr_item]
+end rule
+
+rule findEof8
+       match [repeat machine_expr_item]
+               '< 'eof _ [repeat machine_expr_item]
+end rule
+
+rule findEof9
+       match [repeat machine_expr_item]
+               '$ 'eof _ [repeat machine_expr_item]
+end rule
+
+rule findEof10
+       match [repeat machine_expr_item]
+               '% 'eof _ [repeat machine_expr_item]
+end rule
+
+rule findEof11
+       match [repeat machine_expr_item]
+               '@ 'eof _ [repeat machine_expr_item]
+end rule
+
+rule findEof12
+       match [repeat machine_expr_item]
+               '<> 'eof _ [repeat machine_expr_item]
+end rule
+
+function findEof P [program]
+       replace [program]
+               _ [program]
+       where
+               P 
+                       [findEof1] [findEof2] [findEof3]
+                       [findEof4] [findEof5] [findEof6]
+                       [findEof7] [findEof8] [findEof9]
+                       [findEof10] [findEof11] [findEof12]
+       by
+               'yes
+end function
+               
+function main
+       replace [program]
+               P [program]
+       construct NewP [program]
+               'no
+       by
+               NewP [findEof P]
+end function
index 3113058..221710f 100644 (file)
@@ -57,10 +57,11 @@ int Fsm::init( )
        return 0;
 }
 
-int Fsm::execute( LangEl *_data, int _len )
+int Fsm::execute( LangEl *data, int len )
 {
-       LangEl *p = _data;
-       LangEl *pe = _data+_len;
+       LangEl *p = data;
+       LangEl *pe = data + len;
+       LangEl *eof = pe;
        %% write exec;
 
        if ( cs == Fsm_error )
@@ -72,8 +73,6 @@ int Fsm::execute( LangEl *_data, int _len )
 
 int Fsm::finish( )
 {
-       %% write eof;
-
        if ( cs == Fsm_error )
                return -1;
        if ( cs >= Fsm_first_final )
index 28e9c3d..7aa6217 100644 (file)
@@ -41,14 +41,13 @@ void fsm_execute( struct fsm *fsm,  struct LangEl *_data, int _len )
 {
        struct LangEl *p = _data;
        struct LangEl *pe = _data+_len;
+       struct LangEl *eof = pe;
 
        %% write exec;
 }
 
 int fsm_finish( struct fsm *fsm )
 {
-       %% write eof;
-
        if ( fsm->cs == fsm_error )
                return -1;
        if ( fsm->cs >= fsm_first_final )
index 773e801..66435f4 100644 (file)
@@ -66,6 +66,7 @@ struct LangEl
 {
        struct LangEl *p = _data;
        struct LangEl *pe = _data + _len;
+       struct LangEl *eof = pe;
        %% write exec;
 
        if ( self->cs == Fsm_error ) 
@@ -75,7 +76,6 @@ struct LangEl
 
 - (int) finish;
 {
-       %% write eof;
        if ( self->cs == Fsm_error ) 
                return -1;
        return ( self->cs >= Fsm_first_final ) ? 1 : 0;
index 2cf33c0..adfe76c 100644 (file)
@@ -33,13 +33,12 @@ void erract_execute( struct erract *fsm, const char *_data, int _len )
 {
        const char *p = _data;
        const char *pe = _data+_len;
+       const char *eof = pe;
        %% write exec;
 }
 
 int erract_finish( struct erract *fsm )
 {
-       %% write eof;
-
        if ( fsm->cs == erract_error )
                return -1;
        else if ( fsm->cs >= erract_first_final )
index 1a753ef..bef1139 100644 (file)
 {
        const char *p = _data;
        const char *pe = _data + _len;
+       const char *eof = pe;
        %% write exec;
 }
 
 - (int) finish;
 {
-       %% write eof;
        if ( cs == ErrAct_error )
                return -1;
        else if ( cs >= ErrAct_first_final )
index d0edcd9..41b9d32 100644 (file)
@@ -119,14 +119,13 @@ void tokenizer_execute( struct tokenizer *fsm, const char *_data, int _len )
 {
        const char *p = _data;
        const char *pe = _data+_len;
+       const char *eof = pe;
 
        %% write exec;
 }
 
 int tokenizer_finish( struct tokenizer *fsm )
 {
-       %% write eof;
-
        if ( fsm->cs == tokenizer_error )
                return -1;
        if ( fsm->cs >= tokenizer_first_final )
index b85cc33..431ec26 100755 (executable)
@@ -11,6 +11,8 @@ machine=`sed -n 's/^[\t ]*machine[\t ]*\([a-zA-Z_0-9]*\)[\t ]*;[\t ]*$/\1/p' $fi
 # Make a temporary version of the test case using the C language translations.
 sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin langtrans_c.txl > $file.pr
 
+has_eof_act=`sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin checkeofact.txl`
+
 # Begin writing out the test case.
 cat << EOF
 /*
@@ -45,12 +47,16 @@ void exec( char *data, int len )
 {
        char *p = data;
        char *pe = data + len;
+EOF
+
+[ "$has_eof_act" = "yes" ] && echo "char *eof = pe;"
+
+cat << EOF
        %% write exec;
 }
 
 void finish( )
 {
-       %% write eof;
        if ( cs >= ${machine}_first_final )
                printf( "ACCEPT\\n" );
        else
index 6762d55..3ea9c8a 100755 (executable)
@@ -48,6 +48,7 @@ cat << EOF
        {
                char *p = data.ptr;
                char *pe = data.ptr + data.length;
+               char *eof = pe;
                char _s[];
 
                %% write exec;
@@ -55,7 +56,6 @@ cat << EOF
 
        void finish( )
        {
-               %% write eof;
                if ( cs >= ${machine}_first_final )
                        writefln( "ACCEPT" );
                else
index 2240f4a..1b82076 100755 (executable)
@@ -47,13 +47,13 @@ cat << EOF
        {
                int p = 0;
                int pe = len;
+               int eof = len;
                String _s;
                %% write exec;
        }
 
        void finish( )
        {
-               %% write eof;
                if ( cs >= ${class}_first_final )
                        System.out.println( "ACCEPT" );
                else
index ae5358a..3caa660 100755 (executable)
@@ -32,6 +32,7 @@ cat << EOF
        def run_machine( data )
                p = 0
                pe = data.length
+               eof = data.length
                cs = 0;
 EOF
 
@@ -45,7 +46,6 @@ cat << EOF
 
                %% write init;
                %% write exec;
-               %% write eof;
                if cs >= ${machine}_first_final
                        puts "ACCEPT"
                else
index 77d1a92..3fd39d2 100755 (executable)
@@ -250,7 +250,7 @@ for test_case; do
        [ -z "$allow_minflags" ] && allow_minflags="-n -m -l -e"
 
        case $lang in
-       c|c++|objc|d)
+       c|obj-c|c++|d)
                # Using genflags, get the allowed gen flags from the test case. If the
                # test case doesn't specify assume that all gen flags are allowed.
                allow_genflags=`sed '/@ALLOW_GENFLAGS:/s/^.*: *//p;d' $test_case`
index 4a8e5c4..3369c15 100644 (file)
@@ -119,6 +119,7 @@ end define
 
 define al_term_base
                [id]
+       |       [SPOFF] [id] '( [SPON] [al_expr] ')
        |       [opt al_sign] [number]
        |       [stringlit] 
        |       [charlit]