File Coverage

blib/lib/Lingua/ZHO/Word2Num.pm
Criterion Covered Total %
statement 22 22 100.0
branch 2 2 100.0
condition 4 4 100.0
subroutine 8 8 100.0
pod 2 2 100.0
total 38 38 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::ZHO::Word2Num;
4             # ABSTRACT: Word 2 number conversion in ZHO.
5              
6             # {{{ use block
7              
8 1     1   104193 use 5.10.1;
  1         3  
9              
10 1     1   4 use strict;
  1         1  
  1         21  
11 1     1   3 use warnings;
  1         10  
  1         46  
12              
13 1     1   489 use Export::Attrs;
  1         8095  
  1         5  
14 1     1   1112 use Parse::RecDescent;
  1         31196  
  1         6  
15              
16             # }}}
17             # {{{ variable declarations
18             our $VERSION = '0.2603230';
19             my $parser = zho_numerals();
20              
21             # }}}
22              
23             # {{{ w2n convert number to text
24              
25             sub w2n :Export {
26 4   100 4 1 232153 my $input = shift // return;
27              
28 3 100       26 return 0 if ($input =~ m{\b(nul|ling)\b}xmsi);
29              
30 2         5 $input .= " "; # Grant space at the end
31              
32 2   100     26 return $parser->numeral($input) || undef;
33 1     1   137 }
  1         1  
  1         7  
34              
35             # }}}
36             # {{{ zho_numerals create parser for numerals
37              
38             sub zho_numerals {
39 1     1 1 5 return Parse::RecDescent->new(q{
40             numeral:
41             numeral: million { return $item[1]; } # root parse. go from maximum to minimum value
42             | millenium2 { return $item[1]; }
43             | millenium1 { return $item[1]; }
44             | century { return $item[1]; }
45             | decade { return $item[1]; }
46             | { return undef; }
47              
48             number: 'nul ' { $return = 0; } # try to find a word from 0 to 10
49             | 'Yi ' { $return = 1; }
50             | 'Er ' { $return = 2; }
51             | 'San ' { $return = 3; }
52             | 'Si ' { $return = 4; }
53             | 'Wu ' { $return = 5; }
54             | 'Liu ' { $return = 6; }
55             | 'Qi ' { $return = 7; }
56             | 'Ba ' { $return = 8; }
57             | 'Jiu ' { $return = 9; }
58             | 'Shi ' { $return = 10; }
59              
60             tens: 'YiShi ' { $return = 10; } # try to find a word that representates
61             | 'ErShi ' { $return = 20; } # values 20,30,..,90
62             | 'SanShi ' { $return = 30; }
63             | 'SiShi ' { $return = 40; }
64             | 'WuShi ' { $return = 50; }
65             | 'LiuShi ' { $return = 60; }
66             | 'QiShi ' { $return = 70; }
67             | 'BaShi ' { $return = 80; }
68             | 'JiuShi ' { $return = 90; }
69              
70             hundreds: 'YiBai ' { $return = 100; } # try to find a word that representates
71             | 'ErBai ' { $return = 200; } # values 100,200,..,900
72             | 'SanBai ' { $return = 300; }
73             | 'SiBai ' { $return = 400; }
74             | 'WuBai ' { $return = 500; }
75             | 'LiuBai ' { $return = 600; }
76             | 'QiBai ' { $return = 700; }
77             | 'BaBai ' { $return = 800; }
78             | 'JiuBai ' { $return = 900; }
79              
80             thousands: 'YiQian ' { $return = 1000; } # try to find a word that representates
81             | 'ErQian ' { $return = 2000; } # values 1000,2000,..,9000
82             | 'SanQian ' { $return = 3000; }
83             | 'SiQian ' { $return = 4000; }
84             | 'WuQian ' { $return = 5000; }
85             | 'LiuQian ' { $return = 6000; }
86             | 'QiQian ' { $return = 7000; }
87             | 'BaQian ' { $return = 8000; }
88             | 'JiuQian ' { $return = 9000; }
89              
90             tenthousands: 'YiWan ' { $return = 10000; } # try to find a word that representates
91             | 'ErWan ' { $return = 20000; } # values 10000,20000,..,90000
92             | 'SanWan ' { $return = 30000; }
93             | 'SiWan ' { $return = 40000; }
94             | 'WuWan ' { $return = 50000; }
95             | 'LiuWan ' { $return = 60000; }
96             | 'QiWan ' { $return = 70000; }
97             | 'BaWan ' { $return = 80000; }
98             | 'JiuWan ' { $return = 90000; }
99              
100             decade: tens(?) number(?) number(?) # try to find words that represents values
101             { $return = 0; # from 0 to 20
102             for (@item) {
103             $return += $$_[0] if (ref $_ && defined $$_[0]);
104             }
105             }
106              
107             century: hundreds(?) decade(?) # try to find words that represents values
108             { $return = 0; # from 100 to 999
109             for (@item) {
110             $return += $$_[0] if (ref $_ && defined $$_[0]);
111             }
112             }
113              
114             millenium1: thousands(1) century(?) # try to find words that represents values
115             { $return = 0; # from 1.000 to 999.999
116             for (@item) {
117             if (ref $_ && defined $$_[0]) {
118             $return += $$_[0] if (ref $_ && defined $$_[0]);
119             }
120             }
121             }
122              
123             millenium2: tenthousands(1) thousands(?) century(?) decade(?) # try to find words that represents values
124             { $return = 0; # from 1.000 to 999.999
125             for (@item) {
126             if (ref $_ && defined $$_[0]) {
127             $return += $$_[0] if (ref $_ && defined $$_[0]);
128             }
129             }
130             }
131              
132             million: millenium2(?) millenium1(?) century(?) decade(?) # try to find words that represents values
133             ' Wan ' # from 1.000.000 to 999.999.999.999
134             millenium2(?) millenium1(?) century(?) decade(?)
135             { $return = 0;
136             for (@item) {
137             if (ref $_ && defined $$_[0]) {
138             $return += $$_[0];
139             } elsif ($_ eq "Wan") {
140             $return = ($return>0) ? $return * 100000 : 100000;
141             }
142             }
143             }
144             });
145             }
146              
147             # }}}
148              
149             1;
150              
151             __END__