source: icGREP/icgrep-devel/icgrep/re_cc.cpp @ 4129

Last change on this file since 4129 was 4125, checked in by cameron, 5 years ago

make names canonical; avoid codepoint confusion

File size: 7.2 KB
Line 
1/*
2 *  Copyright (c) 2014 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include "re_cc.h"
8
9int CC::msCSIidx = 0;
10
11CC::CC()
12{
13    gensym_name();
14}
15
16CC::CC(int codepoint)
17{
18    gensym_name();
19    insert1(codepoint);
20}
21
22CC::CC(int lo_codepoint, int hi_codepoint)
23{
24    gensym_name();
25    insert_range(lo_codepoint, hi_codepoint);
26}
27
28CC::CC(CC *cc1, CC *cc2)
29{
30    gensym_name();
31    mSparseCharSet = cc2->getItems();
32    joinCharSets(cc1->getItems());
33}
34
35CC::~CC(){}
36
37std::vector<CharSetItem> CC::getItems()
38{
39    return mSparseCharSet;
40}
41
42std::string CC::getName()
43{
44    std::string name = "CC";
45
46    std::vector<CharSetItem>::iterator it;
47    for (it = mSparseCharSet.begin(); it != mSparseCharSet.end(); ++it)
48    {
49        name += "_" + std::to_string(it->lo_codepoint);
50        name += "." + std::to_string(it->hi_codepoint);
51    }
52
53    return name;
54}
55
56std::string CC::getId()
57{
58    return mId;
59}
60
61bool CC::is_member(int codepoint)
62{
63    return is_member_helper(codepoint, mSparseCharSet.size() - 1);
64}
65
66bool CC::is_member_helper(int codepoint, int idx)
67{
68    if (idx == -1)
69    {
70        return false;
71    }
72    else
73    {
74        CharSetItem item = mSparseCharSet.at(idx);
75
76        if (codepoint < item.lo_codepoint)
77        {
78            return false;
79        }
80        else if (codepoint > item.hi_codepoint)
81        {
82            idx--;
83            return is_member_helper(codepoint, idx);
84        }
85        else
86        {
87            return true;
88        }
89    }
90}
91
92void CC::joinCharSets(std::vector<CharSetItem> items1)
93{
94    joinCharSets_helper(items1, items1.size() - 1);
95}
96
97void CC::joinCharSets_helper(std::vector<CharSetItem> items1, int idx)
98{
99    if (idx > -1)
100    {
101        CharSetItem item = items1.at(idx);
102        insert_range(item.lo_codepoint, item.hi_codepoint);
103        idx--;
104        joinCharSets_helper(items1, idx);
105    }
106}
107
108void CC::insert1(int codepoint)
109{
110    insert_range(codepoint, codepoint);
111}
112
113void CC::insert_range(int lo_codepoint, int hi_codepoint)
114{
115    insert_range_helper(lo_codepoint, hi_codepoint, mSparseCharSet.size() - 1);
116}
117
118void CC::insert_range_helper(int lo_codepoint, int hi_codepoint, int idx)
119{
120    if (idx == -1)
121    {
122        CharSetItem new_item;
123        new_item.lo_codepoint = lo_codepoint;
124        new_item.hi_codepoint = hi_codepoint;
125        std::vector<CharSetItem>::iterator it;
126        it = mSparseCharSet.begin();
127        mSparseCharSet.insert(it, new_item);
128    }
129    else
130    {
131        CharSetItem item = mSparseCharSet.at(idx);
132
133        if (hi_codepoint < item.lo_codepoint - 1)
134        {
135            CharSetItem new_item;
136            new_item.lo_codepoint = lo_codepoint;
137            new_item.hi_codepoint = hi_codepoint;
138            std::vector<CharSetItem>::iterator it;
139            it = mSparseCharSet.begin();
140            mSparseCharSet.insert(it + idx + 1, new_item);
141        }
142        else if (lo_codepoint > item.hi_codepoint + 1)
143        {
144            idx--;
145            insert_range_helper(lo_codepoint, hi_codepoint, idx);
146        }
147        else
148        {
149            int overlap_lo = item.lo_codepoint;
150            int overlap_hi = item.hi_codepoint;
151            std::vector<CharSetItem>::iterator it;
152            it = mSparseCharSet.begin();
153            mSparseCharSet.erase(it + idx);
154            idx--;
155            insert_range_helper(std::min(overlap_lo, lo_codepoint), std::max(overlap_hi, hi_codepoint), idx);
156        }
157    }
158}
159
160void CC::negate_class()
161{
162    negate_class_helper(mSparseCharSet.size() - 1, 0);
163}
164
165void CC::negate_class_helper(int idx, int b)
166{
167    if (idx == -1)
168    {
169        if (b <= mUnicodeMax)
170        {
171            CharSetItem new_item;
172
173            new_item.lo_codepoint = b;
174            new_item.hi_codepoint = mUnicodeMax;
175            std::vector<CharSetItem>::iterator it;
176            it = mSparseCharSet.begin();
177            mSparseCharSet.insert(it, new_item);
178        }
179    }
180    else
181    {
182        CharSetItem item = mSparseCharSet.at(idx);
183
184        if (b < item.lo_codepoint)
185        {
186            CharSetItem new_item;
187
188            new_item.lo_codepoint = b;
189            new_item.hi_codepoint = item.lo_codepoint - 1;
190            std::vector<CharSetItem>::iterator it;
191            it = mSparseCharSet.begin();
192            mSparseCharSet.erase(it + idx);
193            mSparseCharSet.insert(it + idx, new_item);
194            idx--;
195            negate_class_helper(idx, item.hi_codepoint + 1);
196        }
197        else
198        {
199            std::vector<CharSetItem>::iterator it;
200            it = mSparseCharSet.begin();
201            mSparseCharSet.erase(it + idx);
202            idx--;
203            negate_class_helper(idx, item.hi_codepoint + 1);
204        }
205    }
206}
207
208void CC::remove1(int codepoint)
209{
210    remove_range(codepoint, codepoint);
211}
212
213void CC::remove_range(int lo_codepoint, int hi_codepoint)
214{
215    remove_range_helper(lo_codepoint, hi_codepoint, mSparseCharSet.size() - 1);
216}
217
218void CC::remove_range_helper(int lo_codepoint, int hi_codepoint, int idx)
219{
220    if (idx != -1)
221    {
222        CharSetItem item = mSparseCharSet.at(idx);
223
224        if (hi_codepoint < item.lo_codepoint - 1)
225        {
226            return;
227        }
228        else if (lo_codepoint > item.hi_codepoint + 1)
229        {
230            idx--;
231            remove_range_helper(lo_codepoint, hi_codepoint, idx);
232        }
233        else if ((lo_codepoint <= item.lo_codepoint) && (hi_codepoint >= item.hi_codepoint))
234        {
235            std::vector<CharSetItem>::iterator it;
236            it = mSparseCharSet.begin();
237            mSparseCharSet.erase(it + idx);
238            idx--;
239            remove_range_helper(lo_codepoint, hi_codepoint, idx);
240        }
241        else if (lo_codepoint <= item.lo_codepoint)
242        {
243            CharSetItem new_item;
244            new_item.lo_codepoint = hi_codepoint + 1;
245            new_item.hi_codepoint = item.hi_codepoint;
246            std::vector<CharSetItem>::iterator it;
247            it = mSparseCharSet.begin();
248            mSparseCharSet.erase(it + idx);
249            mSparseCharSet.insert(it + idx, new_item);
250        }
251        else if (hi_codepoint >= item.hi_codepoint)
252        {
253            CharSetItem new_item;
254            new_item.lo_codepoint = item.lo_codepoint;
255            new_item.hi_codepoint = lo_codepoint - 1;
256            std::vector<CharSetItem>::iterator it;
257            it = mSparseCharSet.begin();
258            mSparseCharSet.erase(it + idx);
259            mSparseCharSet.insert(it + idx, new_item);
260            idx--;
261            remove_range_helper(lo_codepoint, hi_codepoint, idx);
262        }
263        else
264        {
265            CharSetItem new_item1;
266            new_item1.lo_codepoint = hi_codepoint + 1;
267            new_item1.hi_codepoint = item.hi_codepoint;
268            CharSetItem new_item2;
269            new_item2.lo_codepoint = item.lo_codepoint;
270            new_item2.hi_codepoint = lo_codepoint - 1;
271            std::vector<CharSetItem>::iterator it;
272            it = mSparseCharSet.begin();
273            mSparseCharSet.erase(it + idx);
274            mSparseCharSet.insert(it + idx, new_item1);
275            mSparseCharSet.insert(it + idx, new_item2);
276        }
277    }
278}
279
280void CC::gensym_name()
281{
282    mId = "lex.CC" + std::to_string(msCSIidx);
283    msCSIidx++;
284}
285
Note: See TracBrowser for help on using the repository browser.