[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