Hi, thanks a lot for your reply. I still have quite many 
questions though (my current testcase script is at the bottom):

> -----Original Message-----
> From: ext Ron D. Smith [mailto:[EMAIL PROTECTED]
> > 1) you did not read the section on "skip" very carefully.

The "Skipping between terminals" section in the man doesn't tell 
explicitly that <skip: /regex/> is not supported. There is an example

        <skip: qr/[:,]/>

and I had been misleaded by that.

> > 2) you do not have balanced delimiters in your parse description

Could you please tell a bit more, what do you mean here? 

I have different delimiters in my input text: C-style comments, 
#if/#else/#endif, then quotes surrounding some file paths and 
also the START/END structures like this one:

        START RESOURCE WapBaseErr.rss
        TARGETPATH      \SYSTEM\ERRORS
        LANG            01
        END

Do you mean there is some special way to handle those? Should I somehow 
use Text::Balanced? I don't know yet, how could I connect it to P::RD.

> > 3) the second production in the chunk rule does not 
> eliminate leading newlines
> > 4) You did not look at the trace results that you printed 
> out very carefully, 

I do look at the trace, but P::RD is a tough module. For example
I'm irritated by its rightmost column. Near the top it shows:

|c_comment |<<Didn't match rule>>                 |
| comment  |<<Didn't match subrule: [c_comment]>> |
| comment  |Trying production: [cpp_comment]      |
| comment  |                                      |"\nTARGET
|          |                                      |CNetB.dll\nTARGETTYPE
|          |                                      |dll\nUID 0x10000E5E
                                                                                       
 ....
|          |                                      |sdpagent.lib\n\n"
| comment  |Trying subrule: [cpp_comment]         |
|cpp_commen|Trying rule: [cpp_comment]            |
|cpp_commen|Trying production: [m{//\s*(.*)}]     |
|cpp_commen|Trying terminal: [m{//\s*(.*)}]       |
|cpp_commen|<<Didn't match terminal>>             |
|cpp_commen|                                      |"TARGET CNetB.dll\nTARGETTYPE
|          |                                      |dll\nUID 0x10000E5E
                                                                                       
 .....
|          |                                      |sdpagent.lib\n\n"

Does the rightmost column hold the content of $text? Why does it
tell first "Trying production" and shows "\nTARGET", but below
it tells "Didn't match" and shows "TARGET" without the newline?

I would expect it another way around: before the production 
is tried, the stuff matching $skip is removed isn't it? 
So it should actually show "TARGET", not "\nTARGET" there.

> chunk: comment | <skip: /[ \t]*/> assignment | <error>
> > 5) the item hash does not include the modifiers in the name space.

I see, thanks!

> > 7) the path delimiter in windoze (you poor soul...) is '\' not '/'

I'm porting that mess to Unix :-) So I'll leave the / there.

> assignment: keyword  <skip: '[ \t]*'> value(s)  <skip: $item[2]>  {
>       push @::keyword, $item{keyword};
>       push @::value, join ' ', @{$item{'value'}};
>       1;
> }

Is restoring the $skip = '\s*' above really needed?

And finally my biggest problem right now - the "keyword value(s)"
rule is too greedy and consumes the "// added on 01.01.2002" comment, 
as if it were "file"s:

         'LIBRARY' => [
                        'euser.lib',
                        'efsrv.lib',
                        'c32.lib',
                        '//',
                        'added',
                        'on',
                        '01.01.2002',
                        'esock.lib',
                        'bluetooth.lib',
                        'btdevice.lib',
                        'btmanclient.lib',
                        'btextnotifiers.lib',
                        'sdpagent.lib'
                      ],

How could I prevent it? 

Regards
Alex

#!/nokia/apps/tww/@sys/bin/perl -w

use strict;
use vars qw($parser $text @c_comment @cpp_comment %hol);
use Data::Dumper;
use Parse::RecDescent;
$RD_WARN = 1;
$RD_HINT = 1;
$RD_TRACE = 1;

$parser = Parse::RecDescent->new(q(

mmpfile: chunk(s) /^\Z/
chunk: comment | assignment | <error>
comment: c_comment | cpp_comment

c_comment: m{/[*]\s*(.*?)[*]/}s {
        push @::c_comment, $1;
}

cpp_comment: m{//\s*(.*)} {     
        push @::cpp_comment, $1;
}

assignment: keyword <skip: '[ \t]*'> value(s) {
        # add values to the hash of lists, with key = keyword
        push @{$::hol{uc $item{keyword}}}, @{$item{value}};
}

value: file | type | uid
file: m{[\w\\\\/.-]+}
type: /APP/i | /DLL/i

uid: /0x[0-9A-F]+/i | /\d+/ {
        # positive hex or decimal number
        $item[1];
}

keyword: 
        /^LIBRARY/im |
        /^SOURCEPATH/im |
        /^SOURCE/im |
        /^SYSTEMINCLUDE/im |
        /^TARGETPATH/im |
        /^TARGETTYPE/im |
        /^TARGET/im |
        /^UID/im |
        /^USERINCLUDE/im

)) or die 'Bad grammar';
$text .= $_ while (<DATA>);
defined $parser->mmpfile($text) or die 'bad text';
print Data::Dumper->Dump([\%hol,
                          [EMAIL PROTECTED],
                          [EMAIL PROTECTED],
                          [qw(hol c_comment cpp_comment)]);
__DATA__

TARGET          CNetB.dll
TARGETTYPE      dll
UID                     0x10000E5E 1028888

SOURCEPATH      ..\NetBSrc 
SOURCE          CNetB.cpp  CNetBSerialBase.cpp CNetBBluetoothModule.cpp
SOURCE          CSnakeActiveWrapper.cpp

USERINCLUDE     ..\NetBInc
SYSTEMINCLUDE   \Epoc32\include \Epoc32\include\oem

LIBRARY         euser.lib efsrv.lib c32.lib // added on 01.01.2002
LIBRARY         esock.lib bluetooth.lib btdevice.lib btmanclient.lib
LIBRARY         btextnotifiers.lib sdpagent.lib

Reply via email to