package ILMT::HIN::PAN::SSFAPI::feature_filter; use Exporter qw(import); our @EXPORT = qw( read_FS convert_to_old read_FS_old get_values get_values_2 get_attributes get_path_values get_path_values_2 copyFS add_attr_val add_attr_val_2 update_attr_val update_attr_val_2 del_attr_val del_attr_val_2 unify unify_2 merge merge_2 load_hash printFS_SSF printFS_SSF_2 make_string make_string_2 prune_FS prune_FS_2 get_fs_reference get_num_fs printFS_SSF_old make_string_old); # P.NIRUPAM PRATAP REDDY # 200101050 (UG3) # MODIFIED BY: Samar Husain (samar@research.iiit.ac.in) # NOTE: Feature Path from the beginning has to specified as follows, a1.a2.a3.a4 (etc) #% read_FS($string) --> reference to an or array. #% Pass a string which is the feature structure to be loaded and #% a reference to an or array is returned. # # my $ref_to_fs = read_FS("< fs af='xe,v,f,s,any,,ne,yA' drel=k1:1|k2 vibh=ne|ko|se >"); my @fff = get_values("lex", $ref_to_fs); #print stderr $fff[0]."\n"; my $new_fs = make_string($ref_to_fs); #print stderr "NEW=$new_fs\n"; sub read_FS { local (@_STRING_,$_INDEX_); my $featureString=$_[0]; #temporary $featureString = convert_to_old($featureString); $featureString=~s/af=(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?)([\/>])/lex=$1\/cat=$2\/gen=$3\/num=$4\/per=$5\/cas=$6\/vib=$7\/tam=$8$9/g; $featureString="< ROOT = ".$featureString." >"; @_STRING_= split(//,$featureString); $_INDEX_=0; my %hashRef; $hashRef=load_hash(); return $$hashRef{'ROOT'}; } #the module takes the new xml format and converts it to the old one, #this seems to be a temporary solution, #like this only the printer needs to be modified, everything remains same. sub convert_to_old { my $col_fs = $_[0]; # print stderr "Original: $col_fs\n"; #remove 'fs ' $col_fs =~ s/\s*fs\s+//g; #remove single quotes $col_fs =~ s/'//g; #Remove '/'. Stupid hack, but required so that it doesn't conflict with the delimiter in SSF parsing. $col_fs =~ s/\///g; #take care of any spaces before the closing angular brace, if any $col_fs =~ s/\s*>/>/g; #convert all the spaces into backspaces, this assumes that there can #be no space between attribute=value pair. $col_fs =~ s/\s+/\//g; # print stderr "Converted: $col_fs\n\n\n"; return $col_fs; } #% read_FS($string) --> reference to an array #% Pass a string which is the feature structure to be loaded and #% sub read_FS_old { local (@_STRING_,$_INDEX_); my $featureString=$_[0]; my $featureStructure; @array=split(/\/\//,$featureString); for($i=0;$i<@array;$i++) { $array[$i]=~s/(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?)(\|.*)/af=$1,$2,$3,$4,$5,$6,$7,$8$9/; $array[$i]=~s/\|/\//g; $array[$i]=~s/\/$/>/g; $array[$i]="<".$array[$i]; $array[$i]=~s/[\'\"]//g; $featureStructure.="|".$array[$i]; } $featureStructure=~s/^\|<\|//g; $featureStructure=~s/\/\s*$/>/g; my $ref=read_FS($featureStructure); my $newString=""; return $ref; } #% get_values($featurePath,$FSreference) --> An array containg the matched values. #% $FSreference is the OR containing an or node with a collection of a number of possible Feature Structures. #% The array that is returned can contain both values as well as reference to other featurestructures. #% The returned array is an OR array. sub get_values { my $featurePath=$_[0]; my $arrayRef=$_[1]; $featurePath="ROOT.".$featurePath; my %hash; $hash{'ROOT'}=$arrayRef; my @ReturnedArray; #@ReturnedArray=get_values_hash($featurePath,\%hash); return get_values_2($featurePath,\%hash); #return @ReturnedArray; } #% get_values_2($featurePath,$FSreference) --> An array containg the matched values. #% $FSreference is the reference to a single feature structure. #% The array that is returned can contain both values as well as reference to other featurestructures. #% The returned array is an OR array. sub get_values_2 { #Feature path is given as follows: #a1.a2.a3..... my $featurePath=$_[0]; my $hashRef=$_[1]; my ($presAttr,$nextPath); if($featurePath=~/\./) { $presAttr=$`; $nextPath=$'; } else { $presAttr=$featurePath; } if($nextPath eq "") { my $arrayRef=$$hashRef{$presAttr}; my @newReturnArray; for(my $i=0;$i<@$arrayRef;$i++) { if(ref($$arrayRef[$i]) eq "HASH") { $newReturnArray[$i]=copyFS($$arrayRef[$i]); } else { $newReturnArray[$i]=$$arrayRef[$i]; } } return @newReturnArray; #return @$arrayRef; # Return the array } else { my $arrayRef=$$hashRef{$presAttr}; my @RetArray; for(my $i=0;$i<@$arrayRef;$i++) { if(ref($$arrayRef[$i]) eq "HASH") { push(@RetArray,get_values_2($nextPath,$$arrayRef[$i])); } } return @RetArray; } } #% get_attributes($FSReference) -> array containing the attributes for that feature structure #% $FSReference is the reference to a hash (that is that of a single feature structue) NOT of a or node (i.e a collection) #% of feature structures. #% sub get_attributes { my $hashRef=$_[0]; my @attributes=keys(%$hashRef); my @differentArray,$j=0; my $numberOfAttributes=@attributes; for(my $i=0;$i<$numberOfAttributes;$i++) { if(defined($$hashRef{$attributes[$i]})) { $differentArray[$j]=$attributes[$i]; $j++; } } return @differentArray; } #% get_path_values($attr,$fs) --> 2D array of values and paths. #% $fs is the reference to an or node with more than one Feature Structures in it. #% field 0 contains the path #% field 1 contains the value. sub get_path_values { my $attr=$_[0]; my $arrayRef=$_[1]; my %hash; $hash{'ROOT'}=$arrayRef; my @retArray; @retArray=get_path_values_2($attr,\%hash); for(my $i=0;$i<@retArray;$i++) { $retArray[$i][0]=~s/^\.ROOT\.//g; } return @retArray; } #% get_path_values_2($attr,$fs) --> 2D array of values and paths. #% $fs is the reference to a single feature structure. #% field 0 contains the path #% field 1 contains the value. sub get_path_values_2 { my $attr=$_[0]; my $hashRef=$_[1]; my $path=$_[2]; my $key; my @keys=keys(%$hashRef); my @RetArray; my $count=0; foreach $key(@keys) { my $newPath=$path.".".$key; if($key eq $attr) { my $arrayRef=$$hashRef{$key}; my @newArray; for(my $i=0;$i<@$arrayRef;$i++) { if(ref($$arrayRef[$i]) eq "HASH") { $newArray[$i]=copyFS($$arrayRef[$i]); my @toPushArray; @toPushArray=get_path_values_2($attr,$$arrayRef[$i],$newPath); for(my $i=0;$i<@toPushArray;$i++) { $RetArray[$count][0]=$toPushArray[$i][0]; $RetArray[$count][1]=$toPushArray[$i][1]; $count++; } } else { $newArray[$i]=$$arrayRef[$i]; } } $RetArray[$count][0]=$newPath; $RetArray[$count][1]=\@newArray; $count++; } else { my $arrayRef=$$hashRef{$key}; for(my $i=0;$i<@$arrayRef;$i++) { if(ref($$arrayRef[$i]) eq "HASH") { $newArray[$i]=copyFS($$arrayRef[$i]); my @toPushArray; @toPushArray=get_path_values_2($attr,$$arrayRef[$i],$newPath); for(my $i=0;$i<@toPushArray;$i++) { $RetArray[$count][0]=$toPushArray[$i][0]; $RetArray[$count][1]=$toPushArray[$i][1]; $count++; } } } } } return @RetArray; } #% copyFS($fs) --> Reference of a new FS #% Copies fs into a new fs and returns that. sub copyFS { my $hashRef=$_[0]; my %newHash; my @referenceKeys=keys(%$hashRef); my $key; foreach $key(@referenceKeys) { my $arrayRef=$$hashRef{$key}; my @newArray; for(my $i=0;$i<@$arrayRef;$i++) { if(ref($$arrayRef[$i]) eq "HASH") { $newArray[$i]=copyFS($$arrayRef[$i]); } else { $newArray[$i]=$$arrayRef[$i]; } } $newHash{$key}=\@newArray; } return \%newHash; } #% add_attr_val($featurePath,$value,$FSReference) --> -nil- #% FSReference is an or node containing multiple possible feature structures. #% $value is a reference to an OR array. The values in the array will be either normal strings or references to other #% featurestructures (hashes) sub add_attr_val { my $featurePath=$_[0]; my $val=$_[1]; my $arrayRef=$_[2]; my %hash; $featurePath="ROOT.".$featurePath; $hash{'ROOT'}=$arrayRef; add_attr_val_2($featurePath,$val,\%hash); return; } #% add_attr_val_2($featurePath,$value,$FSReference) --> -nil- #% $value is a reference to an OR array. The values in the array will be either normal strings or references to other #% featurestructures (hashes) sub add_attr_val_2 { my $featurePath=$_[0]; my $val=$_[1]; # This value has to be a reference to an array. my $hashRef=$_[2]; # That array will contain either the references to other my ($presAttr,$nextPath); if($featurePath=~/\./) { $presAttr=$`; $nextPath=$'; } else { $presAttr=$featurePath; } if($nextPath eq "") { my $arrayRef=$$hashRef{$presAttr}; if(defined($arrayRef)) { my $prevNumber=@$arrayRef; for(my $i=0;$i<@$val;$i++) { if(ref($$val[$i]) eq "HASH") { $$arrayRef[$i+$prevNumber]=copyFS($$val[$i]); } else { $$arrayRef[$i+$prevNumber]=$$val[$i]; } } } else { my @arrayAdd; for(my $i=0;$i<@$val;$i++) { if(ref($$val[$i]) eq "HASH") { $$arrayAdd[$i]=copyFS($$val[$i]); } else { $arrayAdd[$i]=$$val[$i]; } } $$hashRef{$presAttr}=\@arrayAdd; } return; } else { my $arrayRef=$$hashRef{$presAttr}; if(defined($arrayRef)) { my $entered=0; for(my $i=0;$i<@$arrayRef;$i++) { if(ref($$arrayRef[$i]) eq "HASH") { $entered=1; $arrayRef[$i]=add_attr_val_2($nextPath,$val,$$arrayRef[$i]); } } if($entered==0) { my %hash; my @arrayAdd; $arrayAdd[0]=\%hash; push(@$arrayRef,@arrayAdd); add_attr_val_2($nextPath,$val,$arrayAdd[0]); } return; } else { my %hash; my @arrayAdd; $arrayAdd[0]=\%hash; $$hashRef{$presAttr}=\@arrayAdd; add_attr_val_2($nextPath,$val,\%hash); } } } #% update_attr_val($featurePath,$val,$FSReference) --> -nil- #% FSReference is the OR Node reference #% The value in the featurepath specified will be changed to the new val. #% If that val is not present then it is added. sub update_attr_val { my $featurePath=$_[0]; my $val=$_[1]; # This value has to be a reference to an array. my $arrayRef=$_[2]; # That array will contain either the references to other $featurePath="ROOT.".$featurePath; my %hash; $hash{'ROOT'}=$arrayRef; update_attr_val_2($featurePath,$val,\%hash); return; } #% update_attr_val_2($featurePath,$val,$FSReference) --> -nil- #% The value in the featurepath specified will be changed to the new val. #% If that val is not present then it is added. sub update_attr_val_2 { my $featurePath=$_[0]; my $val=$_[1]; # This value has to be a reference to an array. my $hashRef=$_[2]; # That array will contain either the references to other my ($presAttr,$nextPath); if($featurePath=~/\./) { $presAttr=$`; $nextPath=$'; } else { $presAttr=$featurePath; } if($nextPath eq "") { if(defined($$hashRef{$presAttr})) # Update an existing value. { my @arrayAdd; for(my $i=0;$i<@$val;$i++) { if(ref($$val[$i]) eq "HASH") { $arrayAdd[$i]=copyFS($$val[$i]); } else { $arrayAdd[$i]=$$val[$i]; } } $$hashRef{$presAttr}=\@arrayAdd; } } else { my $arrayRef=$$hashRef{$presAttr}; my @RetArray; for(my $i=0;$i<@$arrayRef;$i++) { if(ref($$arrayRef[$i]) eq "HASH") { update_attr_val_2($nextPath,$val,$$arrayRef[$i]); } } return; } } #% del_attr_val($featurePath,$FSReference) #% FSReference is the OR node reference #% Deletes the value in the attribute specified by the path. sub del_attr_val { my $featurePath=$_[0]; my $arrayRef=$_[1]; $featurePath="ROOT.".$featurePath; my %hash; $hash{'ROOT'}=$arrayRef; del_attr_val_2($featurePath,\%hash); return; } #% del_attr_val_2($featurePath,$FSReference) #% Deletes the value in the attribute specified by the path. sub del_attr_val_2 { my $featurePath=$_[0]; my $hashRef=$_[1]; my ($presAttr,$nextPath); if($featurePath=~/\./) { $presAttr=$`; $nextPath=$'; } else { $presAttr=$featurePath; } if($nextPath eq "") { if(defined($$hashRef{$presAttr})) # Undefine an already existing value. { delete $$hashRef{$presAttr}; #changed from undef to delete 15th Dec 2004 #undef($$hashRef{$presAttr}); } ######### Changed 19th Feb 2004 03:05 if($$hashRef{$presAttr}=~/^\s*$/) { delete $$hashRef{$presAttr}; #changed from undef to delete 15th Dec 2004 #undef($$hashRef{$presAttr}); } } else { my $arrayRef=$$hashRef{$presAttr}; #my @RetArray; for(my $i=0;$i<@$arrayRef;$i++) { if(ref($$arrayRef[$i]) eq "HASH") { del_attr_val_2($nextPath,$$arrayRef[$i]); } } return; } } #% unify($fs1,$fs2) --> $fs3; #% $fs1 and $fs2 are references to two or nodes possibly containing one or more feature structures, #% But there should not be multiple possible feature Structures given to it. That or node should contain only one possible #% feature structure. #% $fs3 is either -1 or a reference to a new or node of feature structures. #% -1 is returned in the case that the featurestructures cannot be unified. sub unify { my $firstRef=$_[0]; my $secondRef=$_[1]; my (%hash1,%hash2,$hashRef); $hash1{'ROOT'}=$firstRef; $hash2{'ROOT'}=$secondRef; $hashRef=unify_2(\%hash1,\%hash2); if($hashRef!=-1) { return $$hashRef{'ROOT'}; } else { return -1; } } #% unify_2($fs1,$fs2) --> $fs3; #% $fs1 and $fs2 are references to two feature structures #% $fs3 is either -1 or a reference to a new feature structure. #% -1 is returned in the case that the featurestructures cannot be unified. sub unify_2 { my $firstRef=$_[0]; my $secondRef=$_[1]; my @keys1=keys(%$firstRef); my @keys2=keys(%$secondRef); my $key; my %hash; foreach $key(@keys1) { my $valArrayRef1=$$firstRef{$key}; my $valArrayRef2=$$secondRef{$key}; my $retVal; if(@$valArrayRef1>1 or @$valArrayRef2>1) { print "#RULE NOT DEFINED TO MERGE THE VALUES\n"; return -1; } else { if(ref($$valArrayRef1[0]) eq "HASH" and ref($$valArrayRef2[0]) eq "HASH") { $retVal=unify_2($$valArrayRef1[0],$$valArrayRef2[0]); if($retVal!=-1) { my @array; $array[0]=$retVal; $hash{$key}=\@array; } else { return -1; } } elsif((not(ref($$valArrayRef1[0]) eq "HASH")) and (not(ref($$valArrayRef2[0]) eq "HASH"))) { if(defined($$valArrayRef1[0]) and defined($$valArrayRef2[0])) { if($$valArrayRef1[0] eq $$valArrayRef2[0]) { my @array; $array[0]=$$valArrayRef1[0]; $hash{$key}=\@array; } else { return -1; } } else { # If anything is not defined here it will be $$valArrayRef2[0] # Because we are considering the keys of ref1 my @array; $array[0]=$$valArrayRef1[0]; $hash{$key}=\@array; } } elsif(not(defined($$varArrayRef2[0]))) { my @array; $array[0]=$$valArrayRef1[0]; $hash{$key}=\@array; } else { return -1; } } } foreach $key(@keys2) { my $valArrayRef2=$$secondRef{$key}; if(not(defined($$firstRef{$key}))) { my $arrayRef=$$secondRef{$key}; my @arrayAdd; for(my $i=0;$i<@$arrayRef;$i++) { if(not(ref($$arrayRef[$i]) eq "HASH")) { $arrayAdd[$i]=$$arrayRef[$i]; } else { $arrayAdd[$i]=copyFS($$arrayRef[$i]); } } $hash{$key}=\@arrayAdd; } } return \%hash; } #% merge($fs1,$fs2) --> -nil- #% $fs1 and $fs2 are or nodes containing multiple possible feature structures. #% Changes all the values of fs1 to that of fs2 for all the common attributes in fs1 and fs2 #% Rest of the values are left untouched. sub merge { my $firstRef=$_[0]; my $secondRef=$_[1]; my (%hash1,%hash2); merge_2($$firstRef[0],$$secondRef[0]); return; } #% merge_2($fs1,$fs2) --> -nil- #% Changes all the values of fs1 to that of fs2 for all the common attributes in fs1 and fs2 #% Rest of the values are left untouched. sub merge_2 { my $firstRef=$_[0]; my $secondRef=$_[1]; my $key; my @keys2=keys(%$secondRef); foreach $key(@keys2) { undef($$firstRef{$key}); my $arrayRef=$$secondRef{$key}; my @newArray; for(my $i=0;$i<@$arrayRef;$i++) { if(ref($$arrayRef[$i]) eq "HASH") { $newArray[$i]=copyFS($$arrayRef[$i]); # Change the value of one to that in two. } else { $newArray[$i]=$$arrayRef[$i]; } } $$firstRef{$key}=\@newArray; # But the users have to be careful here as there is just a swap of references and not a complete copy of the values. } return; } #% load_hash #% Loads the string passed to a hash and the reference to that hash is returned. sub load_hash { if($_STRING_[$_INDEX_] ne "<") { my $value; while($_STRING_[$_INDEX_] ne "|" and $_STRING_[$_INDEX_] ne "/" and $_STRING_[$_INDEX_] ne ">") # Go on till you find a / or | { $value.=$_STRING_[$_INDEX_]; $_INDEX_++; while($_STRING_[$_INDEX_]=~/\s+/) #Ignore all the spaces. { $_INDEX_++; } } # Stop at the / or the final position. Do not go beyond that. return $value; # Return the final value. } else { my %hash; $_INDEX_++; # Leave the { behind. while($_STRING_[$_INDEX_] ne ">") { my $attr; my @arrayVal; my $arrayMarker=0; if($_STRING_[$_INDEX_] eq "/") { $_INDEX_++; } while($_STRING_[$_INDEX_]=~/\s+/) { $_INDEX_++; } while($_STRING_[$_INDEX_] ne "=") { $attr.=$_STRING_[$_INDEX_]; $_INDEX_++; while($_STRING_[$_INDEX_]=~/\s+/) #Ignore all the spaces. { $_INDEX_++; } } $_INDEX_++; # This is to throw out the = while($_STRING_[$_INDEX_]=~/\s+/) #Ignore all the spaces. { $_INDEX_++; } while(1) # Continue until the loop breaks. { $arrayVal[$arrayMarker]=load_hash(); while($_STRING_[$_INDEX_]=~/\s+/) { $_INDEX_++; # Remove any spaces following the ending of a pair. } $arrayMarker++; if($_STRING_[$_INDEX_] eq "/" or $_STRING_[$_INDEX_] eq ">") { last; } elsif($_STRING_[$_INDEX_] eq "|") { $_INDEX_+=1; #Get beyond that mark. while($_STRING_[$_INDEX_]=~/\s+/) #Ignore all the spaces. { $_INDEX_++; } } else { print "ERROR: $_STRING_[$_INDEX_]"; } } $hash{$attr}=\@arrayVal; } $_INDEX_++; return \%hash; } } #% printFS_SSF($fs) --> -nil- #% $fs is a reference to an or node containing multiple possible feature structures. #% prints the attributes and values present in the hash in the standard format. sub printFS_SSF { my $arrayRef=$_[0]; my $finalString; $finalString=make_string($arrayRef); print "$finalString\n"; } #% printFS_SSF_2($fs) --> -nil- #% $fs is a reference to a single possible feature structure. #% prints the attributes and values present in the hash in the standard format. sub printFS_SSF_2 { my $finalString; my $FSRef=$_[0]; $finalString=make_string_2($FSRef); print "$finalString \n"; } #% make_string($FSReference) --> -$string- #% $FSReference is the array reference returned by the read_FS function. #% $stringRef is reference to a string into which you want to get the string. sub make_string { my $arrayRef=$_[0]; my $string; for(my $i=0;$i<@$arrayRef;$i++) { $string.=make_string_2($$arrayRef[$i])."|"; } $string=~s/\|$//g; $string=~s/\'\"/\"/g; # Litha Changes $string=~s/\"\'/\"/g; # Litha Changes # if($string eq "<>") if($string eq "<'>") { undef($string); } return $string; } sub make_string_2 { my $hashRef=$_[0]; my @keyValues; my $key; # my $refString=$_[1]; my $String; my ($string,@array); @array=('lex','cat','gen','num','per','cas','vib','tam'); my $present=1; foreach $string(@array) { if(not(defined($$hashRef{$string}))) { $present=0;last; } } @keyValues=keys(%$hashRef); if($present eq 1) { #$String.="8) { #$String.="/"; $String.="' "; } } } } else { $String.="<"; } my $count=0; for($key=0;$key<@keyValues;$key++) { my $arrayRef; $arrayRef=$$hashRef{$keyValues[$key]}; if($keyValues[$key] ne "ROOT") { my $attr=$keyValues[$key]; if($attr eq "lex" or $attr eq "cat" or $attr eq "gen" or $attr eq "num" or $attr eq "per" or $attr eq "cas" or $attr eq "vib" or $attr eq "tam") { $count++; next; } if(defined($$hashRef{$keyValues[$key]})) { $String.=$keyValues[$key]."='"; # Litha Changes } else { next; } } for(my $i=0;$i<@$arrayRef;$i++) { if(ref($$arrayRef[$i]) eq "HASH") { $String.=make_string_2($$arrayRef[$i]); } else { $String.=$$arrayRef[$i]; } if($i+1<@$arrayRef) { $String.="|"; } } if($key+1<@keyValues && 8-$count!=@keyValues-$key-1) { my $num=@keyValues; #$String.="/"; $String.="' "; # Litha Changes } } #if($String[@String]=='/') { # chop($String); # print "\nY\n"; #} if($String =~ /'.*'/) # If the FS has more than 8 default fields then no need of "'" else add it. { $String.="'>"; # Litha Changes } else { $String.="'>"; } return $String; } #% prune_FS($featurePath,$fieldNumber,$FSReference) --> +1/-1 #% Deletes the value in the attribute specified by the path. #% +1 indicates successful completion of the function #% -1 indicates that such a feature path does not exist. sub prune_FS { my $featurePath=$_[0]; my $fieldNumber=$_[1]; my $arrayRef=$_[2]; $featurePath="ROOT.".$featurePath; my %hash; $hash{'ROOT'}=$arrayRef; return prune_FS_2($featurePath,$fieldNumber,\%hash); } #% prune_FS_2($featurePath,$fieldNumber,$FSReference) --> +1/-1 #% Deletes the value in the attribute specified by the path. #% +1 indicates successful completion of the function #% -1 indicates that such a feature path does not exist. sub prune_FS_2 { my $featurePath=$_[0]; my $fieldNumber=$_[1]; my $hashRef=$_[2]; my ($presAttr,$nextPath); if($featurePath=~/\./) { $presAttr=$`; $nextPath=$'; } else { $presAttr=$featurePath; } if($nextPath eq "") { =s if(defined($$hashRef{$presAttr})) # Undefine an already existing value. { undef($$hashRef{$presAttr}); } =cut my $hashValue=$$hashRef{$presAttr}; if($hashValue ne "") { my $numEle,$arrayRef; $arrayRef=$$hashRef{$presAttr}; $numEle=@$arrayRef; for(my $i=$fieldNumber;$i<$numEle-1;$i++) { $$arrayRef[$i]=$$arrayRef[$i+1]; } pop(@$arrayRef); # pop the final one which is left out. $numEle=@$arrayRef; if($numEle==0) { undef($$hashRef{$presAttr}); } return 1; } else { return -1; } } else { my $arrayRef=$$hashRef{$presAttr}; my @RetArray; if(not(defined($$hashRef{$presAttr}))) { return -1; } for(my $i=0;$i<@$arrayRef;$i++) { if(ref($$arrayRef[$i]) eq "HASH") { prune_FS_2($nextPath,$fieldNumber,$$arrayRef[$i]); } } return 1; } } #% get_fs_reference($ref_to_array,$index_feature_structure) #% $ref_to_array is the reference to an OR array #% $index_... is field you want from the array. #% sub get_fs_reference { my $refArray=$_[0]; my $index=$_[1]; return $$refArray[$index]; } #% get_num_fs($ref_to_array) --> number of feature structures (Or values also) #% sub get_num_fs { my $refArray=$_[0]; my $number=@$refArray; return $number; } #% printFS_SSF($fs) --> -nil- #% $fs is a reference to an or node containing multiple possible feature structures. #% prints the attributes and values present in the hash in the standard format. sub printFS_SSF_old { my $arrayRef=$_[0]; my $finalString; # In the old format we do not have nested feature structures inside the bigger feature structures. $finalString=make_string($arrayRef); my $featureStructure; my @array=split(/\|/,$finalString); for(my $i=0;$i<@array;$i++) { $array[$i]=~s/^$/\|/g; $array[$i]=~s/\//\|/g; $array[$i]=~s/af=(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?)([\|>])/\/\/$1,$2,$3,$4,$5,$6,$7,$8$9/; $array[$i]=~s/=(.*?)\|/=$1\|/g; $featureStructure.=$array[$i]; } print "$featureStructure\n"; } sub make_string_old { my $arrayRef=$_[0]; my $finalString; # In the old format we do not have nested feature structures inside the bigger feature structures. $finalString=make_string($arrayRef); my $featureStructure; my @array=split(/\|/,$finalString); for(my $i=0;$i<@array;$i++) { $array[$i]=~s/^$/\|/g; $array[$i]=~s/\//\|/g; $array[$i]=~s/af=(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?)([\|>])/\/\/$1,$2,$3,$4,$5,$6,$7,$8$9/; $array[$i]=~s/=(.*?)\|/=$1\|/g; $featureStructure.=$array[$i]; } return $featureStructure; } # Report any bugs to # p_nirupam@students.iiit.net # (or) sriram@students.iiit.net 1;