Go back to 3.X semantics for >, % and error actions. The > operator also embeds
authorthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Mon, 15 Oct 2007 22:40:06 +0000 (22:40 +0000)
committerthurston <thurston@052ea7fc-9027-0410-9066-f65837a77df0>
Mon, 15 Oct 2007 22:40:06 +0000 (22:40 +0000)
a leaving action/priority into the start state if it is final. If EOF happens
in a state with a leaving operator then leaving action it is executed. If EOF
happens in a non-final state that has an error action, the error action is
executed.

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

23 files changed:
ragel/fsmap.cpp
ragel/fsmgraph.h
ragel/parsedata.cpp
rlgen-ruby/ruby-flatcodegen.cpp
test/clang1.rl
test/clang2.rl
test/clang3.rl
test/clang4.rl
test/cppscan1.rl
test/cppscan2.rl
test/cppscan4.rl
test/erract1.rl
test/erract2.rl
test/erract5.rl
test/erract7.rl
test/erract8.rl
test/forder3.rl
test/gotocallret1.rl
test/langtrans_c.sh
test/recdescent1.rl
test/recdescent2.rl
test/recdescent3.rl
test/union.rl

index c9e673a..0674fa9 100644 (file)
@@ -122,6 +122,12 @@ void FsmAp::startFsmPrior( int ordering, PriorDesc *prior )
                if ( trans->toState != 0 )
                        trans->priorTable.setPrior( ordering, prior );
        }
+
+       /* If the new start state is final then set the out priority. This follows
+        * the same convention as setting start action in the out action table of
+        * a final start state. */
+       if ( startState->stateBits & SB_ISFINAL )
+               startState->outPriorTable.setPrior( ordering, prior );
 }
 
 /* Set the priority of all transitions in a graph. Walks all transition lists
@@ -180,6 +186,12 @@ void FsmAp::startFsmAction( int ordering, Action *action )
                if ( trans->toState != 0 )
                        trans->actionTable.setAction( ordering, action );
        }
+
+       /* If start state is final then add the action to the out action table.
+        * This means that when the null string is accepted the start action will
+        * not be bypassed. */
+       if ( startState->stateBits & SB_ISFINAL )
+               startState->outActionTable.setAction( ordering, action );
 }
 
 /* Set functions to execute on all transitions. Walks the out lists of all
@@ -320,6 +332,13 @@ void FsmAp::setErrorTarget( StateAp *state, StateAp *target, int *orderings,
        }
 }
 
+void FsmAp::transferOutActions( StateAp *state )
+{
+       for ( ActionTable::Iter act = state->outActionTable; act.lte(); act++ )
+               state->eofActionTable.setAction( act->key, act->value ); 
+       state->outActionTable.empty();
+}
+
 void FsmAp::transferErrorActions( StateAp *state, int transferPoint )
 {
        for ( int i = 0; i < state->errActionTable.length(); ) {
@@ -327,6 +346,8 @@ void FsmAp::transferErrorActions( StateAp *state, int transferPoint )
                if ( act->transferPoint == transferPoint ) {
                        /* Transfer the error action and remove it. */
                        setErrorAction( state, act->ordering, act->action );
