码迷,mamicode.com
首页 > 编程语言 > 详细

用 C 语言使用 ragel

时间:2016-04-20 23:20:51      阅读:2263      评论:0      收藏:0      [点我收藏+]

标签:

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 := ( true0 @res_true | false0 @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.rl
gcc -o test main.c

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

执行结果

输入

true

false

truefalse

输出

res=1

res=0

res=-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 所有字符.
ascii ascii字符.0~127
extend ascii扩展的字符.有符号-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]
xdigit 16进制数字.[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下载使用手册。

 

用 C 语言使用 ragel

标签:

原文地址:http://www.cnblogs.com/baiihcy/p/5414875.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!