/usr/local/CPAN/Tie-IxHash-FromText/Tie/IxHash/FromText/Parse.pm
package Tie::IxHash::FromText::Parse;
sub _ixhash {
tie(my %h, 'Tie::IxHash');
\%h;
}
sub _dxhash {
tie(my %h, 'Tie::DxHash');
\%h;
}
sub _parse {
local $_ = shift;
my $constr = {i=>\&_ixhash,d=>\&_dxhash}->{shift()};
s/^[\s\n]+//so;
s/^\*+\*\s/* /so;
s/\n+$//sg;
s/\n+/\n/sg;
s/\s+$//mg;
$_.=$/;
# print ; print $/x3;
my @last = (0);
my @st = ();
my $tree=$constr->();
s/^([\*]+)\s+(.+)/
# print "$1 $2\n";
if(length($1) > $last[-1]){
push @last, length($1);
push @st, $2;
# print '$tree->'.join('->', map{"{'$_'}"}@st)."\n";
eval '$tree->'.join('->', map{"{'$_'}"}@st).'=$constr->()';
}
elsif(length($1) < $last[-1]){
foreach (1..$last[-1] - length($1)){
# print '...';
pop @st;
pop @last;
}
if(length($1) eq $last[-1]){
pop @st;
pop @last;
push @last, length($1);
push @st, $2;
}
# print '$tree->'.join('->', map{"{'$_'}"}@st)."\n";
eval '$tree->'.join('->', map{"{'$_'}"}@st).'=$constr->()';
}
else {
pop @st;
pop @last;
push @last, length($1);
push @st, $2;
# print '$tree->'.join('->', map{"{'$_'}"}@st)."\n";
eval '$tree->'.join('->', map{"{'$_'}"}@st).'=$constr->()';
}
# print " (@last) (@st)\n\n";
/mexg;
$tree;
}
1;