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