package Config::Format::Ini::Grammar; use Parse::RecDescent; use strict; my $gram = <<'END_GRAMMAR' ; { my $h ; use Data::Dumper; my %esc = map {$_ => pack 'H2', $_} 0..255; @esc{ '\n', '\t', '\r', '\a' } = ( "\n", "\t", "\r", "\a" ); sub merge2hash { my $aref = shift; my $h; ref eq 'HASH' and @{$h}{keys %$_} = values %$_ for @$aref; $h; } sub postprocess { local $_ = shift ||return; s/ \\x([\d]{1,3})/ $esc{ "$1"+0 } /egx; s/ (\\[ntra]) / $esc{$1} /xge; $_ ; } } startrule : Section(s) { $return = merge2hash( $item[2]) } Section: Title "\n" Pair(s?) { $return = { $item[1]=> merge2hash( $item[3])||{} } } | COMMENT(s) | BLANK(s) | Title: '[' /\w+/ ']' COM(?) { $item[2] } Pair: KEY '=' VAL(s?) COM(?) "\n" {$return = {$item[1]=>$item[3]} } Pair: COMMENT(s){$return = 0} | BLANK(s) {$return = 0} Pair: KEY: /\w+(?=\s*=)/ VAL: { $item[1]->[2] =~ s/\\\n//g } { $item[1]->[2] } VAL: /.*? (?new( $gram ) } 1; __END__ =head1 NAME Config::Format::Ini::Grammar - P:RD grammar for ini file format