From bb2c37198206c80221768d9625739cac144f579f Mon Sep 17 00:00:00 2001 From: thurston Date: Mon, 21 Apr 2008 17:55:02 +0000 Subject: [PATCH] lm_switch needs to set p from tokend when there is no user action. git-svn-id: http://svn.complang.org/ragel/trunk@442 052ea7fc-9027-0410-9066-f65837a77df0 --- ragel/xmlcodegen.cpp | 29 ++++++++++++++++++++++------- rlgen-cd/fsmcodegen.cpp | 14 +++++++++++--- rlgen-csharp/fsmcodegen.cpp | 8 +++++--- rlgen-java/javacodegen.cpp | 8 +++++--- rlgen-ruby/ruby-codegen.cpp | 6 +++++- test/scan4.rl | 33 +++++++++++++++++++++++++++++++++ 6 files changed, 81 insertions(+), 17 deletions(-) create mode 100644 test/scan4.rl diff --git a/ragel/xmlcodegen.cpp b/ragel/xmlcodegen.cpp index 046c2df..16bd833 100644 --- a/ragel/xmlcodegen.cpp +++ b/ragel/xmlcodegen.cpp @@ -311,6 +311,11 @@ void XMLCodeGen::writeLmSwitch( InlineItem *item ) LongestMatch *longestMatch = item->longestMatch; out << "\n"; + /* We can't put the here because we may need to handle the error + * case and in that case p should not be changed. Instead use a default + * label in the switch to adjust p when user actions are not set. An id of + * -1 indicates the default. */ + if ( longestMatch->lmSwitchHandlesError ) { /* If the switch handles error then we should have also forced the * error state. */ @@ -321,17 +326,27 @@ void XMLCodeGen::writeLmSwitch( InlineItem *item ) out << "\n"; } + bool needDefault = false; for ( LmPartList::Iter lmi = *longestMatch->longestMatchList; lmi.lte(); lmi++ ) { - if ( lmi->inLmSelect && lmi->action != 0 ) { - /* Open the action. Write it with the context that sets up _p - * when doing control flow changes from inside the machine. */ - out << " longestMatchId << "\">"; - out << ""; - writeInlineList( lmi->action->inlineList ); - out << "\n"; + if ( lmi->inLmSelect ) { + if ( lmi->action == 0 ) + needDefault = true; + else { + /* Open the action. Write it with the context that sets up _p + * when doing control flow changes from inside the machine. */ + out << " longestMatchId << "\">"; + out << ""; + writeInlineList( lmi->action->inlineList ); + out << "\n"; + } } } + if ( needDefault ) { + out << " " + "\n"; + } + out << " "; } diff --git a/rlgen-cd/fsmcodegen.cpp b/rlgen-cd/fsmcodegen.cpp index 9508120..2d4a14c 100644 --- a/rlgen-cd/fsmcodegen.cpp +++ b/rlgen-cd/fsmcodegen.cpp @@ -333,9 +333,15 @@ void FsmCodeGen::LM_SWITCH( ostream &ret, InlineItem *item, ret << " switch( " << ACT() << " ) {\n"; + bool haveDefault = false; for ( InlineList::Iter lma = *item->children; lma.lte(); lma++ ) { /* Write the case label, the action and the case break. */ - ret << " case " << lma->lmId << ":\n"; + if ( lma->lmId < 0 ) { + ret << " default:\n"; + haveDefault = true; + } + else + ret << " case " << lma->lmId << ":\n"; /* Write the block and close it off. */ ret << " {"; @@ -344,9 +350,11 @@ void FsmCodeGen::LM_SWITCH( ostream &ret, InlineItem *item, ret << " break;\n"; } - /* Default required for D code. */ + + if ( hostLang->lang == HostLang::D && !haveDefault ) + ret << " default: break;"; + ret << - " default: break;\n" " }\n" "\t"; } diff --git a/rlgen-csharp/fsmcodegen.cpp b/rlgen-csharp/fsmcodegen.cpp index 09398d8..dafb4bc 100644 --- a/rlgen-csharp/fsmcodegen.cpp +++ b/rlgen-csharp/fsmcodegen.cpp @@ -357,7 +357,10 @@ void FsmCodeGen::LM_SWITCH( ostream &ret, InlineItem *item, for ( InlineList::Iter lma = *item->children; lma.lte(); lma++ ) { /* Write the case label, the action and the case break. */ - ret << " case " << lma->lmId << ":\n"; + if ( lma->lmId < 0 ) + ret << " default:\n"; + else + ret << " case " << lma->lmId << ":\n"; /* Write the block and close it off. */ ret << " {"; @@ -366,9 +369,8 @@ void FsmCodeGen::LM_SWITCH( ostream &ret, InlineItem *item, ret << " break;\n"; } - /* Default required for D code. */ + ret << - " default: break;\n" " }\n" "\t"; } diff --git a/rlgen-java/javacodegen.cpp b/rlgen-java/javacodegen.cpp index 0859e0c..fdd4899 100644 --- a/rlgen-java/javacodegen.cpp +++ b/rlgen-java/javacodegen.cpp @@ -1496,7 +1496,10 @@ void JavaTabCodeGen::LM_SWITCH( ostream &ret, InlineItem *item, for ( InlineList::Iter lma = *item->children; lma.lte(); lma++ ) { /* Write the case label, the action and the case break. */ - ret << " case " << lma->lmId << ":\n"; + if ( lma->lmId < 0 ) + ret << " default:\n"; + else + ret << " case " << lma->lmId << ":\n"; /* Write the block and close it off. */ ret << " {"; @@ -1505,9 +1508,8 @@ void JavaTabCodeGen::LM_SWITCH( ostream &ret, InlineItem *item, ret << " break;\n"; } - /* Default required for D code. */ + ret << - " default: break;\n" " }\n" "\t"; } diff --git a/rlgen-ruby/ruby-codegen.cpp b/rlgen-ruby/ruby-codegen.cpp index 94c9568..c7e923c 100644 --- a/rlgen-ruby/ruby-codegen.cpp +++ b/rlgen-ruby/ruby-codegen.cpp @@ -570,7 +570,11 @@ void RubyCodeGen::LM_SWITCH( ostream &ret, InlineItem *item, for ( InlineList::Iter lma = *item->children; lma.lte(); lma++ ) { /* Write the case label, the action and the case break. */ - ret << " when " << lma->lmId << " then\n"; + if ( lma->lmId < 0 ) + ret << " else\n"; + else + ret << " when " << lma->lmId << " then\n"; + /* Write the block and close it off. */ ret << " begin"; diff --git a/test/scan4.rl b/test/scan4.rl new file mode 100644 index 0000000..12d4d4c --- /dev/null +++ b/test/scan4.rl @@ -0,0 +1,33 @@ +/* + * @LANG: indep + */ +ptr ts; +ptr te; +int act; +int token; +%% +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => { + prints "pat1\n"; + }; + + [ab]+ . 'c' => { + prints "pat2\n"; + }; + + any; + *|; +}%% +/* _____INPUT_____ +"ba a" +_____INPUT_____ */ +/* _____OUTPUT_____ +pat1 +pat1 +ACCEPT +_____OUTPUT_____ */ -- 2.7.4