keyword value(s) newline
[email protected] Wed, 12 May 2004 11:27:57 +0200
| Newsgroups | perl.recdescent |
|---|---|
| Message-ID | <[email protected]> |
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
*/