source: icGREP/icgrep-0.8/icgrep/utf8_encoder.cpp @ 3972

Last change on this file since 3972 was 3854, checked in by cameron, 5 years ago

Use CodeGenOpt::Default + createPromoteMemoryToRegisterPass

File size: 5.3 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 "utf8_encoder.h"
8
9UTF8_Encoder::UTF8_Encoder(){}
10
11RE* UTF8_Encoder::toUTF8(RE *re)
12{
13    RE* retVal = 0;
14
15    if (Alt* re_alt = dynamic_cast<Alt*>(re))
16    {
17        std::list<RE*> re_list;
18        std::list<RE*>::iterator it;
19
20        for (it = re_alt->GetREList()->begin(); it != re_alt->GetREList()->end(); ++it)
21        {
22            re_list.push_front(toUTF8(*it));
23        }
24
25        retVal = new Alt(&re_list);
26    }
27    else if (Seq* re_seq = dynamic_cast<Seq*>(re))
28    {
29        std::list<RE*> re_list;
30        std::list<RE*>::iterator it;
31
32        for (it = re_seq->GetREList()->begin(); it != re_seq->GetREList()->end(); ++it)
33        {
34            re_list.push_front(toUTF8(*it));
35        }
36
37        retVal = new Seq(&re_list);
38    }
39    else if (Rep* re_rep = dynamic_cast<Rep*>(re))
40    {
41        RepLimit* replimit;
42        if (UpperBound* unbounded = dynamic_cast<UpperBound*>(re_rep->getUB()))
43        {
44            replimit = new UpperBound(unbounded->getUB());
45        }
46        else
47        {
48            replimit = new Unbounded();
49        }
50
51        retVal = new Rep(toUTF8(re_rep->getRE()), re_rep->getLB(), replimit);
52    }
53    else if (CC* re_cc = dynamic_cast<CC*>(re))
54    { 
55        if (re_cc->getItems().size() == 1)
56        {
57            retVal = rangeToUTF8(re_cc->getItems().front());
58        }
59        else if (re_cc->getItems().size() > 1)
60        {           
61            std::list<RE*> re_list;
62            for (int i = 0; i < re_cc->getItems().size(); i++)
63            {
64                re_list.push_back(rangeToUTF8(re_cc->getItems().at(i)));
65            }
66            retVal = new Alt(&re_list);
67        }
68    }
69    else if (Start* re_start = dynamic_cast<Start*>(re))
70    {
71        retVal = new Start();
72    }
73    else if (End* re_end = dynamic_cast<End*>(re))
74    {
75        retVal = new End();
76    }
77
78    return retVal;
79}
80
81RE* UTF8_Encoder::rangeToUTF8(CharSetItem item)
82{
83    int u8len_lo = u8len(item.lo_codepoint);
84    int u8len_hi = u8len(item.hi_codepoint);
85
86    if (u8len_lo < u8len_hi)
87    {
88        int m = max_of_u8len(u8len_lo);
89        Alt* alt = new Alt();
90
91        CharSetItem lo_item;
92        lo_item.lo_codepoint = item.lo_codepoint;
93        lo_item.hi_codepoint = m;
94        alt->AddREListItem(rangeToUTF8(lo_item));
95        CharSetItem hi_item;
96        hi_item.lo_codepoint = m + 1;
97        hi_item.hi_codepoint = item.hi_codepoint;
98        alt->AddREListItem(rangeToUTF8(hi_item));
99
100        return alt;
101    }
102    else
103    {
104        return rangeToUTF8_helper(item.lo_codepoint, item.hi_codepoint, 1, u8len_hi);
105    }
106}
107
108RE* UTF8_Encoder::rangeToUTF8_helper(int lo, int hi, int n, int hlen)
109{
110    int hbyte = u8byte(hi, n);
111    int lbyte = u8byte(lo, n);
112
113    if (n == hlen)
114    {
115        return makeByteRange(lbyte, hbyte);
116    }
117    else if (hbyte == lbyte)
118    {
119        Seq* seq = new Seq();
120        seq->AddREListItem(makeByteClass(hbyte));
121        seq->AddREListItem(rangeToUTF8_helper(lo, hi, n+1, hlen));
122        return seq;
123    }
124    else
125    {
126        int suffix_mask = (1 << ((hlen - n) * 6)) - 1;
127
128        if ((hi & suffix_mask) != suffix_mask)
129        {
130            int hi_floor = (~suffix_mask) & hi;
131
132            Alt* alt = new Alt();
133            alt->AddREListItem(rangeToUTF8_helper(hi_floor, hi, n, hlen));
134            alt->AddREListItem(rangeToUTF8_helper(lo, hi_floor - 1, n, hlen));
135            return alt;
136        }
137        else if ((lo & suffix_mask) != 0)
138        {
139            int low_ceil = lo | suffix_mask;
140
141            Alt* alt = new Alt();
142            alt->AddREListItem(rangeToUTF8_helper(low_ceil + 1, hi, n, hlen));
143            alt->AddREListItem(rangeToUTF8_helper(lo, low_ceil, n, hlen));
144            return alt;
145        }
146        else
147        {
148            Seq* seq = new Seq();
149            seq->AddREListItem(makeByteRange(lbyte, hbyte));
150            seq->AddREListItem(rangeToUTF8_helper(lo, hi, n + 1, hlen));
151            return seq;
152        }
153    }
154}
155
156CC* UTF8_Encoder::makeByteRange(int lo, int hi)
157{
158    return new CC(lo, hi);
159}
160
161CC* UTF8_Encoder::makeByteClass(int byteval)
162{
163    return new CC(byteval, byteval);
164}
165
166int UTF8_Encoder::u8byte(int codepoint, int n)
167{
168    int retVal = 0;
169
170    int len = u8len(codepoint);
171
172    if (n == 1)
173    {
174        if (len == 1)
175        {
176            retVal = codepoint;
177        }
178        else if (len == 2)
179        {
180            retVal = 0xC0 | (codepoint >> 6);
181        }
182        else if (len == 3)
183        {
184            retVal = 0xE0 | (codepoint >> 12);
185        }
186        else
187        {
188            retVal = 0xF0 | (codepoint >> 18);
189        }
190    }
191    else
192    {
193        retVal = 0x80 | ((codepoint >> (6 * (len - n))) & 0x3F);
194    }
195
196    return retVal;
197}
198
199int UTF8_Encoder::u8len(int cp)
200{
201    if (cp <= 0x7F)
202    {
203        return 1;
204    }
205    else if (cp <= 0x7FF)
206    {
207        return 2;
208    }
209    else if (cp <= 0xFFFF)
210    {
211        return 3;
212    }
213    else
214    {
215        return 4;
216    }
217}
218
219int UTF8_Encoder::max_of_u8len(int lgth)
220{
221    if (lgth == 1)
222    {
223        return 0x7F;
224    }
225    else if (lgth == 2)
226    {
227        return 0x7FF;
228    }
229    else if (lgth == 3)
230    {
231        return 0xFFFF;
232    }
233    else if (lgth == 4)
234    {
235        return 0x10FFFF;
236    }
237    else
238    {
239        return -1;
240    }
241}
242
Note: See TracBrowser for help on using the repository browser.