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

Reply via email to