in reply to Parsing a config file with braces and nested braces
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" }, ], }, ], }, ], }, ], }, ]
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Parsing a config file with braces and nested braces
by Anonymous Monk on Jan 08, 2015 at 08:42 UTC | |
|
Re^2: Parsing a config file with braces and nested braces
by Anonymous Monk on Jan 08, 2015 at 04:06 UTC | |
by Anonymous Monk on Jan 08, 2015 at 08:53 UTC |