~ubuntu-branches/ubuntu/raring/sunpinyin/raring

« back to all changes in this revision

Viewing changes to src/pinyin/shuangpin_seg.cpp

  • Committer: Package Import Robot
  • Author(s): YunQiang Su
  • Date: 2012-03-30 15:31:55 UTC
  • mfrom: (1.1.3) (1.2.7 sid)
  • Revision ID: package-import@ubuntu.com-20120330153155-qgls77sogzgtg9zp
Tags: 2.0.3+git20120222-1
* Team upload: git snapshot 20120222.
   - fix breaks if LDFLAGS in environment contains
       multiple words (Closese #646001).
   - rm patches merged to upstream:
       append-os-environ-toenv.patch
       fix-ftbfs-on-sh.patch
       remove-10-candidate-words-limitation.patch
   - refresh disable-lm-dict-compile.patch.
* Bump stardard version to 3.9.3: no modify needed.
* add libsunpinyin3-dbg and python-sunpinyin packages.
* debian/compat to 9, multiarch it.
* rewrite debian/rules with dh 7 format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 
 * 
 
3
 *
4
4
 * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
5
 
 * 
 
5
 *
6
6
 * The contents of this file are subject to the terms of either the GNU Lesser
7
7
 * General Public License Version 2.1 only ("LGPL") or the Common Development and
8
8
 * Distribution License ("CDDL")(collectively, the "License"). You may not use this
9
9
 * file except in compliance with the License. You can obtain a copy of the CDDL at
10
10
 * http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at
11
 
 * http://www.opensource.org/licenses/lgpl-license.php. See the License for the 
 
11
 * http://www.opensource.org/licenses/lgpl-license.php. See the License for the
12
12
 * specific language governing permissions and limitations under the License. When
13
13
 * distributing the software, include this License Header Notice in each file and
14
14
 * include the full text of the License in the License file as well as the
15
15
 * following notice:
16
 
 * 
 
16
 *
17
17
 * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
18
18
 * (CDDL)
19
19
 * For Covered Software in this distribution, this License shall be governed by the
21
21
 * Any litigation relating to this License shall be subject to the jurisdiction of
22
22
 * the Federal Courts of the Northern District of California and the state courts
23
23
 * of the State of California, with venue lying in Santa Clara County, California.
24
 
 * 
 
24
 *
25
25
 * Contributor(s):
26
 
 * 
 
26
 *
27
27
 * If you wish your version of this file to be governed by only the CDDL or only
28
28
 * the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to
29
29
 * include this software in this distribution under the [CDDL or LGPL Version 2.1]
32
32
 * Version 2.1, or to extend the choice of license to its licensees as provided
33
33
 * above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL
34
34
 * Version 2 license, then the option applies only if the new code is made subject
35
 
 * to such option by the copyright holder. 
 
35
 * to such option by the copyright holder.
36
36
 */
37
37
 
38
38
#include <cassert>
41
41
 
42
42
CShuangpinData CShuangpinSegmentor::s_shpData;
43
43
 
44
 
CShuangpinSegmentor::CShuangpinSegmentor (EShuangpinType shpType) 
 
44
CShuangpinSegmentor::CShuangpinSegmentor (EShuangpinType shpType)
45
45
    : m_updatedFrom(0), m_nAlpha(0), m_hasInvalid(false), m_nLastValidPos(0)
46
46
{
47
 
    m_segs.reserve (32);
48
 
    m_pystr.reserve (32);
 
47
    m_segs.reserve(32);
 
48
    m_pystr.reserve(32);
49
49
    s_shpData.setShuangpinType(shpType);
50
50
}
51
51
 
52
 
unsigned CShuangpinSegmentor::push (unsigned ch)
 
52
unsigned
 
53
CShuangpinSegmentor::push(unsigned ch)
53
54
{
54
 
    m_inputBuf.push_back (ch);
 
55
    m_inputBuf.push_back(ch);
55
56
 
56
 
    return m_updatedFrom = _push (ch);
 
57
    return m_updatedFrom = _push(ch);
57
58
}
58
59
 
59
 
unsigned CShuangpinSegmentor::pop ()
 
60
unsigned
 
61
CShuangpinSegmentor::pop()
60
62
{
61
63
    if (m_pystr.empty())
62
64
        return m_updatedFrom = 0;
63
65
 
64
 
    unsigned size = m_inputBuf.size ();
 
66
    unsigned size = m_inputBuf.size();
65
67
 
66
68
    EShuangpinType shpType = s_shpData.getShuangpinType();
67
 
    bool isInputPy = ( islower(m_pystr[size-1]) ||
68
 
                       (m_pystr[size-1] == ';' && (shpType == MS2003 || shpType == ZIGUANG)) );
 
69
    bool isInputPy = (islower(m_pystr[size - 1]) ||
 
70
                      (m_pystr[size - 1] == ';' &&
 
71
                       (shpType == MS2003 || shpType == ZIGUANG)));
69
72
    if (!isInputPy) {
70
73
        m_nAlpha -= 1;
71
74
    }
72
75
 
73
 
    m_inputBuf.resize (size - 1);
74
 
    m_pystr.resize (size - 1);
 
76
    m_inputBuf.resize(size - 1);
 
77
    m_pystr.resize(size - 1);
75
78
 
76
79
    unsigned l = m_segs.back().m_len;
77
 
    m_segs.pop_back ();
 
80
    m_segs.pop_back();
78
81
 
79
 
    if (size==1 || m_segs.back().m_type!=IPySegmentor::INVALID) {
 
82
    if (size == 1 || m_segs.back().m_type != IPySegmentor::INVALID) {
80
83
        m_hasInvalid = false;
81
84
    }
82
 
    if (l == 1) 
 
85
    if (l == 1)
83
86
        return m_updatedFrom = size - 1;
84
87
 
85
 
    std::string new_pystr = m_pystr.substr (size-l);
86
 
    m_pystr.resize (size-l);
 
88
    std::string new_pystr = m_pystr.substr(size - l);
 
89
    m_pystr.resize(size - l);
87
90
 
88
91
    m_updatedFrom = UINT_MAX;
89
92
    std::string::const_iterator it = new_pystr.begin();
90
 
    for (; it!= new_pystr.end(); ++it) {
91
 
        unsigned tmp = _push ((*it) & 0x7f);
 
93
    for (; it != new_pystr.end(); ++it) {
 
94
        unsigned tmp = _push((*it) & 0x7f);
92
95
        if (tmp < m_updatedFrom) m_updatedFrom = tmp;
93
96
    }
94
97
 
95
98
    return m_updatedFrom;
96
99
}
97
100
 
98
 
unsigned CShuangpinSegmentor::insertAt (unsigned idx, unsigned ch)
 
101
unsigned
 
102
CShuangpinSegmentor::insertAt(unsigned idx, unsigned ch)
99
103
{
100
104
    unsigned pyIdx, segIdx;
101
 
    _locateSegment (idx, pyIdx, segIdx);
102
 
 
103
 
    m_inputBuf.insert (idx, 1, ch);
104
 
    m_pystr.insert (idx, 1, ch);
105
 
 
106
 
    std::string new_pystr = m_pystr.substr (pyIdx);
107
 
    m_pystr.resize (pyIdx);
108
 
    m_segs.erase (m_segs.begin()+segIdx, m_segs.end());
109
 
    
 
105
    _locateSegment(idx, pyIdx, segIdx);
 
106
 
 
107
    m_inputBuf.insert(idx, 1, ch);
 
108
    m_pystr.insert(idx, 1, ch);
 
109
 
 
110
    std::string new_pystr = m_pystr.substr(pyIdx);
 
111
    m_pystr.resize(pyIdx);
 
112
    m_segs.erase(m_segs.begin() + segIdx, m_segs.end());
 
113
 
110
114
    if (m_nLastValidPos == idx) {
111
115
        m_hasInvalid = false;
112
 
        
113
116
    } else if (m_nLastValidPos + 1 == idx) {
114
117
        m_hasInvalid = false;
115
118
        int nSize = m_pystr.size();
116
 
        if (islower(m_pystr[nSize-1])) {
 
119
        if (islower(m_pystr[nSize - 1])) {
117
120
            m_nLastValidPos = idx - 1;
118
 
            new_pystr.insert((size_t)0, 1, m_pystr[nSize-1]);
119
 
            m_pystr.erase(nSize-1, 1);
120
 
            m_segs.erase (m_segs.begin()+segIdx-1);
121
 
        } 
122
 
    
 
121
            new_pystr.insert((size_t)0, 1, m_pystr[nSize - 1]);
 
122
            m_pystr.erase(nSize - 1, 1);
 
123
            m_segs.erase(m_segs.begin() + segIdx - 1);
 
124
        }
123
125
    } else if (m_nLastValidPos + 1 > idx) {
124
126
        m_hasInvalid = false;
125
127
        m_nLastValidPos = idx;
128
130
 
129
131
    m_updatedFrom = UINT_MAX;
130
132
    std::string::const_iterator it = new_pystr.begin();
131
 
    for (; it!= new_pystr.end(); ++it) {
132
 
        unsigned tmp = _push ((*it) & 0x7f);
 
133
    for (; it != new_pystr.end(); ++it) {
 
134
        unsigned tmp = _push((*it) & 0x7f);
133
135
        if (tmp < m_updatedFrom) m_updatedFrom = tmp;
134
136
    }
135
137
 
136
138
    return m_updatedFrom;
137
139
}
138
140
 
139
 
unsigned CShuangpinSegmentor::deleteAt (unsigned idx, bool backward)
 
141
unsigned
 
142
CShuangpinSegmentor::deleteAt(unsigned idx, bool backward)
140
143
{
141
144
    unsigned pyIdx, segIdx;
142
145
    if (!backward) idx += 1;
143
 
    _locateSegment (idx, pyIdx, segIdx);
144
 
 
145
 
    m_inputBuf.erase (idx, 1);
146
 
    m_pystr.erase (idx, 1);
147
 
 
148
 
    std::string new_pystr = m_pystr.substr (pyIdx);
149
 
    m_pystr.resize (pyIdx);
150
 
    TSegmentVec tmp_segs (m_segs.begin()+segIdx+1, m_segs.end());
151
 
    m_segs.erase (m_segs.begin()+segIdx, m_segs.end());
 
146
    _locateSegment(idx, pyIdx, segIdx);
 
147
 
 
148
    m_inputBuf.erase(idx, 1);
 
149
    m_pystr.erase(idx, 1);
 
150
 
 
151
    std::string new_pystr = m_pystr.substr(pyIdx);
 
152
    m_pystr.resize(pyIdx);
 
153
    TSegmentVec tmp_segs(m_segs.begin() + segIdx + 1, m_segs.end());
 
154
    m_segs.erase(m_segs.begin() + segIdx, m_segs.end());
152
155
 
153
156
    if (m_nLastValidPos + 1 < idx) {
154
 
       //del invalid ch, and do not effect current status. 
 
157
        //del invalid ch, and do not effect current status.
155
158
        m_pystr.insert(idx, new_pystr);
156
 
        m_segs.insert (m_segs.end(), tmp_segs.begin(), tmp_segs.end());
157
 
        return m_inputBuf.size() -1;
 
159
        m_segs.insert(m_segs.end(), tmp_segs.begin(), tmp_segs.end());
 
160
        return m_inputBuf.size() - 1;
158
161
    } else {
159
162
        m_hasInvalid = false;
160
163
        m_nAlpha = _getNumberOfNonAlpha();
162
165
 
163
166
    m_updatedFrom = UINT_MAX;
164
167
    std::string::const_iterator it = new_pystr.begin();
165
 
    for (; it!= new_pystr.end(); ++it) {
166
 
        unsigned tmp = _push ((*it) & 0x7f);
 
168
    for (; it != new_pystr.end(); ++it) {
 
169
        unsigned tmp = _push((*it) & 0x7f);
167
170
        if (tmp < m_updatedFrom) m_updatedFrom = tmp;
168
171
    }
169
172
 
170
173
    return m_updatedFrom;
171
174
}
172
175
 
173
 
unsigned CShuangpinSegmentor::clear (unsigned from)
 
176
unsigned
 
177
CShuangpinSegmentor::clear(unsigned from)
174
178
{
175
 
    m_inputBuf.resize (from);
176
 
    return _clear (from);
 
179
    m_inputBuf.resize(from);
 
180
    return _clear(from);
177
181
}
178
182
 
179
 
unsigned CShuangpinSegmentor::_clear (unsigned from)
 
183
unsigned
 
184
CShuangpinSegmentor::_clear(unsigned from)
180
185
{
181
186
    unsigned i, j;
182
 
    _locateSegment (from, i, j);
 
187
    _locateSegment(from, i, j);
183
188
 
184
 
    std::string new_pystr = m_pystr.substr (i, from-i);
185
 
    m_pystr.resize (i);
 
189
    std::string new_pystr = m_pystr.substr(i, from - i);
 
190
    m_pystr.resize(i);
186
191
    m_nAlpha = _getNumberOfNonAlpha();
187
192
 
188
 
    m_segs.erase (m_segs.begin()+j, m_segs.end());
 
193
    m_segs.erase(m_segs.begin() + j, m_segs.end());
189
194
 
190
195
    if (m_nLastValidPos + 1 >= from) {
191
196
        m_hasInvalid = false;
192
197
    }
193
 
    
 
198
 
194
199
    m_updatedFrom = from;
195
 
    
 
200
 
196
201
    for (std::string::const_iterator it = new_pystr.begin();
197
 
         it!= new_pystr.end(); ++it) {
198
 
        unsigned tmp = _push ((*it) & 0x7f);
 
202
         it != new_pystr.end(); ++it) {
 
203
        unsigned tmp = _push((*it) & 0x7f);
199
204
        if (tmp < m_updatedFrom) m_updatedFrom = tmp;
200
205
    }
201
206
 
202
207
    return m_updatedFrom;
203
208
}
204
209
 
205
 
int CShuangpinSegmentor::_getNumberOfNonAlpha() const
 
210
int
 
211
CShuangpinSegmentor::_getNumberOfNonAlpha() const
206
212
{
207
213
    int nNonAlpha = 0;
208
214
    for (const char* c = m_pystr.c_str(); *c != 0; ++c) {
212
218
    return nNonAlpha;
213
219
}
214
220
 
215
 
void CShuangpinSegmentor::_locateSegment (unsigned idx, unsigned &strIdx, unsigned &segIdx)
 
221
void
 
222
CShuangpinSegmentor::_locateSegment(unsigned idx,
 
223
                                    unsigned &strIdx,
 
224
                                    unsigned &segIdx)
216
225
{
217
226
    strIdx = segIdx = 0;
218
227
 
219
 
    TSegmentVec::const_iterator it  = m_segs.begin();
 
228
    TSegmentVec::const_iterator it = m_segs.begin();
220
229
    TSegmentVec::const_iterator ite = m_segs.end();
221
230
 
222
231
    for (; it != ite; ++it) {
223
232
        if (strIdx + it->m_len > idx)
224
 
           break; 
 
233
            break;
225
234
 
226
235
        strIdx += it->m_len;
227
236
        segIdx += 1;
228
237
    }
229
238
}
230
239
 
231
 
int CShuangpinSegmentor::_encode(const char* buf, char ch, bool isComplete)
 
240
int
 
241
CShuangpinSegmentor::_encode(const char* buf, char ch, bool isComplete)
232
242
{
233
243
    CMappedYin syls;
234
244
    syls.reserve(8);
245
255
        s.m_len = 2;
246
256
        s.m_start = len - s.m_len;
247
257
        s.m_syllables.clear();
248
 
        s.m_type = IPySegmentor::SYLLABLE; 
249
 
        for (; iter!=iter_end; iter++) {
 
258
        s.m_type = IPySegmentor::SYLLABLE;
 
259
        for (; iter != iter_end; iter++) {
250
260
            s.m_syllables.push_back(s_shpData.encodeSyllable(iter->c_str()));
251
261
        }
252
262
        m_nLastValidPos += 1;
261
271
            TSyllable syl = s_shpData.encodeSyllable(iter->c_str());
262
272
            if ((int)syl != 0) {
263
273
                s.m_syllables.push_back(syl);
264
 
                m_segs.push_back (s);
 
274
                m_segs.push_back(s);
265
275
            } else {
266
 
                m_segs.push_back (TSegment (ch, s.m_start, 1, IPySegmentor::STRING));
 
276
                m_segs.push_back(TSegment(ch, s.m_start, 1,
 
277
                                          IPySegmentor::STRING));
267
278
            }
268
279
        }
269
280
        return s.m_start;
270
281
    }
271
282
}
272
283
 
273
 
unsigned CShuangpinSegmentor::_push (unsigned ch)
 
284
unsigned
 
285
CShuangpinSegmentor::_push(unsigned ch)
274
286
{
275
287
    int startFrom = 0;
276
288
    bool isInputPy;
277
289
    EShuangpinType shpType;
278
290
 
279
 
    m_pystr.push_back (ch);
 
291
    m_pystr.push_back(ch);
280
292
    const int len = m_pystr.size();
281
293
    if (m_hasInvalid) {
282
294
        startFrom = len - 1;
283
 
        m_segs.push_back (TSegment (ch, startFrom, 1, IPySegmentor::INVALID));
 
295
        m_segs.push_back(TSegment(ch, startFrom, 1, IPySegmentor::INVALID));
284
296
        goto RETURN;
285
297
    }
286
298
 
287
299
    shpType = s_shpData.getShuangpinType();
288
 
    isInputPy = ( islower(ch) ||
289
 
                   (ch == ';' && (shpType == MS2003 || shpType == ZIGUANG)) );
290
 
    
291
 
    if (!isInputPy) { 
 
300
    isInputPy = (islower(ch) ||
 
301
                 (ch == ';' && (shpType == MS2003 || shpType == ZIGUANG)));
 
302
 
 
303
    if (!isInputPy) {
292
304
        startFrom = len - 1;
293
 
        
 
305
 
294
306
        IPySegmentor::ESegmentType seg_type;
295
307
        if (ch == '\'' && m_inputBuf.size() > 1)
296
308
            seg_type = IPySegmentor::SYLLABLE_SEP;
297
309
        else
298
310
            seg_type = IPySegmentor::STRING;
299
 
        m_segs.push_back (TSegment (ch, startFrom, 1, seg_type));
 
311
        m_segs.push_back(TSegment(ch, startFrom, 1, seg_type));
300
312
        m_nAlpha += 1;
301
313
        m_nLastValidPos += 1;
302
314
    } else {
303
 
        bool bCompleted = !((len - m_nAlpha)%2) && isInputPy;
 
315
        bool bCompleted = !((len - m_nAlpha) % 2) && isInputPy;
304
316
        char buf[4];
305
317
        if (bCompleted) {
306
 
            sprintf(buf, "%c%c", m_pystr[len-2], ch);
 
318
            sprintf(buf, "%c%c", m_pystr[len - 2], ch);
307
319
        } else {
308
320
            sprintf(buf, "%c", ch);
309
321
        }
311
323
        if (startFrom < 0) {
312
324
            m_hasInvalid = true;
313
325
            startFrom = m_pystr.size() - 1;
314
 
            m_segs.push_back (TSegment (ch, startFrom, 1, IPySegmentor::INVALID));
 
326
            m_segs.push_back(TSegment(ch, startFrom, 1, IPySegmentor::INVALID));
315
327
        }
316
328
    }
317
329
 
318
330
RETURN:;
319
331
 
320
332
    if (m_pGetFuzzySyllablesOp && m_pGetFuzzySyllablesOp->isEnabled())
321
 
        if ( m_segs.back().m_type == SYLLABLE)
322
 
            _addFuzzySyllables (m_segs.back ());
 
333
        if (m_segs.back().m_type == SYLLABLE)
 
334
            _addFuzzySyllables(m_segs.back());
323
335
 
324
336
    return startFrom;
325
337
}
326
338
 
327
 
void CShuangpinSegmentor::_addFuzzySyllables (TSegment& seg)
 
339
void
 
340
CShuangpinSegmentor::_addFuzzySyllables(TSegment& seg)
328
341
{
329
 
    assert (seg.m_type == SYLLABLE);
 
342
    assert(seg.m_type == SYLLABLE);
330
343
 
331
344
    seg.m_fuzzy_syllables.clear();
332
345
 
333
 
    std::vector<unsigned>::iterator it  = seg.m_syllables.begin();
 
346
    std::vector<unsigned>::iterator it = seg.m_syllables.begin();
334
347
    std::vector<unsigned>::iterator ite = seg.m_syllables.end();
335
 
    for (; it != ite; ++it)
336
 
    {
337
 
        CSyllables fuzzy_set = (*m_pGetFuzzySyllablesOp) (*it);
 
348
    for (; it != ite; ++it) {
 
349
        CSyllables fuzzy_set = (*m_pGetFuzzySyllablesOp)(*it);
338
350
 
339
 
        CSyllables::const_iterator _it  = fuzzy_set.begin ();
340
 
        CSyllables::const_iterator _ite = fuzzy_set.end ();
 
351
        CSyllables::const_iterator _it = fuzzy_set.begin();
 
352
        CSyllables::const_iterator _ite = fuzzy_set.end();
341
353
        for (; _it != _ite; ++_it)
342
 
            seg.m_fuzzy_syllables.push_back (*_it);
 
354
            seg.m_fuzzy_syllables.push_back(*_it);
343
355
    }
344
356
}
345
357