#!/usr/bin/env perl use strict; use warnings; use Parse::RecDescent; use Data::Dumper; $::RD_ERRORS = 1; $::RD_WARN = 1; $::RD_HINT = 1; #$::RD_TRACE = 1; #$::RD_AUTOACTION = q { print Dumper \@item }; my $grammar = q{ { use Data::Dumper; sub unroll { my @list = @{$_[0]}; my $unrolled; for my $href (@list) { for my $key (keys %{$href}) { $unrolled->{$key} = $href->{$key}; } } return $unrolled; }; } Expression: Object(s) { $return = unroll($item[1]) } Object: String '{' Param(s) '}' { $return = { $item[1] => unroll($item[3]) } } Param: String '=' String { $return = { $item[1] => $item[3] } } | Object(s) { $return = unroll($item[1]) } String: /[\w\d]+/ { $return = $item[1] } }; my $parser = Parse::RecDescent->new($grammar); my $text = do { undef $/; }; my $tree = $parser->Expression($text) or die $!; $tree->{ObjectType1}{NestedObject}{DeeplyNested}{Param60} = 'tuna'; print Dumper $tree; __DATA__ ObjectType1 { Param1 = 8 Param2 = SomeText NestedObject { Param1 = 3 Param2 = MoreText DeeplyNested { Param50 = 500 Param60 = squid } } } ObjectType2 { Param1 = 3 Param2 = 40 }