[ragel-users] fcall/fret operator error?

Adrian Thurston thurston at complang.org
Fri Oct 10 21:36:04 UTC 2008


Hi Gordon,

That's happening because each machine instantiation has a set of final
states. When you pass an incomplete string the binary_data_machine ends
up in a final state. You can use an EOF action to catch this and raise
an error.

Adrian

P.S. sorry for the double posting of the question -- I approved the
non-member post at the same time as Gordon resent using his subscribed
address.

Gordon Smith wrote:
> Hello all -
> 
> Having a bit of trouble with fcall/fret.
> 
> I need to read a number in a string that indicates the number of bytes
> to follow. I do this correctly with a complete string, but also reach a
> final state with an incomplete string that includes some of the binary
> data. I'm using fcall into another machine to read the binary data.
> 
> Have I missed something obvious?
> 
> Thanks,
> Gordon
> 
> %%{
>     machine TEST;
>     alphtype char;
> 
>     action binary_data_length_check {
>         fsm.binary_data_count++;
>         if ( fsm.binary_data_count >= fsm.byte_count ) {
>             //fhold;
>             fret;
>         }
>     }
> 
>     action binary_data_init { fsm.binary_data_count = 0; }
> 
>     binary_data_machine := any+ $binary_data_length_check >binary_data_init;
> 
>     # We're trying to do this:
>     # any{fsm.byte_count}
>     action binary_data_action {
>         fcall binary_data_machine;
>     }
> 
>     binary_payload = 'r.' @binary_data_action;
> 
>     # b:<NumBytes>:<NumBytes of chars>:<CRC><CR>
>     bridge_packet =
>         'b:'
>         ( xdigit @{ AddXDigit( fsm.byte_count, * p ); } )+
>         ':'
>         binary_payload
>         ':'
>         xdigit+
>         '\r';
> 
>     main := bridge_packet;
> }%%
> 
> %% write data;
> 
> void init() {
>     %% write init;
>     fsm.byte_count = 0;
> }
> 
> void parse(char * payload, char * payloadEnd) {
>     const char * p = payload;
>     const char * pe = payloadEnd;
> 
>     %% access fsm.;
>     %% write exec;
> 
>     if ( fsm.cs == TEST_error ) {
>         std::cout << "FINISH_ERROR\n";
>     } else if ( fsm.cs >= TEST_first_final ) {
>         std::cout << "FINISH_FINAL\n";
>     } else {
>         std::cout << "FINISH_NOT_FINAL\n";
>     }
> }
> 
> int main() {
>     init();
>     {
>         // Complete
>         char * t1 = "b:0004:r.abcd:a0\r";
>         parse(t1, t1 + strlen( t1 ) );
>     }
>    
>     init();
>     {
>         // Incomplete
>         char * t1 = "b:0004:r.ab";
>         parse(t1, t1 + strlen( t1 ) );
>     }
>    
>     return 0;
> }
> 
> ----------
> Output is:
> {{{
> FINISH_FINAL
> FINISH_FINAL
> }}}
> 
> and I expect
> {{{
> FINISH_FINAL
> FINISH_NOT_FINAL
> }}}
> 
> AddXDigit( unsigned target, char c ) adds value of hexadecimal digit to
> target.
> 
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> ragel-users mailing list
> ragel-users at complang.org
> http://www.complang.org/mailman/listinfo/ragel-users




More information about the ragel-users mailing list