【问题标题】:How to get Ragel EOF actions working如何让 Ragel EOF 动作起作用
【发布时间】:2013-04-29 07:21:30
【问题描述】:

我正在与 Ragel 合作评估 FSA,并且我想嵌入一个用户操作,该操作在我的机器完成输入测试时运行。无论机器是否以接受状态结束,我都需要运行此操作。我从 Ragel 指南中获取了这个修改后的示例,该示例说明了我的目标:

#include <string.h>
#include <stdio.h>

%%{
    machine foo;
    main := ( 'foo' | 'bar' ) 0 @{ res = 1; } $/{ finished = 1; };
}%%
%% write data;
int main( int argc, char **argv ) {
    int cs, res = 0, finished = 0;
    if ( argc > 1 ) {
        char *p = argv[1];
        char *pe = p + strlen(p) + 1;
        char* eof = pe;
        %% write init;
        %% write exec;
    }

    printf("result = %i\n", res );
    printf("finished = %i\n", finished);

    return 0;
}

我在这个例子中的目标是当输入是 'foo' 或 'bar' 时 res 为 1,而无论输入如何,finished 都是 1。我无法让它工作 - 当 res 为 1 时,finished 似乎为 1,当 res 为 0 时,finished 似乎为 0。

任何帮助都会很棒。

【问题讨论】:

    标签: c finite-automata state-machine ragel


    【解决方案1】:

    p == pe == eof 时,将执行 eof 操作。另一个重要的事情是,当你的状态机无法匹配任何状态时,状态会出错,匹配会停止,这意味着你永远无法走到尽头。

    让我们看看你什么时候输入foo1。解析为o 时,一切正常。但是下一个字符1 无法匹配您指定的任何状态,因此会发生错误。你永远不会遇到 eof 动作。所以变量resfinish都是0。

    输入foo,一切正常。状态可以走到尽头。所以eof动作发生了。

    你可以设置错误动作看看会发生什么:

    %%{
        main := ( 'foo' | 'bar' ) 0 @{ res = 1; } $err{ printf("error : %c", fc);} $/{ finished = 1; };
    }%%
    

    您可以尝试使用此代码来满足您的需求:

    %%{
        main := (( 'foo' | 'bar' ) 0 @{ res = 1; } | any* ) $/{ finished = 1; };
    }%%
    

    【讨论】:

      【解决方案2】:

      试试这个:

      main := ( 
          'foo' 0 @2 @{ res = 1; } | 
          'bar' 0 @2 @{ res = 1; } |
          any*
          ) @{ finished = 1; };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-06
        • 1970-01-01
        • 1970-01-01
        • 2012-08-10
        • 1970-01-01
        相关资源
        最近更新 更多