Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??

My concept is to wrap some configuration management command lines in a Perl framework to expose the command options along with other configuration data in a standard configuration file. For the design, I've "drawn" these boxes in my head (and now in ASCII art):

/--------------\ /------------\ /-----------\ /------------\ / +--------\ | | | | | | | | | + | | command line |-->| Parse:: |-->| Data |-->| Data:: |-->| + XML | | string |<--| RecDescent |<--| structure |<--| Serializer |<--| + FILE | | | | | | | | | | + | /--------------\ /------------\ /-----------\ /------------\ / +--------\ ^ | /------------\ | | | command | | line | | grammar | | | /------------\

In the proof-of-concept stage, I've had some successes and some setbacks. PerlMonks++ to Niel Neely, the maintainer of Data::Serializer, for responding VERY quickly to a bug. Data::Serializer 0.44 includes this patch and lets me use XML::Dumper in raw mode with store and retrieve. Niel was very responsive and the patch is working great.

On the Parse::RecDescent side, I read the tutorial and wrote a simple grammar, passed alot of command line strings through it successfully to get the data structure to serialize, serialized it and deserialized it. I got stuck when I realized that Parse::RecDescent::Deparse didn't deparse my data structure into a command line string, but instead deparsed my parser into a grammar (should've rtfm before I got this far, I guess)!

Now I could write a function to take my datastructure and turn it into a command line string, but it seems a shame that I've gone to the trouble of writing a grammar to define how to go one direction, but can't use the same grammar to go the other direction. Especially if I intend to change and expand the grammar, I would like that to be the end of it and not have to also change the deparsing function.

So, now I have some questions:
Academic questions:

  • Is it necessarily possible to reverse the data through the grammar to get the command line?
  • or is this only possible for special grammars?
  • Is there something I need to in my grammar to make this possible?
