#!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11147096 use warnings; sub expr { my $val = []; $val = /\G\s+/gc ? $val : /\G([^{}\s]+)/gc ? do { my $key = $1; [ @$val, /\G \{/gc ? { $key => (expr(), /\G\}/gc || die ' missing } ')[0] } : /\G "(.*?)"/gc ? { $key => $1 } : $key ] } : return ref $val eq 'ARRAY' && ( @$val == grep ref $_ eq 'HASH', @$val ) ? { map %$_, @$val } : $val while 1 } sub parse { local $_ = join '', @_; my $parse = expr; pos($_) == length $_ or die "incomplete parse stopped at ", substr $_, pos($_); return $parse; } my $parse = parse( ); $Data::Dump::LINEWIDTH = 26; use Data::Dump 'dd'; dd $parse; __DATA__ sys ecm cloud-provider /Common/aws-ec2 { description "The aws-ec2 parameters" property-template { account { } availability-zone { valid-values { a b c d } } instance-type { valid-values { t2.micro t2.small t2.medium } } region { valid-values { us-east-1 us-west-1 } } } }