Parsing "start ... end" - with symbolic refs?
[email protected] ((Alexander Farber)) Mon, 17 May 2004 01:35:03 +0000
| Newsgroups | perl.recdescent |
|---|---|
| Message-ID | <[email protected]> |
Hi,
I have a text consisting of keyword/value assignments,
placed on 1 line (please see the __DATA__ on the bottom).
Some of the assignments are surrounded by START/END:
START WINS
key1 val1 val2
END
START MARM
key1 val1
END
I would like to capture all of the assignments into hashes
of lists. The top-level assignments should go into %hol,
and the START/END-surrounded assignments should go into
%wins and %marm. I'm trying to achieve this by passing the
platform name (the word following START) as an argument to
the assignment rule and by using that name (lowercased) as
a symbolic reference.
Unfortunately my script listed below dies with the error:
Can't use string ("::hol") as a HASH ref while "strict refs"
in use at (eval 18) line 303, <DATA> line 6.
Why does it mention "strict refs"? I'm explicitly setting
"no strict 'refs'" on the top of my script.
Also, I wonder if there is a nicer way to solve my problem.
The START/END areas do not nest, they are all 1-level deep.
Thank you
Alex
use strict;
no strict 'refs';
use vars qw($parser $text %hol %wins %marm);
use Data::Dumper;
use Parse::RecDescent;
$RD_WARN = 1;
$RD_HINT = 1;
$RD_TRACE = 120;
$parser = Parse::RecDescent->new(q(
mmpfile: chunk(s) /^\Z/
chunk: assignment[$arg[0]] | local | <error>
assignment: keyword <skip: '[ \t]+'> value(s) {
my $hname = lc $arg[0] || 'hol';
push @{${"::$hname"}{uc $item{keyword}}}, @{$item[3]};
}
local: /start/i <skip: '[ \t]+'> platform
<skip: $item[2]> chunk[$item[3]](s?)
/end/i { print "ITEM3: $item[3]\n" }
value: /val\d+/i
keyword: /key\d+/i
platform: /wins/i || /marm/i
)) or die 'Bad grammar';
$text .= $_ while (<DATA>);
defined $parser->mmpfile($text) or die 'bad text';
print Data::Dumper->Dump([\%hol,
\%wins,
\%marm],
[qw(hol wins marm)]);
__DATA__
key1 val1
START WINS
key2 val2 val3
END