source: icGREP/icgrep-devel/icgrep/combine/stringGen.cpp @ 5825

Last change on this file since 5825 was 5825, checked in by faldebey, 13 months ago

Update to CoRE testing system

File size: 7.2 KB
Line 
1#include "stringGen.h"
2
3#include <re/re_re.h>
4#include <re/re_alt.h>
5#include <re/re_any.h>
6#include <re/re_cc.h>
7#include <re/re_name.h>
8#include <re/re_end.h>
9#include <re/re_rep.h>
10#include <re/re_seq.h>
11#include <re/re_start.h>
12#include <re/re_diff.h>
13#include <re/re_intersect.h>
14#include <re/re_assertion.h>
15#include <re/re_name_resolve.h>
16#include <boost/algorithm/string/predicate.hpp>
17#include <boost/lexical_cast.hpp>
18#include <sstream>
19#include <algorithm>
20#include <iostream>
21#include <re/re_parser.h>
22#include <functional>
23#include <locale>
24#include <codecvt>
25#include <stdlib.h>
26#include <time.h>
27#include <UCD/resolve_properties.h>
28#include <UCD/unicode_set.h>
29
30#include <re/printer_re.h>
31using namespace std;
32using namespace re;
33using namespace llvm;
34
35
36CC * StringGenerator::getRandomCodepointCC(CC * cc){
37    assert (cc);
38    if (!cc->subset(*getAllCodepoints())) {
39        cc = intersectCC(cc, getAllCodepoints());
40    }
41    if (cc->empty()) {
42        return cc;
43    }
44    int random = rand() % cc->count();
45    return makeCC(cc->at(random));
46
47}
48
49inline CC * StringGenerator::getAllCodepoints() {
50    assert (allCodepointsCC);
51    return allCodepointsCC;
52}
53
54string stringifyCC(CC * cc){
55    if (cc->empty()){
56        return "";
57    }
58    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
59    std::string u8str = converter.to_bytes(lo_codepoint(cc->begin()));
60    return u8str;
61}
62
63string StringGenerator::stringifyVec(vector<CC *> elements) {
64        string line = "";
65        for (auto e : elements) {
66        if (!e->empty()){
67            line += stringifyCC(getRandomCodepointCC(e));
68        }
69        }
70        return line;
71}
72
73
74string StringGenerator::generate() {
75    if (mSyntax == re::RE_Syntax::FixedStrings) {
76      return mRegex;
77    }
78    else {
79      string result;
80      bool caseInsensitive = std::find(mFlags.begin(), mFlags.end(), "-i") != mFlags.end();
81      if (re::RE * re_ast = re::RE_Parser::parse(mRegex, caseInsensitive, mSyntax)){
82         result = stringifyVec(generate(re_ast));
83      }
84      return result;
85    }
86}
87
88std::vector<CC *> StringGenerator::generate(RE * re, bool Complement, bool getOne) {
89    // cout << Printer_RE::PrintRE(re) << endl;
90        std::vector<CC*> retVec = {};
91    if (re == nullptr) {
92        return retVec;
93
94    } else if (isa<Any>(re)) {
95        if (getOne){
96            retVec.push_back(getRandomCodepointCC(getAllCodepoints()));
97        }
98        else{
99            retVec.push_back(getAllCodepoints());
100        }
101
102    } else if ( Alt* re_alt = dyn_cast<Alt>(re)) {
103        int random = rand() % re_alt->size();
104        retVec = generate((*re_alt)[random]);
105    } else if (CC* re_cc = dyn_cast<CC>(re)) {
106        if (!re_cc->empty()){
107            retVec.push_back(subtractCC(re_cc, forbiddenCC));
108        }
109    } else if (Name* re_name = dyn_cast<Name>(re)) {
110
111        switch (re_name->getType()) {
112        case Name::Type::Byte:
113                case Name::Type::Unicode:
114                                retVec = generate(re_name->getDefinition());
115                                break;
116                        case Name::Type::UnicodeProperty: {
117                if ((re_name->getName() == "whitespace") && !Complement) {
118                    retVec.push_back(makeCC(0x0020));
119                    break;
120                }
121                UCD::UnicodeSet ucs = UCD::resolveUnicodeSet(re_name);
122
123                if (!ucs.empty()) {
124                    CC * propertyCC = makeCC(std::move(ucs));
125                    if (propertyCC->intersects(*forbiddenCC)) {
126                        propertyCC = subtractCC(propertyCC, forbiddenCC);
127                    }
128                    retVec.push_back(propertyCC);
129                                }
130                                break;
131                        }
132                case Name::Type::Capture: {
133                        std::vector<CC *> set = generate(re_name->getDefinition());
134                std::vector<CC *> ref;
135                        if (!set.empty()){
136                    for (auto s : set) {
137                        if (!s->empty()){
138                            CC * randomCC = getRandomCodepointCC(s);
139                            retVec.push_back(randomCC);
140                            ref.push_back(randomCC);
141                        }
142                    }
143                }
144
145                mReferences.push_back(ref);
146                        break;
147                }
148                        case Name::Type::Reference:
149                        {
150                                for (unsigned i = 0; i < mReferences.size(); i++){
151                                        string ref = "\\" + to_string(i+1);
152                                        if (ref == re_name->getName()){
153                                                retVec = mReferences[i];
154                        break;
155                                        }
156                                }
157                                break;
158                        }
159                        default:
160                        cerr << "Bad name type" << endl;
161                }
162    } else if (isa<Assertion>(re)) {
163        //Do Nothing
164    } else if (Diff* diff = dyn_cast<Diff>(re)) {
165        CC * LHS = makeCC();
166        CC * RHS = makeCC();
167        for (auto cc : generate(diff->getLH())) {
168            LHS = makeCC(LHS, cc);
169        }
170        LHS = subtractCC(LHS, forbiddenCC);
171        for (auto cc : generate(diff->getRH(), true, false)) {
172            RHS = makeCC(RHS, cc);
173        }
174        retVec.push_back(subtractCC(LHS, RHS));
175    } else if (Intersect* x = dyn_cast<Intersect>(re)) {
176
177        CC * LHS = makeCC();
178        CC * RHS = makeCC();
179        for (auto cc : generate(x->getLH(), true, false)) {
180            LHS = makeCC(LHS, cc);
181        }
182        for (auto cc : generate(x->getRH(), true, false)) {
183            RHS = makeCC(RHS, cc);
184        }
185        retVec.push_back(intersectCC(LHS, RHS));
186
187    } else if (Rep* re_rep = dyn_cast<Rep>(re)) {
188
189        std::vector<CC *> set = generate(re_rep->getRE());
190        if (!set.empty()){
191                int lb = re_rep->getLB();
192            int ub = (re_rep->getUB() == Rep::UNBOUNDED_REP) ? lb + 1000 : re_rep->getUB();
193
194            int boundRange = (lb == 0)? (ub+1) : (ub - lb + 1);
195                int random = rand() % boundRange + lb;
196                // cout << "random bound = " << to_string(random) << endl;
197            for (auto i =0; i < random; ++i){
198                for (auto *s : set) {
199                    retVec.push_back(s);
200                }
201            }
202        }
203
204    } else if (Seq* re_seq = dyn_cast<Seq>(re)) {
205
206        for (RE * re : *re_seq) {
207            std::vector<CC *> set = generate(re);
208
209            if (!set.empty()) {
210                for (auto s : set) {
211                    retVec.push_back(getRandomCodepointCC(s));
212                }
213                }
214        }
215    } else if (isa<Start>(re) || isa<End>(re)) {
216                retVec.push_back(makeCC());
217    } else {
218        cerr << "RE type not recognised\n";
219    }
220    // if (!retVec.empty())
221    //     cout << retVec.back() << endl;
222    // if (!returnCC->empty()) {
223    //     cout << "returnCC = " << Printer_RE::PrintRE(returnCC) << endl;
224    // }
225    return retVec;
226}
227
228
229
230StringGenerator::StringGenerator(std::string re, std::vector<std::string> flags, re::RE_Syntax syntax)
231: mRegex(re)
232, mFlags(flags)
233, mSyntax(syntax)
234, asciiCC(re::makeCC(0, 0x007E))
235, unicodeCC(re::makeCC(0, 0xEFFFF))
236, forbiddenCC(re::makeCC({{0x0000, 0x0008}, {0x000A, 0x001F},
237                          {0x007F, 0x007F}, {0x0085, 0x0085},
238                          {0x2028, 0x2029}, {0x2424, 0x2424},
239                          {0x2B89, 0x2B92}, {0x4DD7, 0x4DD7},
240                          {0xD800, 0xDFFF}, {0xE01F0, 0xEFFFF}}))
241, allCodepointsCC(subtractCC((syntax == re::RE_Syntax::PCRE) ? unicodeCC : asciiCC, forbiddenCC))
242{
243
244}
245
246StringGenerator::~StringGenerator() {
247    re::RE::Reset();
248    // UCD::UnicodeSet::Reset();
249}
Note: See TracBrowser for help on using the repository browser.