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

Last change on this file since 5516 was 5516, checked in by faldebey, 21 months ago

added combinatorial testing tool

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