[ragel-users] Re: Error actions and error recovery

Adrian Thurston thurs... at cs.queensu.ca
Wed Sep 5 21:16:00 UTC 2007


Hi Christer,

I'm not sure why you expect se to be executed in the first error
example. Since you're matching the closing '}' using handwritten code in
the action, the state machine isn't executing actions.

In the second error example the problem is that you're jumping back to
the main machine and so 'b1' isn't matched (expecting '{').

Here's an example that uses extra machines to handle the errors then
jumps back to appropriate recovery point. Sorry if there are any coding
mistakes in it. I went fast.

Adrian


Christer Sandberg wrote:
>>
>>> pr = alnum+ ';';
>>> se = '{' pr* '}';
>>> main := se+;
>>>
>>> What I would like to accomplish is that if there's an error in pr I
>>> would like to skip to the next ';' or '}'. I there's an error finding
>>> the first '{', I would like to skip to the next '}'.
>> This expression doesn't search for '{' at all - it expects to find one
>> right at the start of the input, and another one immediately after
>> every '}' (with nothing in-between) until you reach the final '}' at
>> the end of the input stream.
> 
> I know, it's a good point but I just posted a simplified example to
> keep the example as simple as possible.
> 
>> Perhaps you need to make use of an (any* -- se) term to skip any non-
>> matching stuff between the blocks you are interested in...
>>
> 
> In my "real" grammar I don't skip anything in between. It's all being handled.
> 
>> pr = alnum+ ';';
>> se = '{' pr* '}';
>> other = (any* -- se);
>> main := other (se other)*;
>>
>> Not sure how well this will work in practice - it looks like it needs
>> backtracking and may need to use the scanner construct...
>>
>> pr = alnum+ ';';
>> se = '{' pr* '}';
>> other = (any+ -- '{');
>> main := |* se => { action };
>>               other => { do nothing };
>>               '{' => { last resort step past open brace action };
>>            *|;
>>
>> The idea here is the 'other' shouldn't even accept part of the 'se'
>> pattern. As soon as it spots an open brace, it should stop and give
>> the 'se' token a chance to match. If neither 'se' nor 'other' can
>> accept any characters, you must have an open brace as the next
>> character, so skip past that then continue.
>>
>> For this to work, it is important that neither 'se' nor 'other' can
>> accept a empty match - if they did, I suspect you'd get an infinite
>> loop with the standalone '{' match never firing. Is that right,
>> Adrian?
>>
> 
> I've got it half working but not all the way. Here's the simple
> example machine again with some debugging output:
> 
>   action _pr {
>     printf("_pr on '%c'\n", *p);
>   }
> 
>   action pr {
>     printf("pr on '%c'\n", *p);
>   }
> 
>   action _se {
>     printf("_se on '%c'\n", *p);
>   }
> 
>   action se {
>     printf("se on '%c'\n", *p);
>   }
> 
>   action pr_err {
>     printf("pr_err on '%c'\n", *p);
>     while (p != pe && *p != ';' && *p != '}') {
>       p++;
>     }
> 
>     p++;
>     printf("pr_err skipped to '%c'\n", *p);
>     fgoto main;
>   }
> 
>   pr = alnum+ >_pr ';' @pr;
>   se = '{' >_se pr* $lerr(pr_err) '}' @se;
> 
>   main := se+;
> 
> If I feed it with this correct string {a1;}{b1;c1;}, the output is the
> following:
> 
> _se on '{'
> _pr on 'a'
> pr on ';'
> se on '}'
> _se on '{'
> _pr on 'b'
> pr on ';'
> _pr on 'c'
> pr on ';'
> se on '}'
> css_error_first_final: 4
> 
> If I feed it with this incorrect string {$;}{a1;}, the output is this:
> 
> _se on '{'
> pr_err on '$'
> pr_err skipped to '}'
> _se on '{'
> _pr on 'a'
> pr on ';'
> se on '}'
> css_error_first_final: 4
> 
> The local error action skips to the closing '}' but then the se action
> is never invoked.
> 
> If I feet it with this incorrect string (which has more than one pr
> between the first braces) {$;b1;}{a1;}, the output is this:
> 
> _se on '{'
> pr_err on '$'
> pr_err skipped to 'b'
> css_error_error: 0
> 
> As you can see the machine exits with an error.
> Any clues of how to solve this?
> 
> /Christer
> 
> --~--~---------~--~----~------------~-------~--~----~
> You received this message because you are subscribed to the Google Groups "ragel-users" group.
> To post to this group, send email to ragel-users at googlegroups.com
> To unsubscribe from this group, send email to ragel-users-unsubscribe at googlegroups.com
> For more options, visit this group at http://groups.google.com/group/ragel-users?hl=en
> -~----------~----~----~----~------~----~------~--~---
> 
> 
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: foo.rl
URL: <http://www.colm.net/pipermail/ragel-users/attachments/20070905/10b9dbd8/attachment-0001.ksh>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 252 bytes
Desc: OpenPGP digital signature
URL: <http://www.colm.net/pipermail/ragel-users/attachments/20070905/10b9dbd8/attachment-0001.sig>


More information about the ragel-users mailing list