Alexander Farber wrote:
Just to rephrase my question.
From my grammar I can save the parsed out data into global variables,
like $::subdirs or $MyModule::subdirs. That works fine.
But how can I do it in OO-way, i.e. save data to $obj1->{subdirs} and then
parse another input text by the same parser and save it to $obj2->{subdirs} ?
see my complete OO Style example. Hope this helps.
Anyway, your grammar looks a little bit odd, don't know
what your "component" will be.
Anyway, the OO trick with P::RD is:
No logic in the grammar, all actions just call a $thisparser->method.
Collect the data under $thisparser->{local}...
and much more tricks in Config::Scoped.
Someone should write tis in the FAQ (a native speaker :-)
but it seems there is currently no FAQ P::RD::maintainer?
Happy parsing
Charly
--
Karl Gaissmaier KIZ/Infrastructure, University of Ulm, Germany
Email:[EMAIL PROTECTED] Service Group Network
#!/usr/bin/perl
#########################################################
# MAIN
#########################################################
use warnings;
use strict;
use Data::Dumper;
#$::RD_HINT = 1;
#$::RD_TRACE = 20;
my $text = join '', <>;
my $parser = Nokia::Gen->new;
$parser->parse($text);
print Dumper( $parser->{local} );
exit 0;
#########################################################
# PARSER PACKAGE
#########################################################
package Nokia::Gen;
use warnings;
use strict;
use base 'Parse::RecDescent';
#
# PUT NO LOGIC INTO GRAMMARs!
# just use method calls, easy to debug and and and ...
#
use constant GRAMMAR => <<'EOGRAMMAR';
genfile: chunk(s) /^\Z/
chunk: comment | option | component | <error>
comment: /#.*$/
{
$thisparser->_comment( $item{__PATTERN1__} );
}
# hmm, optarg(?) or optarg(s), anyway see the OO style
option: /<OPTION\b/i /\w+/ optarg(s) '>'
{
$thisparser->_option( $item{__PATTERN2__}, $item{'optarg(s)'} );
}
optarg: /\w+/
# this rule seems to me very suspect, anyway just see the OO style
component: /\S+/ <skip: '[ \t]+'> dir
{
$thisparser->_component( $item{dir} );
}
# seems to be very greedy, anyway it's your grammar ;-)
dir: /"[^"]*"/ | /\S+/
EOGRAMMAR
#####################################################
# constructor und parse method
#
sub new {
my $class = shift;
my $thisparser = $class->SUPER::new(GRAMMAR);
# set your local parameters
$thisparser->{local}{comments} = [];
$thisparser->{local}{options} = {};
$thisparser->{local}{directories} = {};
return $thisparser;
}
#####################################################
# public object methods
#
sub parse {
my ( $thisparser, $text ) = @_;
return $thisparser->genfile($text);
}
#####################################################
# private methods = ACTIONs
#
sub _comment {
my ( $thisparser, $comment ) = @_;
push @{ $thisparser->{local}{comments} }, $comment;
return 1; # rule success
}
sub _option {
my ( $thisparser, $option_name, $option_list ) = @_;
$option_name = lc $option_name;
$thisparser->{local}{options}{$option_name} = $option_list;
return 1; # rule success
}
sub _component {
my ( $thisparser, $dir ) = @_;
$dir =~ s|\\\\+|/|g;
warn "Warning: directory $dir not found\n"
unless -d $dir;
warn "Warning: directory $dir listed multiple times\n"
if $thisparser->{local}{directories}{ uc $dir }++;
return 1; # rule success
}
1; # keep require happy