Как заставить действия 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; };