1. 首页 > 经验  > 正文

ragel

ragel

Ragel是个有限状态机编译器,它将基于正则表达式的状态机编译成传统语言(C,C++,D,Java,Ruby等)的解析器。Ragel不仅仅可以用来解析位元组流,它实际上可以解析任何可以用正则表达式表达出来的内容。而且可以很方便的将解析代码嵌入到传统语言中。

Ragel一个可以生成协定处理代码的工具. 举个官方的例子如下:
int atoi( char *str )
{
char *p = str;
int cs, val = 0;
bool neg = false;
%%{//Ragel 的关键字,用于声明状态机代码段的开始
action see_neg {
neg = true;
}
action add_digit {
val = val * 10 + (fc - '0');
}
main :=
( '-'@see_neg | '+' )? ( digit @add_digit )+
'\n' @{ fbreak; };
# Initialize and execute.
write init;//状态机关键字,这个会再接下来的内容中介绍
write exec noend; //同上
}%%//状态机代码段结束标记
if ( neg )
val = -1 * val;
if ( cs < atoi_first_final )
cerr << "atoi: there was an error" << endl;
return val;
};
这段代码就是用来将字元串转化为int的解析代码。用ragel转化为c语言后结果如下:
int atoi( char *str )
{
char *p = str;
int cs, val = 0;
bool neg = false;
#line 27 "atoi.c"
{
cs = atoi_start;
}
#line 31 "atoi.c"
{
switch ( cs )
{
case 1:
switch( (*p) ) {
case 43: goto st2;
case 45: goto tr2;
}
if ( 48 <= (*p) && (*p) <= 57 )
goto tr3;
goto st0;
st0:
goto _out0;
tr2:
#line 23 "atoi.rl"
{
neg = true;
}
goto st2;
st2:
p += 1;
case 2:
#line 52 "atoi.c"
if ( 48 <= (*p) && (*p) <= 57 )
goto tr3;
goto st0;
tr3:
#line 27 "atoi.rl"
{
val = val * 10 + ((*p) - '0');
}
goto st3;
st3:
p += 1;
case 3:
#line 63 "atoi.c"
if ( (*p) == 10 )
goto tr4;
if ( 48 <= (*p) && (*p) <= 57 )
goto tr3;
goto st0;
tr4:
#line 33 "atoi.rl"
{ goto _out4; }
goto st4;
st4:
p += 1;
case 4:
#line 74 "atoi.c"
goto st0;
}
_out0: cs = 0; goto _out;
_out4: cs = 4; goto _out;
_out: {}
}
#line 38 "atoi.rl"
if ( neg )
val = -1 * val;
if ( cs < atoi_first_final )
cerr << "atoi: there was an error" << endl;
return val;
};
效率极高。
开源的工具就是好啊。

本文由'是你的宾实呀'发布,不代表演示站立场,转载/删除联系作者,如需删除请-> 关于侵权处理说明