Скрипт для генерации всех форм русского языка при помощи словарей Ispell (rus ispell)
 
Ключевые слова:  rus , ispell ,  (найти похожие документы )From: Кирил Хлопов <kiril@j2.ru > 
Subject: Скрипт для генерации всех форм русского языка при помощи словарей Ispell kiril@j2.ru > http://ispell.narod.ru/  
#$affix_filename='1.aff';
#$dic_file="full.win";
#$fin_dic_file="win.full_dic";
$affix_filename='english.aff';
$dic_file="english.full";
$fin_dic_file="english.all";
$garbage_output=0;
#------------------------------------------------------------------------
sub russian_lc
{
	my ($src_)=@_;
        $src_=~tr/АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ╗ABCDEFGHIJKLMNOPQRSTUVWXYZ/абвгдежзийклмнопрстуфхцчшщъыьэюяёabcdefghijklmnopqrstuvwxyz/;
        return $src_;
}
sub russian_uc
{
	my ($src_)=@_;
        $src_=~tr/абвгдежзийклмнопрстуфхцчшщъыьэюяёabcdefghijklmnopqrstuvwxyz/АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ╗ABCDEFGHIJKLMNOPQRSTUVWXYZ/;
        return $src_;
}
#------------------------------------------------------------------------
sub is1stuc_rus
{
	my ($src_)=@_;
	# get first char
	my($src_1st)=(split//,$src_)[0];
        my($res)=($src_1st=~tr/АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ╗ABCDEFGHIJKLMNOPQRSTUVWXYZ/абвгдежзийклмнопрстуфхцчшщъыьэюяёabcdefghijklmnopqrstuvwxyz/);
        return $res;
}
#------------------------------------------------------------------------
sub make1stuc_rus
{
	my ($src_)=@_;
	my(@str_)=split//,$src_;
        $str_[0]=~tr/абвгдежзийклмнопрстуфхцчшщъыьэюяёabcdefghijklmnopqrstuvwxyz/АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ╗ABCDEFGHIJKLMNOPQRSTUVWXYZ/;
        join "",@str_;
}
#------------------------------------------------------------------------
sub gen_word
{
	my ($w_,$f_)=@_;
	my ($is_capital)=is1stuc_rus($w_);
        $w_=russian_lc($w_);
        my(@new_words);
        # useless
        print "Wanna generate from word '$w_', group '$f_'\n" if($full_debug==1);
        foreach my $aff_ (@{$affixes{$f_}})
        {
        	my($re_,$actions_)=split/\t/,$aff_;
                my($sub_,$app_);
        	if ($actions_=~/,/)	# both parts - substract and append
        	{
	        	($sub_,$app_)=split/,/,$actions_;
	        	$mode_=0;
        	}
        	else
        	{
	        	$app_=$actions_;
	        	$mode_=1;
        	}
        	# copy primary word
        	$nw_=$w_;
        	$sub_=~s/-//;
        	if ($app_=~/^-$/)
        	{
			$app_='';        	
        	}
        	print "\tCut string - '$sub_', append - '$app_'\n" if($full_debug==1);
        	print "\tPattern - '$re_'\n" if($full_debug==1);
        	if ($nw_=~/$re_$/) # patter match
        	{
        	        if ($mode_ == 0) # cut 'n' paste
        	        {
	        	        # cut
				$nw_=~s/^(.*)?$sub_$/$1/;        	
				print "\tAfter cut - '$nw_'\n" if($full_debug==1);
			}	
			# paste
                        $nw_.=$app_;
			print "\tAfter paste - '$nw_'\n" if($full_debug==1);
                        # save
                	push @new_words,$nw_;
        	}
        }
	# return first letter
	if ($is_capital == 1)
	{
	        @new_words=map {make1stuc_rus($_)} @new_words;
	}
	return @new_words;
}
#------------------------------------------------------------------------
sub append_prefix
{
	my ($w_,$f_)=@_;
	my ($is_capital)=is1stuc_rus($w_);
        $w_=russian_lc($w_);
        my(@new_words);
        foreach my $aff_ (@{$affixes{$f_}})
        {
        	my($re_,$actions_)=split/\t/,$aff_;
                # save
		push @new_words,"$actions_$w_";
        }
	# return first letter
	if ($is_capital == 1)
	{
	        @new_words=map {make1stuc_rus($_)} @new_words;
	}
	return @new_words;
}
#------------------------------------------------------------------------
#	MAIN ROUTINE
#------------------------------------------------------------------------
print "Read affix file...";
open AFF,"$affix_filename";
while (<AFF>)
{
	chomp;
	next if (/^#/);
	if (/^prefixes/)
	{
		$change_type=0;
		next; 
	}
	if (/^suffixes/)
	{
		$change_type=1;
		next; 
	}
	# begin
	aa:
	if (/flag\s+\*(\w):/)
	{
		$affix=$1;
		while (<AFF>)
		{
		        chomp;
			if (/^prefixes/)
			{
				$change_type=0;
				goto aa;
			}
			if (/^suffixes/)
			{
				$change_type=1;
				goto aa;
			}
			if (/flag\s+\*(\w):/)
			{
				goto aa;
			}
			next if (/^#/ or $_ eq '');
			s/^\s+(.*)?\s+>\s+(.*)?\s+?#.*$/$1\t$2/;
			s/\t\t/\t/g;
			s/ //g;
			$_=russian_lc($_);
			# save to hash
			push @{$affixes{$affix}},"$_";
			# ...и в вспомогательный хеш
			if ($change_type == 0)	# prefixes
			{
				$prefix{$affix}=1;	
			}
		}
	}
}
print "\rRead done.                  \n";
$words_total=0;
open DIC,"$dic_file";
open NEWDIC,">$fin_dic_file";
while (<DIC>)
{
	chomp;
	my($word,$flag)=split /\//;
        $prefix_exists=0;
	my(@flags)=split//,$flag;
	my(@preffss);
	foreach $fls_ (@flags)
	{
		if ($prefix{$fls_}==1)
		{
			push @preffss,$fls_;
	                # удалим из строки нашу приставку
			$flag=~s/$fls_//g;
			$prefix_exists=1;
		}		
	}
	# поскольку удаляли, еще разик раздраконим паттерн 
	my(@flags)=split//,$flag;
#	print @preffss;
	# main word
	print NEWDIC $word;
	if ($garbage_output ==0)
	{
		print NEWDIC "\n"; 
	}
	else
	{
		print NEWDIC " "; 
	}
	# главное слово с приставкой
	if ($prefix_exists==1)
	{
	        foreach $pre_ (@preffss)
	        {
				print NEWDIC append_prefix($word,$pre_);
				if ($garbage_output ==0)
				{
					print NEWDIC "\n"; 
				}
				else
				{
					print NEWDIC " "; 
				}
	        }
	}
	my(@noword_);
	foreach $fl (@flags)
	{
	        foreach $res_ (gen_word($word,$fl))
	        {
	        	if ($prefix_exists==1)
	        	{
	        		push @noword_,$res_;
	        	}
			print NEWDIC "$res_";
			if ($garbage_output ==0)
			{
				print NEWDIC "\n"; 
			}
			else
			{
				print NEWDIC " "; 
			}
		}
	}
	# напечатаю-ка я с приствками...
	if ($prefix_exists==1)
	{
	        foreach $pre_ (@preffss)
	        {
		        foreach $res_ (@noword_)
		        {
				print NEWDIC append_prefix($res_,$pre_);
				if ($garbage_output ==0)
				{
					print NEWDIC "\n"; 
				}
				else
				{
					print NEWDIC " "; 
				}
		        }
	        }
	}
        $words_total++;
	print "\rGenerated - $words_total";
}
close DIC;
close NEWDIC;
 
1 , Евгений  (?? ), 23:36, 17/03/2012  [ответить ]  
+ – 
2. плюс еще print NEWDIC записать повсюду как print NEWDIC $word,"\t",ла-ла-ла что было, это хоть слово покажет из которого генерили.