ragel(用 C 语言使用 ragel「建议收藏」)

发布时间:2025-12-10 19:31:50 浏览次数:6

用 C 语言使用 ragel「建议收藏」-rage例句

用 C 语言使用 ragel「建议收藏」Ragel是个有限状态机编译器,它将基于正则表达式的状态机编译成传统语言(C,C++,D,Java,Ruby等)的解析器。用Ragel可以很方便且很容易的写出各种FSM,也经常用作语法检测器。RagelStateMachineCompiler一个用C语言实现的例子:编译上面的代码还不

Ragel是个有限状态机编译器,它将基于正则表达式的状态机编译成传统语言(C,C++,D,Java,Ruby等)的解析器。

用Ragel可以很方便且很容易的写出各种FSM,也经常用作语法检测器。

Ragel State Machine Compiler

一个用C语言实现的例子:

#include <stdio.h>#include <string.h>%%{    machine foo; #FSM 名称    #定义动作    action res_true {         res=1;    }    action res_false {        res=0;        }    action res_err {        res=-1;    }    #FSM 起点    main := ( 'true'0 @res_true | 'false'0 @res_false | any @res_err);     #写入 FSM 数据    write data; }%%int GetRes(char *pbuf){    int res;    char *p=pbuf; //初始化 p 指向需要做 FSM 处理的数组起始地址    char *pe=p+strlen(pbuf)+1; //初始化 pe 指向 p 的结束地址    int cs; // cs 用来保存 FSM 运行中状态    //写入初始化代码    %%write init;    //写入执行代码    %%write exec;    return res;}int main(){    int cs;    char buf[256];    while (scanf("%s",buf)) {        printf("res=%d\n",GetRes(buf));    }    return 0;}

希望我今天分享的这篇文章可以帮到您。

编译

上面的代码还不能直接用gcc编译,需要先用ragel编译成C语言代码,再用gcc编译成可执行程序。

ragel -o main.c main.rlgcc -o test main.c

上面例子实现的是把字符串”true” “false”转换成C语言1 0的形式,如果既不是”true”也不是”false”则结果为-1。

执行结果

输入

truefalsetruefalse

输出

res=1res=0res=-1

基本语法

多行的FSM定义以 %%{ 开始 %%} 结束。单行的FSM定义在行首以 %% 开始。

machine foo; 状态机的名称。

action 定义匹配动作,动作内写入匹配后所要执行的代码。

上面代码有3个动作,分别是 res_true, res_false, res_err 用来得出结果 。

main := 正则表达式; 表示FSM起始点,匹配先从这里开始。

上面代码中( ‘true’0 @res_true | ‘false’0 @res_false | any @res_err)表示

(如果成功匹配 “true\0” 执行动作res_true) 或则 (如果成功匹配 “false\0”执行动作res_false) 或则 (如果成功匹配 任意字符 执行动作res_err )

any是Ragel 的关键字,类似的还有

关键字描述
any所有字符.
asciiascii字符.0~127
extendascii扩展的字符.有符号-128~127或无符号0~255
alpha字母.[a~z A~Z]
digit数字.[0~9]
alnum字母和数字.[a~z A~Z 0~9]
lower小写字母.[a~z]
upper大写字母.[A~Z]
xdigit16进制数字.[0~9 a~f A~F]
cntrl控制字符.0~31
graph可视字符.[!-~]
print可打印字符.[ -~]
punct非字母数字可视字符.[!-/:-@[-‘{-~]
space空白字符.[\t\v\f\n\r ]
zlen空字符串.””
empty空集.^any

%%write data; 写入FSM运行中需要的状态数据,可以放在任何地方,但必须要在 %%write exec 之上。

%%write init; 写入FSM的初始化代码,放在函数之内,需要先定义 int cs。

%%write exec; 写入FSM的执行代码,放在函数之内,需要先定义 char *p 和 char *pe。

结束语

虽然使用Ragel很轻松的解决平常我们 if else if 功能,而且效率也不错,但是会使生成的源代码和程序体积变大(19K生成30M源码),所以使用前还是需要考虑考虑。

更详细的使用说明可以在Ragel State Machine Compiler下载使用手册。

需要做网站?需要网络推广?欢迎咨询客户经理 13272073477