[ragel-users] Re: Error actions and error recovery
Christer Sandberg
chr... at gmail.com
Wed Sep 5 07:32:39 UTC 2007
>
>
> > 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
More information about the ragel-users
mailing list