我是Ragel的新手并且一直试图解析特定的Regex表达模式。如果找到匹配项,我希望执行操作done
,如果没有匹配,即使任何单个字符丢失,也要执行parse_error
。
这是我写的代码:
#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;
}
我看到的行为是,当正则表达式完全匹配时,动作done
和parse_error
都会被执行。
任何人都可以提供一些关于如何处理此案的提示吗?
答案 0 :(得分:1)
此代码存在一些问题。首先,技术错误---你用pe
定义一个接一个(它包括零个字符,你的机器不应该关心零(当然你可以让它处理它们) ,但它只是无缘无故地复杂化))。定义eof
也很有用,因为当你有类似&#34;:Load&#34;之类的东西时,它应该是一个错误。在输入中(缺少&#34; Sdf&#34;以及后面的块)。这是由
-char *pe = p+strlen(p) + 1;
+char *pe = p+strlen(p);
+char *eof = pe;
另一个问题是没有必要将一些机器及其负面结合起来控制错误。这些是不同的行为。看一下机器的图片:
你可以看到中间没有正确的错误处理,最后你可以多次调用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
以图形形式显示如下: