FAQ
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} ?

Search Discussions

  • Sean O'Rourke at Aug 3, 2004 at 4:16 pm

    <Alexander.Farber@nokia.com> writes:

    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} ?
    my $g = new Parse::RecDescent <<'EOG';
    thing: dir(s)

    dir: /some_regex/ { $thisparser->{DATA}->subdirs($item[1]) }

    EOG
    $g->{DATA} = new Obj;
    $g->thing($text);
    print $g->{DATA}->subdirs();

    $g->{DATA} = new Obj;
    $g->thing($text);
    print $g->{DATA}->subdirs();

    # ...

    /s
  • Charly at Aug 3, 2004 at 9:35 pm

    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:karl.gaissmaier@kiz.uni-ulm.de 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

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouprecdescent @
categoriesperl
postedAug 3, '04 at 4:00p
activeAug 3, '04 at 9:35p
posts3
users3
websitemetacpan.org...

People

Translate

site design / logo © 2019 Grokbase