FAQ
Hi,

I'm trying convert few parsing modules from the functional
style (with exported functions) to OO-style with the data
stored in a blessed hash. I'm doing it, because I hope that
the modules will be easier to use and maintain (for example
I will give many functions the same name and override them...)

The shortest module I've listed on the bottom, it is not very complex.

My problem is, that currently I use global variables to store
the parsed out data. For example the directories found in the
"component" rule below are stored into a hash referenced by
the global variable $Nokia::Gen::subref.

When I now move to objects and to a constructor like:

sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
$self->{_PARSER} = Parse::RecDescent->new(GRAMMAR) or die 'Bad grammar';
bless $self, $class;
}

Then where do I save those dirs? $Nokia::Gen::self->{SUBREF}
wouldn't work since there is no such variable. And if I use
$main::parser->{SUBREF} then the variable name is hardcoded.

Regards
Alex


PS. Here is one of my modules:

package Nokia::Gen;

use strict;
use vars qw($parser $comref $optref $subref $VERSION @ISA @EXPORT);
use Exporter();
use Parse::RecDescent;
#$::RD_WARN = 1;
#$::RD_HINT = 1;
#$::RD_TRACE = 120;
$VERSION = 1.0;
@ISA = qw(Exporter);
@EXPORT = qw(&parseGenfile);

use constant GRAMMAR => q(

genfile: chunk(s) /^\Z/
chunk: comment | option | component | <error>

comment: /#([^\x0D\x0A]*)/ {
push @{$Nokia::Gen::comref}, $1;
}

option: /<OPTION\b/i /\w+/ optarg(?) '>' {
# for each option create an array holding optargs
push @{$Nokia::Gen::optref->{lc $item[2]}}, @{$item[-2]};
}
optarg: /\w+/

component: /\S+/ <skip: '[ \t]+'> dir {
# change backslahes to slashes
$item{dir} =~ s|\\\\+|/|g;
print STDERR "Warning: directory $item{dir} not found\n"
unless -d $item{dir};
print STDERR "Warning: directory $item{dir} listed multiple times\n"
if $Nokia::Gen::subref->{uc $item{dir}}++;
}
dir: /"([^"]*)"/ { $1 } | /\S+/

);

$parser = Parse::RecDescent->new(GRAMMAR) or die 'Bad grammar';

sub parseGenfile($$$$)
{
my $text = shift;
($comref, $optref, $subref) = @_;

defined $parser->genfile($text) or die 'Bad text';
}

1;

