File Coverage

blib/lib/Lingua/Stem/Ru.pm
Criterion Covered Total %
statement 51 71 71.8
branch 18 38 47.3
condition 2 6 33.3
subroutine 7 9 77.7
pod 4 4 100.0
total 82 128 64.0


line stmt bran cond sub pod time code
1             package Lingua::Stem::Ru;
2             $Lingua::Stem::Ru::VERSION = '0.04';
3 1     1   12637 use 5.006;
  1         2  
4 1     1   3 use strict;
  1         1  
  1         15  
5 1     1   3 use warnings;
  1         3  
  1         27  
6 1     1   3 use Exporter 5.57 'import';
  1         12  
  1         27  
7 1     1   3 use Carp;
  1         1  
  1         877  
8              
9             our @EXPORT = ();
10             our @EXPORT_OK = qw (stem stem_word clear_stem_cache stem_caching);
11             our %EXPORT_TAGS = ();
12              
13             my $Stem_Caching = 0;
14             my $Stem_Cache = {};
15              
16             my $VOWEL = qr/аеиоуыэюя/;
17             my $PERFECTIVEGROUND = qr/((ив|ивши|ившись|ыв|ывши|ывшись)|((?<=[ая])(в|вши|вшись)))$/;
18             my $REFLEXIVE = qr/(с[яь])$/;
19             my $ADJECTIVE = qr/(ее|ие|ые|ое|ими|ыми|ей|ий|ый|ой|ем|им|ым|ом|его|ого|ему|ому|их|ых|ую|юю|ая|яя|ою|ею)$/;
20             my $PARTICIPLE = qr/((ивш|ывш|ующ)|((?<=[ая])(ем|нн|вш|ющ|щ)))$/;
21             my $VERB = qr/((ила|ыла|ена|ейте|уйте|ите|или|ыли|ей|уй|ил|ыл|им|ым|ен|ило|ыло|ено|ят|ует|уют|ит|ыт|ены|ить|ыть|ишь|ую|ю)|((?<=[ая])(ла|на|ете|йте|ли|й|л|ем|н|ло|но|ет|ют|ны|ть|ешь|нно)))$/;
22             my $NOUN = qr/(а|ев|ов|ие|ье|е|иями|ями|ами|еи|ии|и|ией|ей|ой|ий|й|иям|ям|ием|ем|ам|ом|о|у|ах|иях|ях|ы|ь|ию|ью|ю|ия|ья|я)$/;
23             my $RVRE = qr/^(.*?[$VOWEL])(.*)$/;
24             my $DERIVATIONAL = qr/[^$VOWEL][$VOWEL]+[^$VOWEL]+[$VOWEL].*(?<=о)сть?$/;
25              
26             sub stem {
27 3 50   3 1 455 return [] if ($#_ == -1);
28 3         3 my $parm_ref;
29 3 50       4 if (ref $_[0]) {
30 3         4 $parm_ref = shift;
31             } else {
32 0         0 $parm_ref = { @_ };
33             }
34              
35 3         3 my $words = [];
36 3         4 my $locale = 'ru';
37 3         3 my $exceptions = {};
38 3         7 foreach (keys %$parm_ref) {
39 3         4 my $key = lc ($_);
40 3 50       4 if ($key eq '-words') {
    0          
    0          
41 3         3 @$words = @{$parm_ref->{$key}};
  3         8  
42             } elsif ($key eq '-exceptions') {
43 0         0 $exceptions = $parm_ref->{$key};
44             } elsif ($key eq '-locale') {
45 0         0 $locale = $parm_ref->{$key};
46             } else {
47 0         0 croak (__PACKAGE__ . "::stem() - Unknown parameter '$key' with value '$parm_ref->{$key}'\n");
48             }
49             }
50              
51 3         4 local( $_ );
52 3         4 foreach (@$words) {
53             # Flatten case
54 9         9 $_ = lc $_;
55              
56             # Check against exceptions list
57 9 50       12 if (exists $exceptions->{$_}) {
58 0         0 $_ = $exceptions->{$_};
59 0         0 next;
60             }
61              
62             # Check against cache of stemmed words
63 9         7 my $original_word = $_;
64 9 0 33     10 if ($Stem_Caching && exists $Stem_Cache->{$original_word}) {
65 0         0 $_ = $Stem_Cache->{$original_word};
66 0         0 next;
67             }
68              
69 9         10 $_ = stem_word($_);
70              
71 9 50       16 $Stem_Cache->{$original_word} = $_ if $Stem_Caching;
72             }
73 3 50       7 $Stem_Cache = {} if ($Stem_Caching < 2);
74              
75 3         5 return $words;
76             }
77              
78             sub stem_word {
79 49682     49682 1 338486 my $word = lc shift;
80              
81             # Check against cache of stemmed words
82 49682 0 33     59012 if ($Stem_Caching && exists $Stem_Cache->{$word}) {
83 0         0 return $Stem_Cache->{$word};
84             }
85              
86 49682         132540 my ($start, $RV) = $word =~ /$RVRE/;
87 49682 100       62089 return $word unless $RV;
88              
89             # Step 1
90 49465 100       159732 unless ($RV =~ s/$PERFECTIVEGROUND//) {
91 49033         65285 $RV =~ s/$REFLEXIVE//;
92              
93 49033 100       115789 if ($RV =~ s/$ADJECTIVE//) {
94 15241         33545 $RV =~ s/$PARTICIPLE//;
95             } else {
96 33792 100       137356 $RV =~ s/$NOUN// unless $RV =~ s/$VERB//;
97             }
98             }
99              
100             # Step 2
101 49465         37904 $RV =~ s/и$//;
102              
103             # Step 3
104 49465 100       89136 $RV =~ s/ость?$// if $RV =~ /$DERIVATIONAL/;
105              
106             # Step 4
107 49465 100       59928 unless ($RV =~ s/ь$//) {
108 49034         31836 $RV =~ s/ейше?//;
109 49034         32381 $RV =~ s/нн$/н/;
110             }
111              
112 49465         75975 return $start.$RV;
113             }
114              
115             sub stem_caching {
116 0     0 1   my $parm_ref;
117 0 0         if (ref $_[0]) {
118 0           $parm_ref = shift;
119             } else {
120 0           $parm_ref = { @_ };
121             }
122 0           my $caching_level = $parm_ref->{-level};
123 0 0         if (defined $caching_level) {
124 0 0         if ($caching_level !~ m/^[012]$/) {
125 0           croak(__PACKAGE__ . "::stem_caching() - Legal values are '0','1' or '2'. '$caching_level' is not a legal value");
126             }
127 0           $Stem_Caching = $caching_level;
128             }
129 0           return $Stem_Caching;
130             }
131              
132             sub clear_stem_cache {
133 0     0 1   $Stem_Cache = {};
134             }
135            
136              
137             1;
138             __END__