+                       if ( ! state->isFinState() )
+                               state->eofActionTable.setAction( act->ordering, act->action );
                        state->errActionTable.vremove( i );
                }
                else {
index 3241f0f..b10ff3a 100644 (file)
@@ -1134,6 +1134,7 @@ struct FsmAp
        void leaveFsmPrior( int ordering, PriorDesc *prior );
 
        /* Action setting support. */
+       void transferOutActions( StateAp *state );
        void transferErrorActions( StateAp *state, int transferPoint );
        void setErrorAction( StateAp *state, int ordering, Action *action );
 
index 0dcb238..9a05d70 100644 (file)
@@ -1064,6 +1064,10 @@ FsmAp *ParseData::makeInstance( GraphDictEl *gdNode )
         * All state construction is now complete.
         */
 
+       /* Transfer actions from the out action tables to eof action tables. */
+       for ( StateSet::Iter state = graph->finStateSet; state.lte(); state++ )
+               graph->transferOutActions( *state );
+
        /* Transfer global error actions. */
        for ( StateList::Iter state = graph->stateList; state.lte(); state++ )
                graph->transferErrorActions( state, 0 );
@@ -1235,31 +1239,9 @@ void ParseData::checkInlineList( Action *act, InlineList *inlineList )
                /* EOF checks. */
                if ( act->numEofRefs > 0 ) {
                        switch ( item->type ) {
-                       case InlineItem::PChar: 
-                               error(item->loc) << "pointer to current element does not exist in "
-                                               "EOF action code" << endl;
-                               break;
-                       case InlineItem::Char: 
-                               error(item->loc) << "current element does not exist in "
-                                               "EOF action code" << endl;
-                               break;
-                       case InlineItem::Hold:
-                               error(item->loc) << "changing the current element not possible in "
-                                               "EOF action code" << endl;
-                               break;
-                       case InlineItem::Exec:
-                               error(item->loc) << "changing the current element not possible in "
-                                               "EOF action code" << endl;
-                               break;
-                       case InlineItem::Goto: case InlineItem::Call: 
-                       case InlineItem::Next: case InlineItem::GotoExpr: 
-                       case InlineItem::CallExpr: case InlineItem::NextExpr:
-                       case InlineItem::Ret:
-                               error(item->loc) << "changing the current state not possible in "
-                                               "EOF action code" << endl;
-                               break;
-                       default:
-                               break;
+                               /* Currently no checks. */
+                               default:
+                                       break;
                        }
                }
 
index 5168c7f..0d4196b 100644 (file)
@@ -515,7 +515,8 @@ void RubyFlatCodeGen::BREAK( ostream &out, int targState )
 {
        out << 
                "       begin\n"
-               "               _break_resume = true\n"
+               "               _trigger_goto = true\n"
+               "               _goto_level = _out\n"
                "               break\n"
                "       end\n";
 }
@@ -829,6 +830,9 @@ void RubyFlatCodeGen::writeExec()
                                EOF_ACTION_SWITCH() <<
                                "               end\n"
                                "       end\n"
+                               "       if _trigger_goto\n"
+                               "               next\n"
+                               "       end\n"
                                "       end\n";
                }
 
