我正在与Ragel一起评估FSA,我想嵌入一个用户操作,只要我的机器完成输入测试就会运行。无论机器是否以接受状态结束,我都需要执行此操作。我从Ragel指南中获取了这个修改过的例子,它说明了我的目标:
#include <string.h>
#include <stdio.h>
%%{
machine foo;
main := ( 'foo' | 'bar' ) 0 @{ res = 1; } $/{ finished = 1; };
}%%
%% write data;
int main( int argc, char **argv ) {
int cs, res = 0, finished = 0;
if ( argc > 1 ) {
char *p = argv[1];
char *pe = p + strlen(p) + 1;
char* eof = pe;
%% write init;
%% write exec;
}
printf("result = %i\n", res );
printf("finished = %i\n", finished);
return 0;
}
这个例子的目标是当输入为'foo'或'bar'时res为1,而无论输入如何,finish为1。我不能让它工作 - 当res为1时,完成似乎为1,当res为0时,则为0。
任何帮助都会很棒。
答案 0 :(得分:3)
eof操作将在p == pe == eof
时执行。另一个重要的事情是,当你的状态机无法匹配任何状态时,状态将转为错误并且匹配将停止,这意味着你永远不能走到最后。
让我们看看您何时输入foo1
。解析为o
时,一切正常。如果下一个字符1
无法匹配您指定的任何状态,则会发生错误。你永远不能满足eof行动。因此变量res
和finish
都是0。
当您输入foo
时,每件事情都可以。国家可以走到尽头。所以eof行动发生了。
您可以设置错误操作以查看会发生什么:
%%{
main := ( 'foo' | 'bar' ) 0 @{ res = 1; } $err{ printf("error : %c", fc);} $/{ finished = 1; };
}%%
您可以尝试使用此代码来满足您的需求:
%%{
main := (( 'foo' | 'bar' ) 0 @{ res = 1; } | any* ) $/{ finished = 1; };
}%%
答案 1 :(得分:1)
试试这个:
main := (
'foo' 0 @2 @{ res = 1; } |
'bar' 0 @2 @{ res = 1; } |
any*
) @{ finished = 1; };