2013-04-29 21 views
6

FSA'ları değerlendirmek için Ragel ile çalışıyorum ve makinem girişin tamamlanmasını tamamladığında çalışan bir kullanıcı eylemi gömmek istiyorum. Makinenin kabul eden bir durumda olup olmadığına bakılmaksızın çalışabilmek için bu işleme ihtiyacım var. Ben gidiyorum Ne yapılacağını gösteren Ragel kılavuzunda alınan bu değiştirilmiş örnek var:Ragel EOF eylemleri nasıl çalışır

#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; 
} 

girdi 'foo' veya 'bar' ya olduğunda res 1 olabilmesi için bu örnek için Amacım olduğunu bitmiş ise 1 ne olursa olsun girdi. Ancak bunu çalışmak için alamıyorum - res 1 olduğunda, 1 ve res 0 olduğunda 0 görünüyor.

Herhangi bir yardım harika olurdu.

cevap

1

bu deneyin: ne zaman p == pe == eof

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

eof eylem gerçekleştirilecektir. Bir başka önemli şey şu ki, devlet makineniz herhangi bir durumundaki durumunu eşleştiremediğinde, durum hatayı gidecektir ve eşleşme duracaktır, bu da asla sona ermeyeceğiniz anlamına gelir.

foo1'u girdiğinizde görelim. o'a ayrıştırma yaparken her şey yolunda. Howerver sonraki karakter 1 belirttiğiniz herhangi bir durumla eşleşemiyor, böylece bir hata oluşur. Eof eylemiyle asla baş edemezsiniz. Yani res ve değişkenlerinin her ikisi de 0'dır.

foo girdiğinizde her şey tamamdır. Devlet sonuna kadar gidebilir. Böylece eylem gerçekleşir.

Sen ne olacağını görmek için hata eylemi ayarlayabilirsiniz:

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

Ve ihtiyaçlarınızı karşılamak için bu kodu deneyebilirsiniz:

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