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;
};
效率極高。
開源的工具就是好啊。

相關詞條

熱門詞條

聯絡我們