Re: <skip: over comments> and misleading <error> messages
[email protected] (Karl Gaissmaier)
| Newsgroups | perl.recdescent |
|---|---|
| Message-ID | <[email protected]> |
Hi Yves,
> "Orton, Yves" schrieb:
>
> ....
>
> > The problem is, (as far as I understand) that the <skip> must be
> > bound to a rule, and when the rule isn't matched, then the already
> > skipped text is stuffed back to the $text stream from where the
> > <error> directive is generating the message "but found ....".
> >
> > If Damian had spent a Package Variable:
> >
> > $RD_SKIP
>
> Well, there is such a variable, but its not called $::RD_SKIP its called
>
> $Parse::RecDescent::skip
oh fine, the next time I will look first in the source!
....
>
> So if you rewrite your example to be (with a couple of extra comments for
> testing)
>
> #!/usr/bin/perl -w
> use Parse::RecDescent;
> # Ignore continuous whitespace or # and everything after it.
> $Parse::RecDescent::skip=qr/
> (
> ^\s+ # ignore continuous whitespace
> | # or
> \#.*$ # Comment to the end of the line (the \
> is mandatory)
> )+ # One or many times.
> /x; # xtended regex syntax, ignore
> whitespace and comments in regex
> my $grammar =<<'EOGRAMMAR';
> file : int(s) /\z/
> | <error>
>
> int : /[+-]?\d+/
> | <error>
> EOGRAMMAR
>
> my $parser = Parse::RecDescent->new($grammar);
>
> my $text = <<'EOTEXT';
> # comment
> 123 #comment
> # comment
> .123 #Comment
> EOTEXT
>
> my $result = $parser->file($text);
>
> __END__
>
> The I get the following result
>
> ERROR (line 1): Invalid int: Was expecting /[+-]?\\d+/
>
> ERROR (line 1): Invalid file: Was expecting int
>
> Which is what I believe you wanted.
>
> Incidentally the regex you posted qr{(\s*(#.*\n)*)*} scares the *sh*t* out
> of me. (The )*)* is a construct that may not be wrong in this case but
> often _is_ very wrong, so when I see it my spidey sense goes crazy, and I
> replace it. (Not everything a programmer does is logical...)
>
> I rewrote it as /(^\s+|#.*)+$/ which to me is much safer and easier to
> understand too.
but not proper matching, it's already stopping at the first line comment
and therefore you get this ERROR messages as you get.
But anyway, your regex looks much better than my first try and I changed
my regex now to qr{(\s+|#.*)+} (the old one was running but awful to maintain)
or gr{
( # capture group 1
\s+ # one or more whitespace
| # or
\#.* # or anything starting with # before next \n
)+ # close capture group 1, one ore more repetitions
}x
your whitspace should not start with ^\s because then you get not
rid of the \n after #.*$.
Anyway Ives, working with your hint about Parse::RecDescent::skip
the result looks a little bit better:
> #!/usr/bin/perl
> use Parse::RecDescent;
> $Parse::RecDescent::skip = qr{(\s+|#.*)+};
> $RD_TRACE = 1;
> my $grammar =<<'EOGRAMMAR';
> file : int(s) /\z/
> | <error>
>
> int : /[+-]?\d+/
> | <error>
> EOGRAMMAR
>
> my $parser = Parse::RecDescent->new($grammar);
>
> my $text = <<'EOTEXT';
> # comment
> .123
> EOTEXT
>
> my $result = $parser->file($text);
ERROR (line 2): Invalid int: Was expecting /[+-]?\\d+/
ERROR (line 1): Invalid file: Was expecting int
but still complaining about ERROR in line 1, what is not
correct. Looking in the trace:
Parse::RecDescent: Treating "file :" as a rule declaration
Parse::RecDescent: Treating "int(s)" as a one-or-more subrule match
Parse::RecDescent: Treating "/\z/" as a /../ pattern terminal
Parse::RecDescent: Treating "| <error" as a new (error) production
Parse::RecDescent: Treating "<error>" as an error marker
Parse::RecDescent: Treating "int :" as a rule declaration
Parse::RecDescent: Treating "/[+-]?\d+/" as a /../ pattern terminal
Parse::RecDescent: Treating "| <error" as a new (error) production
Parse::RecDescent: Treating "<error>" as an error marker
| file |Trying rule: [file] |
| file | |" # comment\n .123\n"
| file |Trying production: [int /\z/] |
| file |Trying repeated subrule: [int] |
| int |Trying rule: [int] |
| int |Trying production: [/[+-]?\d+/] |
| int |Trying terminal: [/[+-]?\d+/] |
| int |<<Didn't match terminal>> |
| int | |".123\n"
| int |Trying production: [<error...>] |
| int | |" # comment\n .123\n"
| int |Trying directive: [<error...>] |
| int | |".123\n"
| int |<<Didn't match directive>> |
| int |<<Didn't match rule>> |
| file |<<Didn't match repeated subrule: |
| |[int]>> |
| file | |" # comment\n .123\n"
| file |Trying production: [<error...>] |
| file |Trying directive: [<error...>] |
| file |<<Didn't match directive>> |
| file |<<Didn't match rule>> |
it gets again stuffed back but the <error> directive spends a
different message. Has something to do how and when Damian
is using skip.
Regards and again thanks for your time
Charly
--
Karl Gaissmaier Computing Center,University of Ulm,Germany
Email:[email protected] Network Administration
Tel.: ++49 731 50-22499