problem filling a data structure

[email protected] (Your Friend)
Newsgroups perl.recdescent
Message-ID <[email protected]>
Hello RecDescent Masters.

I´m not able to reach Perlmonks.org for nearly a week now, so I try to
find here an answer for a problem that I´m not able to solve with
RecDescent.

I have a data structure which is

a hash of entries
where
an entry is a list/array of sets

I have also a grammar that can parse the syntax of the text files that
contain the data I want to fill this structure with. Until here
everything is ok.

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.

Heres the grammar:

--SNIP
sub newfacts {
    return new Parse::RecDescent (q{
        
      entry:       phrase '=' meanings ';'
                   { print "FINAL: $item[1] = $item[3]\n";
                     return "$item[1] = $item[3]"; }
                 | 
                     { return 0; }
        
      word:        /[\w\-\&\.äãâáàåæçðëêéèïîíöôóòôøüûúñßÿ']+/   #'
                     { $return = $item[1]; }
                     
      phrase:      word(s)
                     { $return = join ' ', @{$item[1]}; }
                     
      property:   '!' property
                     { $return = "!$item[2]"; }
                 | phrase '(' proplist ')'
                     { $return = "$item[1]($item[3])"; }                     
                 | phrase
                     { $return = $item[1]; }
                     
      meaning:     expr log meaning
                     { 
                       $return = "$item[1] $item[2] $item[3]"; }
                 | expr
                     { 
                       $return = $item[1]; }

      proplist:    expr log proplist
                     { $return = "$item[1] $item[2] $item[3]"; }
                 | expr
                     { $return = $item[1]; }

      meanings:    meaning ':' meanings
                     { 
                       $return = "$item[1] : $item[3]"; }
                 | meaning
                     { 
                       $return = $item[1]; }
                     
      expr:        property
                     { $return = $item[1]; }
                 | '(' property log property ')' 
                     { $return = "($item[2] $item[3] $item[4])"; }
                     
      log:         ','     { $return = ","; }            # AND
                 | '|'     { $return = "|"; }            # OR
                 | '+'     { $return = "+"; }            # XOR
                 | '>'     { $return = ">"; }            # IMP
                 | '!' log { $return = "!$item{log}"; }  # negiert
        });
}
--SNIP

You may ask why proplist and meaning are identical. Thats because
proplist is meaning, but should be treated differently. proplist
should be added to the data structure just as string, where meaning is
already a set.

And heres an example of a file to parse:

--SNIP
#
# BEGIN TEST
#
 
# Test: word
a = b;
 
# Test: phrase
mao tse tung = communist leader;
 
# Test: simple property
b = Hypothenuse(lang);
 
# Test: complex property
c = a(b, !d | e, f+k(j));
 
# Test: simple property list
#
g = h, i j1, l(m), z(z(u)), 123, 12-3-44, 12.3.22;
 
#
# Test: complex property list
#
h = h, i j a(b, !d | e, f+k(j)), l(m>n);
 
#
# Test: List of meanings
#
j =   a(o), b(haha hehe)
    : b,z
    : c(g(x));
--SNIP

Oh yes - because the files can/could be parsed incrementally, the
parser shall just look at ONE entry and parse that. The loop for whole
files is wrapped around the calls to $parser->entry($entry);

Now the exact description of the problem and what I´ve tried:

I tried to define a

{ my @meanings;
  my $tset = Set::Scalar->new;
}

as a startup action, and then tried to fill those in actions:

      meaning:     expr log meaning
                     { $tset->insert($item[1]);
                       $return = "$item[1] $item[2] $item[3]"; }
                 | expr
                     { $tset->insert($item[1]);
                       $return = $item[1]; }

      meanings:    meaning ':' meanings
                     { push @meanings,$item[1];
                       $tset->clear;
                       $return = "$item[1] : $item[3]"; }
                 | meaning
                     { push @meanings,$item[1];
                       $tset->clear;
                       $return = $item[1]; }


Of course it didn´t work because an autoaction is just done at compile
time (of the parser) and therefore meanings grew and grew.
Because of both speed and space reasons I cannot create a new parser
each time an entry-object (array of sets) is created, because then
parsing of a 50000 entry file would take a week and it would take
about 500MB of memory (because every entry-object would also hold an
instance of the parser.

I tried to dig here and there, but now is the 4th day and I´m making
no real advancement. I´ve read the Parse::RecDescent docs at
http://www.enstimac.fr/Perl/perl5.6.0/site_perl/5.6.0/Parse/RecDescent.html#rules
forth and back (ok I understood 40% at best) but cannot find a
solution for the problem.

If I could give the parser more than one argument it would
help. Something like

$parser->entry($string_to_parse,$reference_to_an_entry);


Any hints?

Bye
   Richard
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.