File Coverage

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


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