Allow libpinyin to build in cross compile mode.
[platform/upstream/libpinyin.git] / src / storage / pinyin_parser2.h
1 /* 
2  *  libpinyin
3  *  Library to deal with pinyin.
4  *  
5  *  Copyright (C) 2011 Peng Wu <alexepico@gmail.com>
6  *  
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  * 
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  *  GNU General Public License for more details.
16  *  
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20  */
21
22 #ifndef PINYIN_PARSER2_H
23 #define PINYIN_PARSER2_H
24
25 #include <glib.h>
26 #include "novel_types.h"
27 #include "chewing_key.h"
28 #include "pinyin_custom2.h"
29
30 namespace pinyin{
31
32 typedef struct {
33     const char * m_pinyin_str;
34     const char * m_shengmu_str;
35     const char * m_yunmu_str;
36     const char * m_chewing_str;
37     ChewingKey   m_chewing_key;
38 } content_table_item_t;
39
40 typedef struct {
41     const char * m_pinyin_input;
42     guint32      m_flags;
43     guint16      m_table_index;
44 } pinyin_index_item_t;
45
46 typedef struct {
47     const char * m_chewing_input;
48     guint32      m_flags;
49     guint16      m_table_index;
50 } chewing_index_item_t;
51
52 typedef struct {
53     const char * m_orig_key;
54     guint32      m_orig_freq;
55     const char * m_new_keys[2];
56     guint32      m_new_freq;
57 } divided_table_item_t;
58
59 typedef struct {
60     const char * m_orig_keys[2];
61     guint32      m_orig_freq;
62     const char * m_new_keys[2];
63     guint32      m_new_freq;
64 } resplit_table_item_t;
65
66 typedef struct {
67     const char * m_shengmu;
68 } double_pinyin_scheme_shengmu_item_t;
69
70 typedef struct {
71     const char * m_yunmus[2];
72 } double_pinyin_scheme_yunmu_item_t;
73
74 typedef struct {
75     const char m_input;
76     const char * m_chewing;
77 } chewing_symbol_item_t;
78
79 typedef struct {
80     const char m_input;
81     const char m_tone;
82 } chewing_tone_item_t;
83
84 typedef GArray * ParseValueVector;
85
86
87 /**
88  * PhoneticParser2:
89  *
90  * Parse the ascii string into an array of the struct ChewingKeys.
91  *
92  */
93 class PhoneticParser2
94 {
95 public:
96     /**
97      * PhoneticParser2::~PhoneticParser2:
98      *
99      * The destructor of the PhoneticParser2.
100      *
101      */
102     virtual ~PhoneticParser2() {}
103
104 public:
105     /**
106      * PhoneticParser2::parse_one_key:
107      * @options: the pinyin options from pinyin_custom2.h.
108      * @key: the parsed result of struct ChewingKey.
109      * @str: the input of the ascii string.
110      * @len: the length of the str.
111      * @returns: whether the entire string is parsed as one key.
112      *
113      * Parse only one struct ChewingKey from a string.
114      *
115      */
116     virtual bool parse_one_key(pinyin_option_t options, ChewingKey & key, const char *str, int len) const = 0;
117
118     /**
119      * PhoneticParser2::parse:
120      * @options: the pinyin options from pinyin_custom2.h.
121      * @keys: the parsed result of struct ChewingKeys.
122      * @str: the input of the ascii string.
123      * @len: the length of the str.
124      * @returns: the number of chars were actually used.
125      *
126      * Parse the ascii string into an array of struct ChewingKeys.
127      *
128      */
129     virtual int parse(pinyin_option_t options, ChewingKeyVector & keys, ChewingKeyRestVector & key_rests, const char *str, int len) const = 0;
130
131 };
132
133
134 /**
135  * FullPinyinParser2:
136  *
137  * Parses the full pinyin string into an array of struct ChewingKeys.
138  *
139  */
140 class FullPinyinParser2 : public PhoneticParser2
141 {
142     /* Note: some internal pointers to full pinyin table. */
143
144 protected:
145     ParseValueVector m_parse_steps;
146
147     int final_step(size_t step_len, ChewingKeyVector & keys,
148                    ChewingKeyRestVector & key_rests) const;
149
150     bool post_process2(pinyin_option_t options, ChewingKeyVector & keys,
151                        ChewingKeyRestVector & key_rests,
152                        const char * str, int len) const;
153
154 public:
155     const divided_table_item_t * retrieve_divided_item
156     (pinyin_option_t options, ChewingKey * key, ChewingKeyRest * rest,
157      const char * str, int len) const;
158
159     const resplit_table_item_t * retrieve_resplit_item_by_original_pinyins
160     (pinyin_option_t options,
161      ChewingKey * cur_key, ChewingKeyRest * cur_rest,
162      ChewingKey * next_key, ChewingKeyRest * next_rest,
163      const char * str, int len) const;
164     const resplit_table_item_t * retrieve_resplit_item_by_resplit_pinyins
165     (pinyin_option_t options,
166      ChewingKey * cur_key, ChewingKeyRest * cur_rest,
167      ChewingKey * next_key, ChewingKeyRest * next_rest,
168      const char * str, int len) const;
169
170 public:
171     FullPinyinParser2();
172     virtual ~FullPinyinParser2() {
173         g_array_free(m_parse_steps, TRUE);
174     }
175
176     virtual bool parse_one_key(pinyin_option_t options, ChewingKey & key, const char *str, int len) const;
177
178     /* Note:
179      *   the parse method will use dynamic programming to drive parse_one_key.
180      */
181     virtual int parse(pinyin_option_t options, ChewingKeyVector & keys, ChewingKeyRestVector & key_rests, const char *str, int len) const;
182 };
183
184
185 /**
186  * DoublePinyinParser2:
187  *
188  * Parse the double pinyin string into an array of struct ChewingKeys.
189  *
190  */
191 /* The valid input chars of ShuangPin is a-z and ';'
192  */
193 class DoublePinyinParser2 : public PhoneticParser2
194 {
195     /* Note: two internal pointers to double pinyin scheme table. */
196 protected:
197     const double_pinyin_scheme_shengmu_item_t * m_shengmu_table;
198     const double_pinyin_scheme_yunmu_item_t   * m_yunmu_table;
199
200 public:
201     DoublePinyinParser2() {
202         m_shengmu_table = NULL; m_yunmu_table = NULL;
203         set_scheme(DOUBLE_PINYIN_DEFAULT);
204     }
205
206     virtual ~DoublePinyinParser2() {}
207
208     virtual bool parse_one_key(pinyin_option_t options, ChewingKey & key, const char *str, int len) const;
209
210     virtual int parse(pinyin_option_t options, ChewingKeyVector & keys, ChewingKeyRestVector & key_rests, const char *str, int len) const;
211
212 public:
213     bool set_scheme(DoublePinyinScheme scheme);
214 };
215
216
217 /**
218  * ChewingParser2:
219  *
220  * Parse the chewing string into an array of struct ChewingKeys.
221  *
222  * Several keyboard scheme are supported:
223  * * Chewing_STANDARD  Standard ZhuYin keyboard, which maps 1 to Bo(ㄅ), q to Po(ㄆ) etc.
224  * * Chewing_IBM       IBM ZhuYin keyboard, which maps 1 to Bo(ㄅ), 2 to Po(ㄆ) etc.
225  * * Chewing_GINYIEH   Gin-Yieh ZhuYin keyboard.
226  * * Chewing_ETEN      Eten (倚天) ZhuYin keyboard.
227  *
228  */
229
230 /* Note: maybe yunmus shuffle will be supported later.
231  *         currently this feature is postponed.
232  */
233 class ChewingParser2 : public PhoneticParser2
234 {
235     /* Note: some internal pointers to chewing scheme table. */
236 protected:
237     const chewing_symbol_item_t * m_symbol_table;
238     const chewing_tone_item_t   * m_tone_table;
239
240 public:
241     ChewingParser2() {
242         m_symbol_table = NULL; m_tone_table = NULL;
243         set_scheme(CHEWING_DEFAULT);
244     }
245
246     virtual ~ChewingParser2() {}
247
248     virtual bool parse_one_key(pinyin_option_t options, ChewingKey & key, const char *str, int len) const;
249
250     virtual int parse(pinyin_option_t options, ChewingKeyVector & keys, ChewingKeyRestVector & key_rests, const char *str, int len) const;
251
252 public:
253     bool set_scheme(ChewingScheme scheme);
254     bool in_chewing_scheme(pinyin_option_t options, const char key, const char ** symbol) const;
255 };
256
257
258 /* compare pinyins with chewing internal representations. */
259 inline int pinyin_compare_initial2(pinyin_option_t options,
260                                    ChewingInitial lhs,
261                                    ChewingInitial rhs) {
262     if (lhs == rhs)
263         return 0;
264
265     if ((options & PINYIN_AMB_C_CH) &&
266         ((lhs == CHEWING_C && rhs == CHEWING_CH) ||
267          (lhs == CHEWING_CH && rhs == CHEWING_C)))
268         return 0;
269
270     if ((options & PINYIN_AMB_S_SH) &&
271         ((lhs == CHEWING_S && rhs == CHEWING_SH) ||
272          (lhs == CHEWING_SH && rhs == CHEWING_S)))
273         return 0;
274
275     if ((options & PINYIN_AMB_Z_ZH) &&
276         ((lhs == CHEWING_Z && rhs == CHEWING_ZH) ||
277          (lhs == CHEWING_ZH && rhs == CHEWING_Z)))
278         return 0;
279
280     if ((options & PINYIN_AMB_F_H) &&
281         ((lhs == CHEWING_F && rhs == CHEWING_H) ||
282          (lhs == CHEWING_H && rhs == CHEWING_F)))
283         return 0;
284
285     if ((options & PINYIN_AMB_L_N) &&
286         ((lhs == CHEWING_L && rhs == CHEWING_N) ||
287          (lhs == CHEWING_N && rhs == CHEWING_L)))
288         return 0;
289
290     if ((options & PINYIN_AMB_L_R) &&
291         ((lhs == CHEWING_L && rhs == CHEWING_R) ||
292          (lhs == CHEWING_R && rhs == CHEWING_L)))
293         return 0;
294
295     if ((options & PINYIN_AMB_G_K) &&
296         ((lhs == CHEWING_G && rhs == CHEWING_K) ||
297          (lhs == CHEWING_K && rhs == CHEWING_G)))
298         return 0;
299
300     return (lhs - rhs);
301 }
302
303
304 inline int pinyin_compare_middle_and_final2(pinyin_option_t options,
305                                             ChewingMiddle middle_lhs,
306                                             ChewingMiddle middle_rhs,
307                                             ChewingFinal final_lhs,
308                                             ChewingFinal final_rhs) {
309     if (middle_lhs == middle_rhs && final_lhs == final_rhs)
310         return 0;
311
312     /* both pinyin and chewing incomplete options will enable this. */
313     if (options & (PINYIN_INCOMPLETE | CHEWING_INCOMPLETE)) {
314         if (middle_lhs == CHEWING_ZERO_MIDDLE &&
315             final_lhs == CHEWING_ZERO_FINAL)
316             return 0;
317         if (middle_rhs == CHEWING_ZERO_MIDDLE &&
318             final_rhs == CHEWING_ZERO_FINAL)
319             return 0;
320     }
321
322     /* compare chewing middle first. */
323     int middle_diff = middle_lhs - middle_rhs;
324     if (middle_diff)
325         return middle_diff;
326
327     if ((options & PINYIN_AMB_AN_ANG) &&
328         ((final_lhs == CHEWING_AN && final_rhs == CHEWING_ANG) ||
329          (final_lhs == CHEWING_ANG && final_rhs == CHEWING_AN)))
330         return 0;
331
332     if ((options & PINYIN_AMB_EN_ENG) &&
333         ((final_lhs == CHEWING_EN && final_rhs == CHEWING_ENG) ||
334          (final_lhs == CHEWING_ENG && final_rhs == CHEWING_EN)))
335         return 0;
336
337     if ((options & PINYIN_AMB_IN_ING) &&
338         ((final_lhs == PINYIN_IN && final_rhs == PINYIN_ING) ||
339          (final_lhs == PINYIN_ING && final_rhs == PINYIN_IN)))
340         return 0;
341
342     return (final_lhs - final_rhs);
343 }
344
345
346 inline int pinyin_compare_tone2(pinyin_option_t options,
347                                 ChewingTone lhs,
348                                 ChewingTone rhs) {
349     if (lhs == rhs)
350         return 0;
351     if (lhs == CHEWING_ZERO_TONE)
352         return 0;
353     if (rhs == CHEWING_ZERO_TONE)
354         return 0;
355     return (lhs - rhs);
356 }
357
358
359 };
360
361 #endif