Solved

create hash out of a recursive string in perl

Posted on 2008-10-20
4
375 Views
Last Modified: 2012-05-05
I have the following string(s)and I want to generate a hash of hash from this one.

;&EVENT[__nmi_0](nmi, THREAD => 0, TRIGGER => &TRIGGER[__nmi_0.trigger](eom, LIP => 0x2020, SELF_CHECK => 'MUST_COMPLETE', THREAD => 0));

Hash %Event might look like this:

Event[nmi_0][event] = nmi
Event[nmi_0][Thread] =0
Event[nmi_0][Trigger] = __nmi_0.trigger
Event[nmi_0][__nmi_0.trigger][trigger] = eom
Event[nmi_0][__nmi_0.trigger][LIP] = 0x2020
Event[nmi_0][__nmi_0.trigger][SELF_CHECK] = 'MUST_COMPLETE'
Event[nmi_0][__nmi_0.trigger][THREAD] = 0


Below is an example of recursive strings.

;&EVENT[__psmi_1](psmi, THREAD => 0, TRIGGER => &TRIGGER[__retire_1](retire, LIP => 0x203f, TRIGGER => &EVENT[__smi_1](smi, THREAD => 1, TRIGGER => &TRIGGER[__eom_1](eom, LIP => 0x203f, THREAD => 0))));

Event[psmi_0][event] = psmi
Event[nmi_0][Thread] =0
Event[nmi_0][Trigger] = __retire_0.trigger
Event[nmi_0][__retire_0.trigger][trigger] = retire
Event[nmi_0][__retire_0.trigger][LIP] = 0x203f
Event[nmi_0][__nmi_0.trigger][trigger] = smi_1
Event[nmi_0][__nmi_0.trigger][smi_1][event] = smi
Event[nmi_0][__nmi_0.trigger][smi_1][Thread] = 0
Event[nmi_0][__nmi_0.trigger][smi_1][Trigger] = eom_1
Event[nmi_0][__nmi_0.trigger][smi_1][eom_1][event] = eom
Event[nmi_0][__nmi_0.trigger][smi_1][eom_1][Thread] = 0
Event[nmi_0][__nmi_0.trigger][smi_1][eom_1][LIP] = 0x203f


Can someone show me how to do hash like this? The string can have these events and triggers nested any number of times my hash has to build accordingly.

Thanks
0
Comment
Question by:Anu2117
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 

Author Comment

by:Anu2117
ID: 22761307
Event[psmi_0][event] = psmi
Event[psmi_0][Thread] =0
Event[psmi_0][Trigger] = __retire_0.trigger
Event[psmi_0][__retire_0.trigger][trigger] = retire
Event[psmi_0][__retire_0.trigger][LIP] = 0x203f
Event[psmi_0][__retire_0.trigger][trigger] = smi_1
Event[psmi_0][__retire_0.trigger][smi_1][event] = smi
Event[psmi_0][__retire_0.trigger][smi_1][Thread] = 0
Event[psmi_0][__retire_0.trigger][smi_1][Trigger] = eom_1
Event[psmi_0][__retire_0.trigger][smi_1][eom_1][event] = eom
Event[psmi_0][__retire_0.trigger][smi_1][eom_1][Thread] = 0
Event[psmi_0][__retire_0.trigger][smi_1][eom_1][LIP] = 0x203f

 
I made a mistake in my example hash, here is the correct hash interpretation for the string. This the 2nd example in my question above.
 
 
0
 
LVL 39

Accepted Solution

by:
Adam314 earned 500 total points
ID: 22761803
Your expected data doesn't seem consistent with your input string... but accounting for possible typos
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
 
my @str = (";&EVENT[__nmi_0](nmi, THREAD => 0, TRIGGER => &TRIGGER[__nmi_0.trigger](eom, LIP => 0x2020, SELF_CHECK => 'MUST_COMPLETE', THREAD => 0));",
           ";&EVENT[__psmi_1](psmi, THREAD => 0, TRIGGER => &TRIGGER[__retire_1](retire, LIP => 0x203f, TRIGGER => &EVENT[__smi_1](smi, THREAD => 1, TRIGGER => &TRIGGER[__eom_1](eom, LIP => 0x203f, THREAD => 0))));");
 
my %Event;
my %Pieces;
foreach (@str) {
	%Pieces = ();
	my $Cnt;
	
	1 while s/\&(\w+)\[__([^\]]+)\]\((\w+),\s+([^\(\)]+)\)/print "String=$_\n";$Cnt++;$Pieces{$Cnt}=MakeHash($1,$2,$3,$4);"$2:SubHash{$Cnt}"/ge;
	for my $piece (sort {$b <=> $a} keys %Pieces) {
		while(my ($k, $v) = each %{$Pieces{$piece}}) {
			if($v =~ /^(.*):SubHash{(\d+)}$/) {
				$Pieces{$piece}->{$k}=$1;
				$Pieces{$piece}->{$1}=$Pieces{$2};
			}
		}
	}
	if(/^;(.*):SubHash{(\d+)};$/) {
		$Event{$1}=$Pieces{$2};
	}
}
print Dumper(\%Event);
sub MakeHash {
	print "MakeHash(" . join("; ", @_) . ")\n";
	return {lc($_[0])=> $_[2], split(/[,=>\s]+/, $_[3])};
}

Open in new window

0
 

Author Closing Comment

by:Anu2117
ID: 31507961
Adam,

    The ultimate use of this hash is to pass it as an argument to xml::simple::xmlout() so, I can get an xml output of this hash. But I am not getting that desired output right. This hash looks almost like an example hash in xmlout() help, but the xml is not like what is expected. I will file another ticket for this. If you get a chance, please take a look. Thanks a lot for the help.
0
 
LVL 84

Expert Comment

by:ozo
ID: 22762516
use Data::Dumper;
$_=q;&EVENT[__psmi_1](psmi, THREAD => 0, TRIGGER => &TRIGGER[__retire_1](retire, LIP => 0x203f, TRIGGER => &EVENT[__smi_1](smi, THREAD => 1, TRIGGER => &TRIGGER[__eom_1](eom, LIP => 0x203f, THREAD => 0))));;
$Event=mkhash("event","psmi_0 => $_");
sub mkhash{
    my($n,$h)=@_;
    my %h;
    (my $re=$h)=~s/((\()|(\))|[^()]+)/${[')','']}[!$3]\Q$1\E${['(','']}[!$2]/gs;  
    $re=join'|',map quotemeta,$h=~/$re/;
    while( $h=~/(?:(\w+)\s*=>\s*)?(?:&(\w+)\[(\w+)\]\(($re)\)|(\w+)|'([^'']*)')/g ){
my $x=$3?"$3.\L$2":$1||$n;
      $h{$x}=$2?mkhash("\L$2",$4):$5.$6;

    }
    return \%h;
}
print Dumper $Event;
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question