Как заставить действия Ragel EOF работать

Я работаю с 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;
}

Моя цель в этом примере состоит в том, чтобы res было равно 1, когда входное значение равно либо "foo", либо "bar", а готовое значение равно 1 независимо от ввода. Я не могу заставить это работать, хотя - закончено, кажется, 1, когда res равно 1, и 0, когда res равно 0.

Любая помощь будет потрясающей.

2 ответа

Eof действие будет иметь место, когда p == pe == eof, Еще одна важная вещь: когда ваш конечный автомат не может соответствовать ни одному состоянию, состояние переходит в состояние ошибки, и сопоставление останавливается, а это означает, что вы никогда не сможете перейти к концу.

Посмотрим, когда вы введете foo1, При разборе на o, все отлично. Howerver следующий характер 1 не может соответствовать ни одному указанному вами состоянию, поэтому возникает ошибка. Вы никогда не сможете встретиться с действием. Так что переменная res а также finish оба 0.

Когда вы вводите foo, все отлично. Государство может идти до конца. Итак, действие происходит.

Вы можете установить действие по ошибке, чтобы увидеть, что происходит:

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

И вы можете попробовать этот код для удовлетворения ваших потребностей:

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

Попробуй это:

main := ( 
    'foo' 0 @2 @{ res = 1; } | 
    'bar' 0 @2 @{ res = 1; } |
    any*
    ) @{ finished = 1; };
Другие вопросы по тегам