Search Discussions

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

    <Alexander.Farber@nokia.com> writes:
    Then where do I save those dirs? $Nokia::Gen::self->{SUBREF}
    wouldn't work since there is no such variable. And if I use
    $main::parser->{SUBREF} then the variable name is hardcoded.
    From the P::RD manpage, I've found

    $thisparser
    A reference to the Parse::RecDescent object through which
    parsing was initiated.

    Would this do what you need? Could you store directories as
    $thisparser->{DATA}{SUBREF}?

    /s
  • Nntp.perl.org at Aug 3, 2004 at 7:51 pm

    Sean O'Rourke wrote:
    <Alexander.Farber@nokia.com> writes:
    >
    Then where do I save those dirs? $Nokia::Gen::self->{SUBREF}
    wouldn't work since there is no such variable. And if I use
    $main::parser->{SUBREF} then the variable name is hardcoded.
    >
    >
    From the P::RD manpage, I've found >
    $thisparser
    A reference to the Parse::RecDescent object through which
    parsing was initiated. >
    Would this do what you need? Could you store directories as
    $thisparser->{DATA}{SUBREF}?
    or better: $thisparser->{local}{all}{of}{your}{data}
    ^^^^^

    I use the P::RD heavily in inheritance. But be aware, P::RD
    is inheritable but not the precompiled grammars!

    I wrote a patch (posted already on this list)
    news://nntp.perl.org:119/406F3D12.7020400@kiz.uni-ulm.de

    in order to solve this problem for a project of mine:
    Config::Scoped

    Study Config::Scoped for OO style parsers, and ask me if you
    have problems, but it's very well doceumented. It's released on
    CPAN. From the README:

    NAME

    Config:Scoped - feature rich configuration file parser


    FEATURES

    Config::Scoped has the following highlights as a configuration file
    parser:

    * Complex recursive datastructures to any extent with scalars,
    lists and hashes as elements,

    * As a subset parses any complex Perl datastructures
    (no references and globs) without *do* or *require*,

    * Include files with recursion checks,

    * Controlled macro expansion in double quoted tokens,

    * Lexically scoped parameter assignments and pragma directives,

    * Perl quote like constructs to any extent, '', "", and
    here docs <<,

    * Perl code evaluation in Safe compartments,

    * Caching and restore with MD5 checks to determine
    alterations in the original config files,

    * Standard macro, parameter, declaration redefinition
    validation, may be overridden to validate on semantic
    knowledge,

    * Standard file permission and ownership safety validation,
    may be overridden,

    * Fine control for redefiniton warnings with pragma's
    and other safety checks,

    * Easy inheritable, may be subclassed to build parsers
    with specialized validation features,

    * Condoning syntax checker, semicolons and or commas are not always
    necessary to finish a statement or a list item if the end can be
    guessed by other means like newlines, closing brackets,
    braces etc.,

    * Well spotted messages for syntax errors even within include
    files with correct line numbers and file names,

    * Exception based error handling,

    * etc.,

    PREREQUISITES

    Parse::RecDescent, Error

    Standard modules:

    Carp
    Storable
    File::Spec
    File::Basename
    Digest::MD5
    Safe

    APPETIZER

    Configuration file example:

    # default parameters
    community = public;
    variables = [ ifInOctets, ifOutOctets ];
    oids = {
    ifInOctets = 1.3.6.1.2.1.2.2.1.10;
    ifOutOctets = 1.3.6.1.2.1.2.2.1.16;
    };

    %warnings parameter off; ### allow parameter redefinition

    # declarations
    devices rtr001 {
    ports = [ 1, 2, 8, 9 ];
    }

    devices rtr007 {
    community = 'really top secret!';
    ports = [ 1, 2, 3, 4 ];
    }


    INSTALLATION

    It's all pure Perl.

    perl Makefile.PL
    make
    make test
    make install

    AUTHOR

    Karl Gaissmaier (karl.gaissmaier@kiz.uni-ulm.de)


    COPYRIGHT

    Copyright (c) 2004, Karl Gaissmaier. All Rights Reserved.
    This program is free software; you can redistribute it and/or
    modify it under the same terms as Perl itself.



    --
    Karl Gaissmaier KIZ/Infrastructure, University of Ulm, Germany
    Email:karl.gaissmaier@kiz.uni-ulm.de Service Group Network
  • Charly at Aug 3, 2004 at 8:02 pm
    Sorry for the above wrong Sender name, too many computers
    and not enough time.

    sigh

    Charly
    --
    Karl Gaissmaier KIZ/Infrastructure, University of Ulm, Germany
    Email:karl.gaissmaier@kiz.uni-ulm.de Service Group Network
  • Randal L. Schwartz at Aug 3, 2004 at 3:50 pm
    Completely ignoring the rest of your note, and obssessing on this
    one part:
    "Alexander" == Alexander Farber <Alexander.Farber@nokia.com> writes:
    Alexander> sub new {
    Alexander> my $proto = shift;
    Alexander> my $class = ref($proto) || $proto;

    Please don't do this. Read my rant at:

    <http://www.stonehenge.com/merlyn/UnixReview/col52.html>

    and note that the latest version of the "perldoc perltoot" where this
    abomination first appeared has been fixed in the latest Perl releases.

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
    <merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
    Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
    See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouprecdescent @
categoriesperl
postedAug 3, '04 at 12:28p
activeAug 3, '04 at 8:02p
posts5
users4
websitemetacpan.org...

People

Translate

site design / logo © 2019 Grokbase