2017-04-11 70 views
0

我是Ragel的新手,一直試圖解析正則表達式的特定模式。如果發現匹配,我想要執行動作done,如果沒有匹配,即使對於任何單個字符丟失,也要執行parse_error如何讓Ragel執行不同的解析操作

這是我寫的代碼:

#include <iostream> 
#include <string.h> 
#include <stdio.h> 

%%{ 
action done { 
printf("done\n"); 
} 


action parse_error { 
printf("error : %c\n",fc); 
} 


machine ldf;  
main := (':'.'LoadSdf'.[0-9]+.[a-zA-Z0-9_\-\.])@done | //execute done 
     (^(':'.'LoadSdf'.[0-9]+.[a-zA-Z0-9_\-\.])) $err(parse_error); //execute parse error for no match 

}%% 

%%write data; 
int main(int argc, char** argv) 
{ 
int cs; 
if(argc > 1) { 
char *p = argv[1]; 
char *pe = p+strlen(p) + 1; 
%%write init; 
%%write exec; 
} 
return 0; 
} 

我看到的現象是,當有正則表達式表達的完美匹配的行動doneparse_error都執行。

任何人都可以提供一些關於如何解決這種情況的提示?

+0

最好修復[其他問題](http://stackoverflow.com/questions/ 43341913/compiling-errors-with-ragel-and-c),然後還提供一些測試用例來顯示行爲以及它與預期結果的不同之處。 –

回答

1

這段代碼有幾個問題。首先,一個技術錯誤---你與pe定義(它包括零個字符,你的機器不應該關心零)(當然你可以使它處理它們,但它只是使事情變得複雜原因))。定義eof也很有用,因爲當您在輸入中輸入「:Load」(缺少「Sdf」和後面的塊)時它應該是錯誤的。這是固定的

-char *pe = p+strlen(p) + 1; 
+char *pe = p+strlen(p); 
+char *eof = pe; 

另一個問題是,沒有必要結合一些機器和它的負面控制錯誤。這些是不同的行爲。看看你的機器的畫面:

Original state machine

你可以看到,中間還有就是沒有合適的錯誤處理,並在結束時,你可以有done()調用幾次,因爲它規定發生過渡到最終狀態之一。可能它只能在正確的機器完成狀態下運行(即在最終狀態下達到EOF)。

所以,如果你對你的機器定義修改爲

main := (':'.'LoadSdf'.[0-9]+.[a-zA-Z0-9_\-\.]) %/done $!(parse_error); 

,你可能會得到你想要的東西:

$ ./a.out "asdf" 
error : a 
$ ./a.out "qwerty" 
error : q 
$ ./a.out ":Load" 
error : 
$ ./a.out ":LoadSdf" 
error : 
$ ./a.out ":LoadSdf1212" 
done 
$ ./a.out ":LoadSdf1q" 
done 
$ ./a.out ":LoadSdf1qwe" 
error : w 

看起來像這樣的圖形形式:

Fixed state machine

相關問題