Hi,

I'm struggling since few days, trying to parse text files,
which contain C and C++ comments, some #if/#else/#endif
statements and for the most part assignments happening 
on 1 line. The keyword in the beginning of the line is 
followed by space separated values.

I feel that I've done my homework by reading the FAQ and 
"man P::RD" and also searching the archives, but I must 
admit, that I had to omit some parts of the documentation 
I've read, since it was to difficult for me to grok.

My script is below, why doesn't it parse? I tried moving 
<skip: /[ \t]*/> from the chunk rule to:

        assignment: <skip: /[ \t]*/> keyword value(s) /\n/ 

but it didn't help... 2 additional questions: can I use the 
$1, $2 and so on captured in the regexes, as for example here:

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

Also, is there a way to specify the case-insensitive 
keyword terminals, without using regexes like /^SOURCE/im ?
I wonder also if I should have used /^SOURCE$/im there...

#!/usr/bin/perl -w

use strict;
use vars qw($parser $text @c_comment @cpp_comment @keyword @value);
use Parse::RecDescent;
$RD_WARN=1;
$RD_HINT=1;
$RD_TRACE = 1;

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

file: chunk(s) /^\Z/

chunk: comment | <skip: /[ \t]*/> assignment | <error>

comment: c_comment | cpp_comment

cpp_comment: m{//([^\n]*)} {    
        push @::cpp_comment, $1;
        1;
}

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

assignment: keyword value(s) /\n/ {
        push @::keyword, $item{keyword};
        push @::value, join ' ', @{$item{'value(s)'};
        1;
}

value: file | type | uid

file: m{[\w\\/.-]+}

type: /APP/i | /DLL/i

uid: /0x[0-9A-F]+/i

keyword: 
        /^AIF/im |
        /^DOCUMENT/im |
        /^LANG/im |
        /^LIBRARY/im |
        /^RESOURCE/im |
        /^SOURCE/im |
        /^SOURCEPATH/im |
        /^SYSTEMINCLUDE/im |
        /^TARGETPATH/im |
        /^TARGETTYPE/im |
        /^TARGET/im |
        /^UID/im |
        /^USERINCLUDE/im

)) or die 'Bad grammar';
$text .= $_ while (<DATA>);
defined $parser->file($text) or die 'bad text';

__DATA__

TARGET          CNetB.dll
TARGETTYPE      dll
UID                     0x10000e5e 0x102F43DB

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

/*
START WINS
BASEADDRESS     0x46200000
END

#if ( (defined ( WINS ) ) || ( defined (WINSCW) ) )
SOURCEPATH      ..\SwImp\src
SOURCE          CApiCamSpecsImpSw.cpp
#else
SOURCEPATH      ..\Mirage1\src
SOURCE          CApiCamHandlerImpMirage1.cpp
#endif
*/


Reply via email to