Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
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
  • Outside of code tags, you may need to use entities for some characters:
            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 romping around the Monastery: (6)
    As of 2014-09-30 21:19 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      How do you remember the number of days in each month?











      Results (384 votes), past polls