index 7ed0456..85532c6 100644 (file)
@@ -161,6 +161,7 @@ void test( char *buf )
 {
        int len = strlen( buf );
        char *p = buf, *pe = buf + len;
+       char *eof = pe;
        char identBuf[IDENT_BUFLEN+1];
        int identLen;
        int curLine;
index fb7428e..3b22e4b 100644 (file)
 {
        const char *p = data; 
        const char *pe = data + len;
+       const char *eof = pe;
 
        %% write exec;
 }
index 6c9150e..82f5eed 100644 (file)
@@ -159,6 +159,7 @@ class CLang
        {
                char *p = _data;
                char *pe = _data + _len;
+               char *eof = pe;
                %% write exec;
        }
 
index cdd0c44..9644b8e 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * @LANG: indep
+ * @NEEDS_EOF: yes
  */
 
 ptr tokstart;
index 0b6e00d..8c87f78 100644 (file)
@@ -136,6 +136,7 @@ int Scanner::execute( char *data, int len )
        Scanner *fsm = this;
        char *p = data;
        char *pe = data + len;
+       char *eof = pe;
 
        %% write exec;
        if ( cs == Scanner_error )
index 9ce3a25..78efe20 100644 (file)
@@ -184,6 +184,7 @@ int Scanner::execute( char *data, int len )
 {
        char *p = data;
        char *pe = data + len;
+       char *eof = pe;
 
        %% write exec;
 
index 8e9dc1b..42a97f1 100644 (file)
@@ -192,6 +192,7 @@ class Scanner
        {
                char *p = _data;
                char *pe = _data + _len;
+               char *eof = null;
 
                %% write exec;
 
index 9f34f55..e928179 100644 (file)
@@ -65,6 +65,7 @@ int ErrAct::execute( const char *_data, int _len )
 {
        const char *p = _data;
        const char *pe = _data+_len;
+       const char *eof = pe;
        %% write exec;
 
        if ( cs == ErrAct_error )
index a4d0ef9..b1fbfbf 100644 (file)
 _____INPUT_____ */
 
 /* _____OUTPUT_____
+err_start
 eof_start
+err_all
 eof_all
 FAIL
+err_all
+err_middle
 eof_all
 eof_middle
 FAIL
 err_start
 err_all
 FAIL
+err_all
+err_middle
 eof_all
 eof_middle
 FAIL
 err_all
 err_middle
 FAIL
+err_all
+err_middle
 eof_all
 eof_middle
 FAIL
 err_all
 err_middle
 FAIL
+err_all
+err_middle
 eof_all
 eof_middle
 FAIL
 err_all
 err_middle
 FAIL
+err_all
+err_out
 eof_all
 eof_out
 FAIL
index 2b23324..0ea6e9a 100644 (file)
@@ -69,6 +69,7 @@
 {
        const char *p = _data;
        const char *pe = _data + _len;
+       const char *eof = pe;
        %% write exec;
 }
 
index 4b403ef..040ad73 100644 (file)
@@ -21,6 +21,7 @@ int main()
 {
        int cs;
        char *p = "hello", *pe = p + strlen(p);
+       char *eof = pe;
        %%{
                write init;
                write exec;
index c358d23..7926186 100644 (file)
@@ -19,6 +19,7 @@ class erract8
        static void test( char data[] )
        {
                int cs, p = 0, pe = data.length;
+               int eof = pe;
                int top;
 
                %% write init;
index 15ea41e..55daf18 100644 (file)
@@ -83,15 +83,18 @@ through m1 b
 accept m1
 ACCEPT
 enter m2
+enter m2
 accpet m2
 ACCEPT
 enter m1 aa
+enter m1 aa
 leave m1 aa
 through m1 b
 enter m2
 accept m1
 ACCEPT
 enter m1 aa
+enter m1 aa
 leave m1 aa
 through m1 b
 enter m2
index 54626dd..8b294dd 100644 (file)
@@ -106,6 +106,7 @@ correct command
 ACCEPT
 correct command
 ACCEPT
+error: failed to recover
 FAIL
 error: garbling line
 error: failed to recover
index 431ec26..12f0ab4 100755 (executable)
@@ -11,7 +11,10 @@ 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`
+needs_eof=`sed '/@NEEDS_EOF/s/^.*$/yes/p;d' $file`
+if [ "$needs_eof" != 'yes' ]; then
+       needs_eof=`sed -n '/\/\*/,/\*\//d;p' $file | txl -q stdin checkeofact.txl`
+fi
 
 # Begin writing out the test case.
 cat << EOF
@@ -49,7 +52,7 @@ void exec( char *data, int len )
        char *pe = data + len;
 EOF
 
-[ "$has_eof_act" = "yes" ] && echo "char *eof = pe;"
+[ "$needs_eof" = "yes" ] && echo "char *eof = pe;"
 
 cat << EOF
        %% write exec;
index 66812f4..1ffca28 100644 (file)
@@ -74,7 +74,7 @@ void test( char *buf )
        int cs;
        int *stack;
        int top, stack_size;
-       char *p, *pe, *item = 0;
+       char *p, *pe, *eof, *item = 0;
 
        int len = strlen( buf );
 
@@ -85,6 +85,7 @@ void test( char *buf )
 
        p = buf;
        pe = buf + len;
+       eof = pe;
 
        %% write exec;
 
index 1e51451..59c4586 100644 (file)
@@ -71,7 +71,7 @@ class recdescent2
 
        static void test( char data[] )
        {
-               int cs, p = 0, pe = data.length, item = 0;
+               int cs, p = 0, pe = data.length, eof = data.length, item = 0;
                int stack[] = new int[1024];
                int stack_size = 1;
                int top;
index c5621e1..1216b43 100644 (file)
@@ -70,6 +70,7 @@ def run_machine( data )
        item = 0;
        p = 0;
        pe = data.length;
+       eof = pe;
        cs = 0;
        stack = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
        stack_size = 1;
index a8beace..8be02e2 100644 (file)
@@ -100,6 +100,7 @@ void Concurrent::execute( const char *data, int len )
 {
        const char *p = data;
        const char *pe = data + len;
+       const char *eof = pe;
 
        %% write exec;
 }