FW: Using $skip='[ \t]+' to parse line(s)
[email protected] Thu, 13 May 2004 23:50:43 +0200
| Newsgroups | perl.recdescent |
|---|---|
| Message-ID | <[email protected]> |
Sorry, but few more questions.
Since the text I'm trying to parse consists mostly
of 1-line statements, I've decided to try parsing it
with the $Parse::RecDescent::skip set to '[ \t]*':
#!/usr/bin/perl -w
use strict;
use vars qw($parser $text %hol);
use Data::Dumper;
use Parse::RecDescent;
$Parse::RecDescent::skip = '[ \t]*';
$RD_HINT = 1;
$RD_TRACE = 1;
$parser = Parse::RecDescent->new(q(
mmpfile: line(s) /^\Z/
line: assignment | <error>
assignment: keyword value(s) /\n/ {
# add 1 or more values to the hash of lists
push @{$::hol{uc $item{keyword}}},
ref $item{value} ? @{$item{value}} : $item{value};
}
keyword: /key\d+/
value: /val\d+/
)) or die 'Bad grammar';
$text = "key1 val1\nkey2 val2 val3\n";
defined $parser->mmpfile($text) or die 'bad text';
print Data::Dumper->Dump([\%hol], ['hash of lists']);
And here are the problems I have:
1) Using '[ \t]+' as the skip value fails with
4| keyword |Trying terminal: [/key\d+/] |
4| keyword |<<Didn't match terminal>> |
Does this mean, the $Parse::RecDescent::skip is _always_
inserted in front of every terminal and thus has to match,
even if trivially?
2) For some strange reason the script above omits the actual
values even though I see that /val\d+/ matched in the trace:
4| value |Trying terminal: [/val\d+/] |
4| value |>>Matched terminal<< (return value: |
| |[val2]) |
4| value | |" val3\n"
4| value |>>Matched production: [/val\d+/]<< |
4| value |>>Matched rule<< (return value: |
| |[val2]) |
4| value |(consumed: [ val2]) |
.......
$hash of lists = {
'KEY2' => [
undef
],
'KEY1' => [
undef
]
};
Why do I have undefs above? I've tried changing the terminal to:
value: /val\d+/ { $item[1] }
since the "value" is what's being push()ed. But it didn't help.
3) And the last problem is: what to do, if the last line in the
parsed text isn't terminated by a newline? I can not write
assignment: keyword value(s) /\n|\Z/
since it will eat the EOF and the top rule will fail. Should I write
assignment: keyword value(s) /\n?/
(which seems to work)?
Regards
Alex