use warnings; use strict; use Regexp::Grammars; my @blockstack; my $grammar = do { use Regexp::Grammars; qr{ \A (?: <.comment> | <[confblock]> )* \z ^ \{ (?: <[param]> | <[confblock]> | <.comment> )* \} <.ws> ^ = (?:\n|\z) ^ \h* \# [^\n]* (?:\n|\z) }xms }; my $data = do { local $/; }; $data =~ $grammar or die "failed to parse"; my %conf = %/; #/ use Data::Dump; dd \%conf; __DATA__ # comment ObjectType1 { Param1 = Foo NestedObject { Param1 = Bar } # just another comment } # comment ObjectType2 { Param1 = Quz NestedObject { Param1 = Baz } }