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

Last change on this file since 5805 was 5805, checked in by cameron, 15 months ago

Name::Type::Byte removed in favor of cc::Byte alphabet; other cleanups

File size: 6.3 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#include <UCD/PropertyObjects.h>
30
31
32using namespace std;
33using namespace re;
34using namespace llvm;
35
36
37const std::vector<std::string> split(const std::string &s, char delim) {
38    std::vector<std::string> elems;
39    std::stringstream ss;
40    ss.str(s);
41    std::string item;
42    while (std::getline(ss, item, delim)) {
43        elems.push_back(item);
44    }
45    return elems;
46}
47
48vector<string> appendRtoL(std::vector<string> LHS, std::vector<string> RHS){
49        std::copy(RHS.begin(), RHS.end(), std::back_inserter(LHS));
50        return LHS;
51}
52
53vector<string> getIntersect(vector<string> v1, vector<string> v2)
54{
55
56    vector<string> v3;
57
58    sort(v1.begin(), v1.end());
59    sort(v2.begin(), v2.end());
60
61    set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),back_inserter(v3));
62
63    return v3;
64}
65
66vector<string> getDiff(vector<string> v1, vector<string> v2)
67{
68
69    vector<string> v3;
70
71    sort(v1.begin(), v1.end());
72    sort(v2.begin(), v2.end());
73
74    set_difference(v1.begin(),v1.end(),v2.begin(),v2.end(),back_inserter(v3));
75
76    return v3;
77}
78
79std::vector<string> getAllCodepoints(){
80        std::vector<string> cpSet;
81        unsigned int max = 0x10FFFF;
82        for (unsigned cp = 0; cp < max; ++cp){
83                if (cp < 0xD800 || cp > 0xDFFF) {
84                        std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
85                std::string u8str = converter.to_bytes(cp);
86                cpSet.push_back(u8str);
87                }
88        }
89        return cpSet;
90}
91
92string StringGenerator::stringifyVec(vector<string> elements, string separator){
93        string line = "";
94        bool sep = false;
95        for (auto e : elements){
96                line += sep? separator + e : e;
97                sep = true;
98        }
99        return line;
100}
101
102bool StringGenerator::hasFlag(string flag, std::vector<string> flags){
103        return (std::find(flags.begin(), flags.end(), flag) != flags.end()) ? true : false;
104}
105
106
107string StringGenerator::generate(string re, std::vector<string> flags, re::RE_Syntax syntax){
108
109        bool caseInsensitive = hasFlag("-i", flags);
110
111        re::RE * re_ast = re::RE_Parser::parse(re, caseInsensitive, syntax);
112        string str = stringifyVec(generate(re_ast));
113        return str;
114}
115
116std::vector<std::string> StringGenerator::generate(RE * re) {
117        srand (time(NULL));
118        std::vector<string> retVec;
119    if (re == nullptr) {
120        return retVec;
121    } else if ( Alt* re_alt = dyn_cast<Alt>(re)) {
122        std::vector<string> set;
123        for ( RE * re : *re_alt){
124                set = appendRtoL(set, generate(re));
125        }
126                int random = rand() % set.size();
127                retVec.push_back(set[random]);
128               
129    } else if (CC* re_cc = dyn_cast<CC>(re)) {
130        for (auto i : *re_cc) {
131                for (auto cp = lo_codepoint(i); cp <= hi_codepoint(i); cp++){
132                        std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
133                        std::string u8str = converter.to_bytes(cp);
134                        retVec.push_back(u8str);
135                }
136        }
137    } else if (Name* re_name = dyn_cast<Name>(re)) {
138
139        switch (re_name->getType()) {
140                case Name::Type::Unicode:
141                                retVec = generate(re_name->getDefinition()); 
142                                break;
143                        case Name::Type::UnicodeProperty: {
144                if (re_name->getName() == "whitespace"){
145                    retVec.push_back(" ");
146                    break;
147                }
148                                UCD::UnicodeSet ucs = UCD::resolveUnicodeSet(re_name);
149                                for (auto i : ucs){
150                                        for (auto cp = lo_codepoint(i); cp <= hi_codepoint(i); cp++){
151                                                std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
152                                        std::string u8str = converter.to_bytes(cp);
153                                                retVec.push_back(u8str);
154                                }
155                                }
156                                break;
157                        }
158                case Name::Type::Capture: {
159                        std::vector<string> set = generate(re_name->getDefinition());
160                        int random = rand() % set.size();
161                        string str = set[random];
162                        references.push_back(str);
163                        retVec.push_back(str);
164                        break;
165                }
166                        case Name::Type::Reference:
167                        {
168                bool found = false;
169                                for (unsigned i = 0; i < references.size(); i++){
170                                        string ref = "\\" + to_string(i+1);
171                                        if (ref == re_name->getName()){
172                                                retVec.push_back(references[i]);
173                        found = true;
174                                        }
175                                }
176                if (!found){
177                    cerr << "reference not found\n";
178                }
179                                break;
180                        }
181                        default: 
182                        retVec.push_back("Bad MyEnum");
183                 }
184    } else if (Assertion * a = dyn_cast<Assertion>(re)) {
185        //Do Nothing
186    } else if (Diff* diff = dyn_cast<Diff>(re)) {
187
188        std::vector<string> set = getDiff(generate(diff->getLH()), generate(diff->getRH()));
189        retVec = appendRtoL(retVec, set);
190
191    } else if (Intersect* x = dyn_cast<Intersect>(re)) {
192
193        std::vector<string> set = getIntersect(generate(x->getLH()), generate(x->getRH()));
194        retVec = appendRtoL(retVec, set);
195
196    } else if (Rep* re_rep = dyn_cast<Rep>(re)) {
197
198        int lb = re_rep->getLB();
199        int ub = (re_rep->getUB() == Rep::UNBOUNDED_REP) ? lb + 100 : re_rep->getUB();
200        string ret = "";
201       
202        int range = (ub - lb) + 1;
203        int random = (lb == 0)? rand() % ub : rand() % range + lb;
204       
205        std::vector<string> set = generate(re_rep->getRE());
206        for (auto i =0; i<random; ++i){
207                srand (time(NULL));
208                int random2 = rand() % set.size();
209                ret += set[random2];
210        }
211        retVec.push_back(ret);
212
213    } else if (Seq* re_seq = dyn_cast<Seq>(re)) {
214
215        for (RE * re : *re_seq) {
216            std::vector<string> set = generate(re);
217           
218            if (!set.empty()){
219                    int random = rand() % set.size();
220                    retVec.push_back(set[random]);
221                }
222        }
223    } else if (isa<Start>(re) || isa<End>(re)) {
224                retVec.push_back("");
225    } else if (isa<Any>(re)) {
226        retVec = getAllCodepoints();
227    } else {
228        cerr << "RE type not recognised\n";
229    }
230    return retVec;
231}
Note: See TracBrowser for help on using the repository browser.