If there's an existing module that can handle your configuration file format, then it is always preferable to use that over DIY. But since I haven't written a grammar in a while I thought it would be a nice exercise. (That also means I'm a bit rusty and it may not be coded optimally.) I used Regexp::Grammars, but there are a few other similar modules out there, a classic being Parse::RecDescent.

The $MATCH lines control the data that is returned and reduce it from what Regexp::Grammars normally produces (to see what that is, remove the $MATCH lines). The data structure is still kind of overly complex and deeply nested, that's because I thought it might be better to initially keep the ordering of all items intact. If your config blocks don't contain duplicate keys and the order doesn't matter then of course they can be reduced down to regular hashes. I also took the liberty of allowing the config values surrounded by brackets to be interpreted as whitespace separated lists, I'm not sure if that's how your config format works or not.

use warnings; use strict; use 5.010; # required for Regexp::Grammars my $parser = do { use Regexp::Grammars; qr{ <[Block]>* <rule: Block> <BlockName=Word> \{ <[BlockItem]>* \} (?{ $MATCH = { $MATCH{BlockName} => $MATCH{BlockItem} } }) <rule: BlockItem> (?: <Block> | <KeyValue> ) (?{ $MATCH = $MATCH{KeyValue} || $MATCH{Block} }) <rule: KeyValue> <Key=Word> (?: <Value=Word> | \[ <[Value=Word]>* % \s+ \] ) \; (?{ $MATCH = { $MATCH{Key} => $MATCH{Value} } }) <token: Word> [\w-]+ } }; my $input = do { open my $fh, '<', '1112435.txt' or die $!; local $/; <$fh> }; $input =~ $parser or die "Failed to parse input"; use Data::Dump 'pp'; say pp $/{Block};

And finally, the output for your current example:

[ { bob => [ { ed => [ { larry => [ { rule5 => [ { option => [{ "disable-server-response +-inspection" => "no" }] }, { tag => ["some_tag"] }, { from => ["prod-L3"] }, { to => ["corp-L3"] }, { source => ["any"] }, { destination => ["any"] }, { "source-user" => ["any"] }, { category => ["any"] }, { application => ["any"] }, { service => ["any"] }, { "hip-profiles" => ["any"] }, { "log-start" => "no" }, { "log-end" => "yes" }, { "negate-source" => "no" }, { "negate-destination" => "no" }, { action => "allow" }, { "log-setting" => "orion_log" }, ], }, { rule6 => [ { option => [{ "disable-server-response +-inspection" => "no" }] }, { tag => ["some_tag"] }, { from => ["prod-L3"] }, { to => ["corp-L3"] }, { source => ["any"] }, { destination => ["any"] }, { "source-user" => ["any"] }, { category => ["any"] }, { application => ["any"] }, { service => ["any"] }, { "hip-profiles" => ["any"] }, { "log-start" => "no" }, { "log-end" => "yes" }, { "negate-source" => "no" }, { "negate-destination" => "no" }, { action => "allow" }, { "log-setting" => "orion_log" }, ], }, ], }, ], }, ], }, ]

In reply to Re: Parsing a config file with braces and nested braces by Anonymous Monk
in thread Parsing a config file with braces and nested braces by IamtheGorf

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!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • 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, details, 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, summary, 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.