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
*/