RE: keyword value(s) newline
[email protected] Thu, 13 May 2004 19:18:10 +0200
| Newsgroups | perl.recdescent |
|---|---|
| Message-ID | <[email protected]> |
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, \@c_comment, \@cpp_comment], [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