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



Reply via email to