File Coverage

blib/lib/Lingua/VIE/Word2Num.pm
Criterion Covered Total %
statement 23 28 82.1
branch 0 6 0.0
condition 2 4 50.0
subroutine 9 10 90.0
pod 3 3 100.0
total 37 51 72.5


line stmt bran cond sub pod time code
1             # For Emacs: -*- mode:cperl; eval: (folding-mode 1); coding:utf-8 -*-
2             package Lingua::VIE::Word2Num;
3             # ABSTRACT: Word to number conversion in Vietnamese
4              
5 1     1   98056 use 5.16.0;
  1         3  
6 1     1   4 use utf8;
  1         2  
  1         10  
7 1     1   21 use warnings;
  1         2  
  1         54  
8              
9             # {{{ use block
10              
11 1     1   528 use Export::Attrs;
  1         9402  
  1         8  
12 1     1   1234 use Parse::RecDescent;
  1         36053  
  1         7  
13              
14             # }}}
15             # {{{ var block
16             our $VERSION = '0.2603300';
17             my $parser = vie_numerals();
18              
19             # }}}
20              
21             # {{{ w2n convert text to number
22              
23             sub w2n :Export {
24 2   100 2 1 258794 my $input = shift // return;
25              
26 1         14 return $parser->numeral($input);
27 1     1   130 }
  1         1  
  1         7  
28              
29             # }}}
30             # {{{ vie_numerals create parser for vietnamese numerals
31              
32             sub vie_numerals {
33 1     1 1 5 return Parse::RecDescent->new(q{
34            
35              
36             numeral: mega
37             | kOhOd
38             | { }
39              
40             # units in isolation (0..9)
41             number: 'không' { 0 }
42             | 'một' { 1 }
43             | 'hai' { 2 }
44             | 'ba' { 3 }
45             | 'bốn' { 4 }
46             | 'năm' { 5 }
47             | 'sáu' { 6 }
48             | 'bảy' { 7 }
49             | 'tám' { 8 }
50             | 'chín' { 9 }
51              
52             # compound unit variants (after mươi)
53             compound_unit: 'mốt' { 1 }
54             | 'tư' { 4 }
55             | 'lăm' { 5 }
56             | number
57              
58             # units after mười (11..19): lăm for 5, bốn for 4, regular otherwise
59             muoi_unit: 'lăm' { 5 }
60             | 'bốn' { 4 }
61             | number
62              
63             # 10..19
64             teens: 'mười' muoi_unit { 10 + $item[2] }
65             | 'mười' { 10 }
66              
67             # 20..99
68             tens: number 'mươi' compound_unit { $item[1] * 10 + $item[3] }
69             | number 'mươi' { $item[1] * 10 }
70              
71             deca: tens
72             | teens
73             | number
74              
75             # hundreds: lẻ marks a zero-tens placeholder (e.g. 101 = một trăm lẻ một)
76             hecto: number 'trăm' 'lẻ' number { $item[1] * 100 + $item[4] }
77             | number 'trăm' deca { $item[1] * 100 + $item[3] }
78             | number 'trăm' { $item[1] * 100 }
79              
80             hOd: hecto
81             | deca
82              
83             # thousands: không trăm marks hundreds=0 (e.g. 1005 = một nghìn không trăm lẻ năm)
84             kilo: hOd 'nghìn' 'không' 'trăm' deca { $item[1] * 1000 + $item[5] }
85             | hOd 'nghìn' hOd { $item[1] * 1000 + $item[3] }
86             | hOd 'nghìn' { $item[1] * 1000 }
87             | hOd 'ngàn' 'không' 'trăm' deca { $item[1] * 1000 + $item[5] }
88             | hOd 'ngàn' hOd { $item[1] * 1000 + $item[3] }
89             | hOd 'ngàn' { $item[1] * 1000 }
90              
91             kOhOd: kilo
92             | hOd
93              
94             mega: hOd 'triệu' 'không' 'nghìn' hOd { $item[1] * 1_000_000 + $item[5] }
95             | hOd 'triệu' kOhOd { $item[1] * 1_000_000 + $item[3] }
96             | hOd 'triệu' { $item[1] * 1_000_000 }
97             });
98             }
99              
100             # }}}
101             # {{{ ordinal2cardinal convert ordinal text to cardinal text
102              
103             sub ordinal2cardinal :Export {
104 0   0 0 1   my $input = shift // return;
105              
106             # Vietnamese ordinals: prefix "thứ " to cardinal, with two specials.
107             # "thứ nhất" (1st) → "một"
108 0 0         return 'một' if $input eq 'thứ nhất';
109             # "thứ tư" (4th) → "bốn"
110 0 0         return 'bốn' if $input eq 'thứ tư';
111              
112             # Regular: strip "thứ " prefix ([ ] needed because /x ignores bare spaces)
113 0 0         $input =~ s{\Athứ[ ]}{}xms and return $input;
114              
115 0           return; # not an ordinal
116 1     1   374 }
  1         2  
  1         4  
117              
118             # }}}
119              
120             1;
121              
122             __END__