Design decisions:
  • Is there a module that already reverses the parsing of Parse::RecDescent parsers?
  • Is there another module that makes this bi-directionality easier (I'd prefer not to learn another grammar specification syntax, but could)?
  • Is there a module that already does all this soup-to-nuts?

And finally, the infamous "what I've already done". This is grammarharness.pl:

#/usr/bin/perl -Wl use strict; use warnings; use Parse::RecDescent; use Data::Dumper; use Data::Serializer; my $grammar; my $grammarfile = $ARGV[0]; open my $gf,'<',$grammarfile or die 'bad grammarfile'; while (<$gf>) { $grammar.=$_; } close $gf; print '$grammar is ',"\n",$grammar; $::RD_HINT++; #$::RD_TRACE++; my $parser = new Parse::RecDescent ($grammar) or die 'bad grammar'; my $stringtoparsefile = $ARGV[1]; open my $sf,'<',$stringtoparsefile or die 'bad stringstoparse file'; my $result; my $reresult; #Data::Serializer 0.44 supports raw=> my $serializer = Data::Serializer->new(raw=>'1',serializer => 'XML::Du +mper'); my $outfilebasename = 'data'; my $outfileext = 'out'; my $outfileindex = 10; while (<$sf>) { print 'parsing $_: ',$_; if (defined $parser->startrule($_)){ $result = $parser->startrule($_); print Dumper($result); $serializer->store( $result, $outfilebasename.$outfileindex.'.'.$outfileext, '>>' ); $reresult = $serializer->retrieve( $outfilebasename.$outfileindex++.'.'.$outfileext, ); print Dumper($reresult); }else{ print " badstring\n"} }

This is packagegrammar.txt:
startrule: commandline{$item{commandline}} commandline: command options {[$item {command},$item{options}]} command: packagecommand {$item{packagecommand}} packagecommand: /(hap)/ | /(hccmrg)/ | /(hup)/ | /(hspp)/ | /(hpp)/ | +/(hpg)/ | /(hdp)/ | /(hdlp)/ | /(hcp)/ options: option(s?) option: optionflag optionvalue { [$item{optionflag}, $item{optionvalue +}?$item{optionvalue}:1] } optionflag: /(-\w+)/ { $1 } optionvalue: /(\w*)/ { $1 }

This is packagecommands.txt:
hap -b hap -b sknxharvest01 hap -b sknxharvest01 -enc testfile.dfo hap -b sknxharvest01 -usr cgowing -pass chaspass hap -badflag hap -prompt hap -b sknxharvest01 -prompt hap -prompt -b sknxharvest01

how it works (nothing particularly wrong here; it mostly proves all the working parts without attempting the deparse):
C:\chas_sandbox\grammars>grammarharness.pl packagegrammar.txt packagec +ommands.tx t $grammar is startrule: commandline{$item{commandline}} commandline: command options {[$item {command},$item{options}]} command: packagecommand {$item{packagecommand}} packagecommand: /(hap)/ | /(hccmrg)/ | /(hup)/ | /(hspp)/ | /(hpp)/ | +/(hpg)/ | /(hdp)/ | /(hdlp)/ | /(hcp)/ options: option(s?) option: optionflag optionvalue { [$item{optionflag}, $item{optionvalue +}?$item{op tionvalue}:1] } optionflag: /(-\w+)/ { $1 } optionvalue: /(\w*)/ { $1 } parsing $_: hap -b $VAR1 = [ 'hap', [ [ '-b', 1 ] ] ]; $VAR1 = [ 'hap', [ [ '-b', '1' ] ] ]; parsing $_: hap -b sknxharvest01 $VAR1 = [ 'hap', [ [ '-b', 'sknxharvest01' ] ] ]; $VAR1 = [ 'hap', [ [ '-b', 'sknxharvest01' ] ] ]; parsing $_: hap -b sknxharvest01 -enc testfile.dfo $VAR1 = [ 'hap', [ [ '-b', 'sknxharvest01' ], [ '-enc', 'testfile' ] ] ]; $VAR1 = [ 'hap', [ [ '-b', 'sknxharvest01' ], [ '-enc', 'testfile' ] ] ]; parsing $_: hap -b sknxharvest01 -usr cgowing -pass chaspass $VAR1 = [ 'hap', [ [ '-b', 'sknxharvest01' ], [ '-usr', 'cgowing' ], [ '-pass', 'chaspass' ] ] ]; $VAR1 = [ 'hap', [ [ '-b', 'sknxharvest01' ], [ '-usr', 'cgowing' ], [ '-pass', 'chaspass' ] ] ]; parsing $_: hap -badflag $VAR1 = [ 'hap', [ [ '-badflag', 1 ] ] ]; $VAR1 = [ 'hap', [ [ '-badflag', '1' ] ] ]; parsing $_: hap -prompt $VAR1 = [ 'hap', [ [ '-prompt', 1 ] ] ]; $VAR1 = [ 'hap', [ [ '-prompt', '1' ] ] ]; parsing $_: hap -b sknxharvest01 -prompt $VAR1 = [ 'hap', [ [ '-b', 'sknxharvest01' ], [ '-prompt', 1 ] ] ]; $VAR1 = [ 'hap', [ [ '-b', 'sknxharvest01' ], [ '-prompt', '1' ] ] ]; parsing $_: hap -prompt -b sknxharvest01 $VAR1 = [ 'hap', [ [ '-prompt', 1 ], [ '-b', 'sknxharvest01' ] ] ]; $VAR1 = [ 'hap', [ [ '-prompt', '1' ], [ '-b', 'sknxharvest01' ] ] ]; C:\chas_sandbox\grammars>type data10.xml <perldata> <arrayref memory_address="0xdee0b8"> <item key="0">hap</item> <item key="1"> <arrayref memory_address="0xd67300"> <item key="0"> <arrayref memory_address="0xdee28c"> <item key="0">-b</item> <item key="1">1</item> </arrayref> </item> </arrayref> </item> </arrayref> </perldata> C:\chas_sandbox\grammars>


#my sig used to say 'I humbly seek wisdom. '. Now it says:
use strict;
use warnings;
I humbly seek wisdom.

In reply to Reversible parsing (with Parse::RecDescent?) by goibhniu

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others chilling in the Monastery: (8)
    As of 2015-07-08 06:04 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









      Results (94 votes), past polls