Re: problem filling a data structure

[email protected] (Marcel Grunauer)
Newsgroups perl.recdescent
Message-ID <20011030204352.IOXU9577.viefep11-int.chello.at@localhost>
On Tuesday, October 30, 2001, at 04:27  PM, Your Friend wrote:

> I have a data structure which is
>
> a hash of entries
> where
> an entry is a list/array of sets

....

> Problem: I cannot figure out how to actually FILL the parsed data into
> the structure. I can only decide if a string is grammatically correct
> or not.

Try this grammar, which you have to feed the input as one big
string. It uses a global variable, $::res into which the results
are assembled. At the end the variable is also returned for
convenience.

It basically parses a phrase and a list of meanings. Instead of
reconstructing what it just parsed at each step, it checks the
remaining text at various stages (using an idea taken from
Parse::RecDescent::Consumer) to see what the 'phrase' or 'meaning'
subrules just matched. The 'meanings' subrule then (implicitly)
returns a reference to an array of 'meaning' strings. That arrayref
is stored at the proper slot in the result hash.

(Hope that explanation makes sense. I'm sure Damian can come up
with a grammar that's way more elegant and efficient...)


{ sub consumer {
         my $text = shift;
         my $closure = sub { substr $text, 0, length($text) - 
length($_[0]) }
} }

start : entry(s) { $::res }

entry :
           comment
         | def
         | <error>

def : <rulevar: local $p_cons>
def : <rulevar: local $p_text>

# The // skips initial whitespace so it won't end up in $p_text

def :
     // { $p_cons = consumer($text) } phrase { $p_text = 
$p_cons->($text) }
     '=' meanings ';'
     { $::res->{$p_text} = $item{meanings} }

comment : /#.*(?=\n)/m

phrase  : ident(s)

ident   : /[\w&\.'-]+/

meanings : meaning(s /:/)

meaning : <rulevar: local $m_cons>
meaning : // { $m_cons = consumer($text) } element(s /,?/) 
{ $m_cons->($text) }

element : alternation(s /\|/)

alternation : expr(s /[+>]/)

expr : /!?/ term

term : ident '(' meaning ')' | ident



Marcel

--
Aspect-Oriented Perl            http://codewerk.unixbeard.net/aspects/
cpan> install Aspect
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.