File Coverage

blib/lib/Lingua/RUS/Word2Num.pm
Criterion Covered Total %
statement 34 34 100.0
branch n/a
condition 2 2 100.0
subroutine 10 10 100.0
pod 2 2 100.0
total 48 48 100.0


line stmt bran cond sub pod time code
1             # For Emacs: -*- mode:cperl; eval: (folding-mode 1); coding:utf-8 -*-
2              
3             package Lingua::RUS::Word2Num;
4             # ABSTRACT: Word 2 number conversion in RUS.
5              
6             # {{{ use block
7              
8 1     1   135375 use 5.10.1;
  1         4  
9              
10 1     1   7 use strict;
  1         14  
  1         46  
11 1     1   7 use warnings;
  1         1  
  1         64  
12              
13 1     1   7 use utf8;
  1         3  
  1         7  
14 1     1   785 use Export::Attrs;
  1         17380  
  1         10  
15 1     1   153 use Carp;
  1         4  
  1         108  
16 1     1   1383 use Parse::RecDescent;
  1         68979  
  1         10  
17              
18             # }}}
19             # {{{ variable declarations
20             our $VERSION = '0.2603230';
21             my $parser = ru_numerals();
22              
23             # }}}
24              
25             # {{{ w2n convert number to text
26              
27             sub w2n :Export {
28 7   100 7 1 320606 my $input = shift // return;
29              
30 6         25 $input =~ s/^\s+одна тысяча / тысяч /g; # Thousand variations. We just want one
31 6         22 $input =~ s/ тысячи / тысяч /g;
32 6         17 $input =~ s/ тысячa / тысяч /g;
33 6         19 $input =~ s/ тысяча / тысяч /g;
34              
35 6         12 $input =~ s/^\s+один миллион / миллион /g; # Million variations. We just want one
36 6         51 $input =~ s/ миллиона / миллион /g;
37 6         19 $input =~ s/ миллионов / миллион /g;
38              
39 6         14 $input .= " "; # Grant end space
40              
41 6         70 return $parser->numeral($input);
42 1     1   354 }
  1         2  
  1         15  
43              
44             # }}}
45             # {{{ ru_numerals create parser for numerals
46              
47             sub ru_numerals {
48 1     1 1 6 return Parse::RecDescent->new(q{
49             numeral:
50             numeral: million { return $item[1]; } # root parse. go from maximum to minimum value
51             | millenium { return $item[1]; }
52             | century { return $item[1]; }
53             | decade { return $item[1]; }
54             | { return undef; }
55              
56             number: 'девятнадцать ' { $return = 19; } # try to find a word from 0 to 19
57             | 'восемнадцать ' { $return = 18; }
58             | 'семнадцать ' { $return = 17; }
59             | 'шестнадцать ' { $return = 16; }
60             | 'пятнадцать ' { $return = 15; }
61             | 'четырнадцать ' { $return = 14; }
62             | 'тринадцать ' { $return = 13; }
63             | 'двенадцать ' { $return = 12; }
64             | 'одинадцать ' { $return = 11; }
65             | 'десять ' { $return = 10; }
66             | 'девять ' { $return = 9; }
67             | 'восемь ' { $return = 8; }
68             | 'семь ' { $return = 7; }
69             | 'шесть ' { $return = 6; }
70             | 'пять ' { $return = 5; }
71             | 'четыре ' { $return = 4; }
72             | 'три ' { $return = 3; }
73             | 'два ' { $return = 2; }
74             | 'две ' { $return = 2; }
75             | 'одна ' { $return = 1; }
76             | 'один ' { $return = 1; }
77             | 'ноль ' { $return = 0; }
78              
79             tens: 'двадцать ' { $return = 20; } # try to find a word that representates
80             | 'тридцать ' { $return = 30; } # values 20,30,..,90
81             | 'сорок ' { $return = 40; }
82             | 'пятьдесят ' { $return = 50; }
83             | 'шестьдесят ' { $return = 60; }
84             | 'семьдесят ' { $return = 70; }
85             | 'восемьдесят ' { $return = 80; }
86             | 'девяносто ' { $return = 90; }
87              
88             hundreds: 'сто ' { $return = 100; } # try to find a word that representates
89             | 'сотня ' { $return = 100; } # values 200,300,..,900
90             | 'двести ' { $return = 200; }
91             | 'триста ' { $return = 300; }
92             | 'четыреста ' { $return = 400; }
93             | 'пятьсот ' { $return = 500; }
94             | 'шестьсот ' { $return = 600; }
95             | 'семьсот ' { $return = 700; }
96             | 'восемьсот ' { $return = 800; }
97             | 'девятьсот ' { $return = 900; }
98              
99             decade: tens(?) number(?) # try to find words that represents values
100             { $return = -1; # from 0 to 99
101             for (@item) {
102             if (ref $_ && defined $$_[0]) {
103             $return += $$_[0] if ($return != -1);
104             $return = $$_[0] if ($return == -1);
105             }
106             }
107             $return = undef if ($return == -1);
108             }
109              
110             century: hundreds(?) decade(?) # try to find words that represents values
111             { $return = 0; # from 100 to 999
112             for (@item) {
113             $return += $$_[0] if (ref $_ && defined $$_[0]);
114             }
115             $return ||= undef;
116             }
117              
118             millenium: century(?) decade(?) 'тысяч ' century(?) decade(?) # try to find words that represents values
119             { $return = 0; # from 1.000 to 999.999
120             for (@item) {
121             if (ref $_ && defined $$_[0]) {
122             $return += $$_[0];
123             } elsif ($_ eq "тысяч ") {
124             $return = ($return>0) ? $return * 1000 : 1000;
125             }
126             }
127             $return ||= undef;
128             }
129              
130             million: century(?) decade(?) # try to find words that represents values
131             'миллион ' # from 1.000.000 to 999.999.999
132             millenium(?) century(?) decade(?)
133             { $return = 0;
134             for (@item) {
135             if (ref $_ && defined $$_[0]) {
136             $return += $$_[0];
137             } elsif ($_ eq "миллион ") {
138             $return = ($return>0) ? $return * 1000000 : 1000000;
139             }
140             }
141             $return ||= undef;
142             }
143             });
144             }
145              
146             # }}}
147              
148             1;
149              
150             __END__