File Coverage

blib/lib/Lingua/Stem/Uk.pm
Criterion Covered Total %
statement 62 82 75.6
branch 14 38 36.8
condition 2 6 33.3
subroutine 10 12 83.3
pod 4 4 100.0
total 92 142 64.7


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