source: icGREP/icgrep-devel/icgrep/combine/regexGen.cpp @ 5533

Last change on this file since 5533 was 5533, checked in by faldebey, 2 years ago

more bug fixes and cleanup for testing tool

File size: 14.7 KB
Line 
1#include "regexGen.h"
2#include "stringGen.h"
3
4#include <string>
5#include <vector>
6#include <fstream>
7#include <boost/algorithm/string/split.hpp>
8#include <iostream>
9#include <algorithm>
10
11#include <stdlib.h>
12#include <time.h> 
13#include <stdio.h>
14#include <re/re_diff.h>
15#include <re/re_any.h> 
16#include <re/re_parser.h>
17
18
19using namespace std;
20
21class CC {
22        std::vector<string> ccList;
23        std::vector<string> usedCC;
24public:
25        CC(std::vector<string> header, std::vector<string> row, re::RE_Syntax syntax){
26                RegexGen reGen(syntax);
27                ccList = reGen.parseCC(header, row);
28
29        }
30
31        std::string getCC(){
32
33                int random;
34                std::string cc;
35                if (!ccList.empty()){
36                        random = rand() % ccList.size();
37                        cc = ccList[random];
38                        ccList.erase(ccList.begin()+random);
39                        usedCC.push_back(cc);
40                        return cc;
41                }
42                else {
43                        random = rand() % usedCC.size();
44                        cc = usedCC[random];
45                        return cc;
46                }
47        }
48        std::string changeCC(std::string cc){
49                std::string newCC;
50                int random;
51                if (!ccList.empty()){
52                        random = rand() % ccList.size();
53                        newCC = ccList[random];
54                        ccList.erase(ccList.begin()+random);
55                        usedCC.push_back(newCC);
56                }
57                else {
58                        random = rand() % usedCC.size();
59                        newCC = usedCC[random];
60                }
61                ccList.push_back(cc);
62                return newCC;
63        }
64        std::vector<string> getRemainingCC(){
65                return ccList;
66        }
67        bool isEmpty(){
68                return ccList.empty();
69        }
70};
71
72RegexGen::RegexGen(std::vector<string> header, std::vector<string> row){
73        syntax = setSyntax(header, row);
74        RE = parseRE(header, row);
75        flags = parseFlags(header, row);
76}
77
78string RegexGen::stringifyLine(vector<string> elements, string separator){
79        string line = "";
80        bool sep = false;
81        for (auto e : elements){
82                line += sep? separator + e : e;
83                sep = true;
84        }
85        return line;
86}
87
88string RegexGen::getBoundary(){
89        return "\\b";
90}
91string RegexGen::getNotBoundary(){
92        return "\\B";
93}
94string RegexGen::getWord(){
95        if (syntax == re::RE_Syntax::BRE){
96                return "w";
97        }
98        else return "\\w";
99}
100string RegexGen::getNotWord(){
101        if (syntax == re::RE_Syntax::BRE){
102                return "notWord";
103        }
104        else return "\\W";
105}
106string RegexGen::getWhitespace(){
107        return "\\s";
108}
109string RegexGen::getNotWhitespace(){
110        return "\\S";
111}
112string RegexGen::getTab(){
113        if (syntax == re::RE_Syntax::BRE){
114                return "t";
115        }
116        else return "\\t";
117}
118string RegexGen::getDigit(){
119        if (syntax == re::RE_Syntax::BRE){
120                return "d";
121        }
122        else return "\\d";
123}
124string RegexGen::getNotDigit(){
125        if (syntax == re::RE_Syntax::BRE){
126                return "D";
127        }
128        else return "\\D";
129}
130string RegexGen::getAny(){
131        return ".";
132}
133string RegexGen::getPosix(string value){
134        return "[[:" + value + ":]]";
135}
136std::string RegexGen::getUnicode(){
137        if (syntax == re::RE_Syntax::ERE) {
138                std::vector<string> ucd;
139                ifstream file;
140                file.open("../icgrep/combine/Unicode.txt");
141                string line;
142                while(getline(file, line)){
143                        ucd.push_back(line);
144                }
145                file.close();
146                int random = rand() % ucd.size();
147                return "\\u" + ucd[random];
148        }
149        else {
150                return "u";
151        }
152}
153std::string RegexGen::getList(){
154        if (syntax == re::RE_Syntax::BRE) {
155                return "l";
156        }
157        else {
158                const char *l[] = {"[abc]","[XYZ]","[123]","[àŠ¹à§àŠ¯àŠŸàŠ²à§‹]"};
159                std::vector<string> lists (l, l + sizeof(l) / sizeof(l[0]));
160                int random = rand() % lists.size();
161                return lists[random];
162        }
163       
164}
165std::string RegexGen::getNList(){
166        if (syntax == re::RE_Syntax::BRE) {
167                return "L";
168        }
169        else {
170                std::vector<string> lists = {"[^abc]","[^XYZ]","[^123]","[^àŠ¹à§àŠ¯àŠŸàŠ²à§‹]"};
171                int random = rand() % lists.size();
172                return lists[random];
173        }
174}
175std::string RegexGen::getRange(){
176        if (syntax == re::RE_Syntax::BRE) {
177                return "r";
178        }
179        else {
180                std::vector<string> lists = {"[a-zA-Z0-9]","[A-Za-z]","[0-9]","[ا-ي]"};
181                int random = rand() % lists.size();
182                return lists[random];
183        }
184}
185std::string RegexGen::getPropertyValue(){
186        std::vector<string> property = {"Common", "Latin", "Greek", "Cyrillic",
187                                                        "Armenian", "Hebrew", "Arabic", "Syriac", 
188                                                        "Thaana", "Devanagari", "Bengali", "Gurmukhi", 
189                                                        "Gujarati", "Oriya", "Tamil", "Telugu", "Kannada"};
190        int random = rand() % property.size();
191        return property[random];
192}
193std::string RegexGen::getProperty(){
194        if (syntax == re::RE_Syntax::BRE) {
195                return "p";
196        }
197        else {
198                return "\\p{" + getPropertyValue() + "}" ;
199        }
200}
201std::string RegexGen::getNotProperty(){
202        if (syntax == re::RE_Syntax::BRE) {
203                return "P";
204        }
205        else {
206                return "\\P{" + getPropertyValue() + "}" ;
207        }
208}
209std::string RegexGen::getName(){
210        if (syntax == re::RE_Syntax::ERE) {
211                return "\\N{" + getPropertyValue() + "}" ;
212        }
213        else {
214                return "N";
215        }
216}
217string RegexGen::getZeroOrOne(string cc){
218        if (syntax == re::RE_Syntax::BRE) {
219                return cc+ "\\?";
220        }
221        else {
222                return cc + "?" ;
223        }
224}
225string RegexGen::getZeroOrMore(string cc){
226                return cc + "*" ;
227}
228string RegexGen::getOneOrMore(string cc){
229        if (syntax == re::RE_Syntax::BRE) {
230                return cc+ "\\+";
231        }
232        else {
233                return cc + "+" ;
234        }
235}
236string RegexGen::getRep(string cc, int rep){
237        if (syntax == re::RE_Syntax::BRE) {
238                return cc + "\\{" + to_string(rep) + "\\}";
239        }
240        else {
241                return cc + "{" + to_string(rep) + "}";
242        }
243}
244string RegexGen::getRep(string cc, int lb, int ub){
245        if (syntax == re::RE_Syntax::BRE) {
246                return cc + "\\{" + to_string(lb) + ',' + to_string(ub) + "\\}";
247        }
248        else {
249                return cc + "{" + to_string(lb) + ',' + to_string(ub) + "}";
250        }
251}
252string RegexGen::getRepMore(string cc, int rep){
253        if (syntax == re::RE_Syntax::BRE) {
254                return cc + "\\{" + to_string(rep) + ",\\}";
255        }
256        else {
257                return cc + "{" + to_string(rep) + ",}";
258        }
259}
260string RegexGen::getJoin(string LS, string RS){
261        if (syntax == re::RE_Syntax::BRE) {
262                return "\\(" + LS + "\\|" + RS + "\\)";
263        }
264        else {
265                return "(" + LS + "|" + RS + ")";
266        }
267}
268string RegexGen::getBackRef(string cc){
269        if (syntax == re::RE_Syntax::BRE) {
270                return "\\(" + cc + "\\)";
271        }
272        else {
273                return "(" + cc + ")";
274        }
275       
276}
277string RegexGen::getAssertionCoating(string cc){
278        if (cc.find("\\p{") == 0
279                || cc.find("\\P{") == 0
280                || cc.find("\\N{") == 0){
281                re::RE * re_ast = re::RE_Parser::parse(cc, 0);
282                StringGenerator strGen;
283                std::vector<string> set = strGen.generate(re_ast);
284                int random = rand() % set.size();
285                return set[random];
286        }
287        else {
288                return cc;
289        }
290}
291
292string RegexGen::getNegativeAssertionCoating(string cc){
293        re::RE * re_ast = re::RE_Parser::parse(cc, 0);
294        StringGenerator strGen;
295        std::vector<string> set = strGen.generate(re::makeDiff(re::makeAny(),re_ast));
296        int random = rand() % set.size();
297        return set[random];
298}
299string RegexGen::getLookAhead(string cc){
300        if (syntax == re::RE_Syntax::PCRE) {
301                std::string tail = getAssertionCoating(cc);
302                return "(?=" + cc + ")" + tail;
303        }
304        return "";
305}
306string RegexGen::getNegativeLookAhead(string cc){
307        if (syntax == re::RE_Syntax::PCRE) {
308                std::string tail = getNegativeAssertionCoating(cc);
309                return "(?!" + cc + ")" + tail;
310        }
311        return "";
312}
313string RegexGen::getLookBehind(string cc){
314        if (syntax == re::RE_Syntax::PCRE) {
315                std::string front = getAssertionCoating(cc);
316                return front + "(?<=" + cc + ")";
317        }
318        return "";
319}
320string RegexGen::getNegativeLookBehind(string cc){
321        if (syntax == re::RE_Syntax::PCRE) {
322                std::string front = getNegativeAssertionCoating(cc);
323                return front + "(?<!" + cc + ")";
324        }
325        return "";
326}
327
328
329bool RegexGen::usesCC(std::string op){
330        std::vector<string> set = {"zeroOrOne","zeroOrMore","oneOrMore","repeat_n","repeat_nm","repeat_n_more","repeat_m_less", 
331                                                        "backref", "join", "look_ahead", "mlook_ahead", "look_behind", "nlook_behind" "look_ahead", 
332                                                        "mlook_ahead", "look_behind", "nlook_behind"};
333
334        if(std::find(set.begin(), set.end(), op) != set.end()){
335                return true;
336        }
337        else return false;
338}
339
340re::RE_Syntax RegexGen::setSyntax(std::vector<string> header, std::vector<string> row){
341        int colnum = 0;
342        for(auto col : row){
343                if (header[colnum] == "syntax") {
344                        if (col == "-G"){
345                                return re::RE_Syntax::BRE;
346                        }
347                        else if (col == "-E"){
348                                return re::RE_Syntax::ERE;
349                        }
350                }
351                colnum++;
352        }
353        return re::RE_Syntax::PCRE;
354}
355
356
357
358std::vector<string> RegexGen::parseCC(std::vector<string> header, std::vector<string> row){
359        std::vector<string> ccList;
360
361        int colnum = 0;
362        for(auto col : row){
363                if (col != "false"){
364                        string cc;
365
366                        if (header[colnum] == "wordC") {
367                                cc = getWord();
368                                ccList.push_back(getWord());
369                        }
370                        else if (header[colnum] == "notWordC") {
371                                cc = getNotWord();
372                                ccList.push_back(getNotWord());
373                        }
374                        else if (header[colnum] == "whitespace") {
375                                cc = getWhitespace();
376                                ccList.push_back(getWhitespace());
377                        }
378                        else if (header[colnum] == "notWhitespace") {
379                                cc = getNotWhitespace();
380                                ccList.push_back(getNotWhitespace());
381                        }
382                        else if (header[colnum] == "tab") {
383                                cc = getTab();
384                                ccList.push_back(getTab());
385                        }
386                        else if (header[colnum] == "digit") {
387                                cc = getDigit();
388                                ccList.push_back(getDigit());
389                        }
390                        else if (header[colnum] == "notDigit") {
391                                cc = getNotDigit();
392                                ccList.push_back(getNotDigit());
393                        }
394                        else if (header[colnum] == "any") {
395                                cc = getWord();
396                                ccList.push_back(getAny());
397                        }
398                        else if (header[colnum] == "unicodeC"){
399                                cc = getUnicode();
400                                ccList.push_back(getUnicode());
401                        }
402                        else if (header[colnum] == "list"){
403                                cc = getList();
404                                ccList.push_back(getList());
405                        }
406                        else if (header[colnum] == "nList"){
407                                cc = getNList();
408                                ccList.push_back(getNList());
409                        }
410                        else if (header[colnum] == "range"){
411                                cc = getRange();
412                                ccList.push_back(getRange());
413                        }
414                        else if (header[colnum] == "posix"){
415                                // if (col != "off"){
416                                //      c = getPosix(col);
417                                //      if (!c.empty())
418                                //      ccList.push_back(getPosix(col));
419                                // }
420                        }
421                        else if (header[colnum] == "property") {
422                                cc = getProperty();
423                                ccList.push_back(getProperty());
424                        }
425                        else if (header[colnum] == "notProperty") {
426                                cc = getProperty();
427                                ccList.push_back(getNotProperty());
428                        }
429                        else if (header[colnum] == "nameProperty") {
430                                cc = getName();
431                                ccList.push_back(getName());
432                        }
433                }
434                ++colnum;
435        }
436        return ccList;
437}
438
439std::string RegexGen::parseRE(std::vector<string> header, std::vector<string> row){
440        srand (time(NULL));
441        std::vector<string> fullRE;
442        std::vector<string> assertions;
443        CC ccHandler(header,row, syntax);
444        int random;
445        bool bref = false;
446        string first = "";
447        string last = "";
448        int colnum = 0;
449        std::string re;
450        for (auto col : row){
451                if (col != "false" && !ccHandler.isEmpty()){
452                       
453                        string cc;
454                        if (usesCC(header[colnum])){
455
456                                cc = ccHandler.getCC();
457                                if (header[colnum] == "zeroOrOne"  ){
458                                        re = getZeroOrOne(cc);
459                                        if (!re.empty())
460                                        fullRE.push_back(re);
461                                }
462                                else if (header[colnum] == "zeroOrMore"){
463                                        re = getZeroOrMore(cc);
464                                        if (!re.empty())
465                                        fullRE.push_back(re);
466                                } 
467                                else if (header[colnum] == "oneOrMore"){
468                                        re = getOneOrMore(cc);
469                                        // std::string nestDepth = row[colnum+1];
470                                        // int depth = std::stoi(nestDepth);
471                                        // while(depth>0){
472                                        //      std::string cc2;
473                                        //      cc2 = ccHandler.getCC();
474                                        //      re = '(' + re + cc2 + ')' + header[colnum];
475                                        //      --depth;
476                                        // }
477                                        if (!re.empty())
478                                        fullRE.push_back(re);
479                                }
480                                else if (header[colnum] == "repeat_n"){
481                                        random = rand() % 200 + 1;
482                                        re = getRep(cc, random);
483                                        // std::string nestDepth = row[colnum+1];
484                                        // int depth = std::stoi(nestDepth);
485                                        // while(depth>0){
486                                        //      std::string cc2;
487                                        //      cc2 = ccHandler.getCC();
488                                        //      random = rand() % 200;
489                                        //      re = '(?:' + re + cc2 + ')' + '{' + to_string(random) + '}';
490                                        //      --depth;
491                                        // }
492                                        if (!re.empty())
493                                        fullRE.push_back(re);
494                                }
495                                else if (header[colnum] == "repeat_nm" ){
496                                        int r1 = rand() % 200;
497                                        int r2 = rand() % 200;
498                                        while ((r1 == 0) && (r2 == 0)){
499                                                r2 = rand() % 200;
500                                        }
501                                        if (r1 > r2) {
502                                                std::swap(r1, r2);
503                                        }
504                                        re = getRep(cc, r1, r2);
505                                        // std::string nestDepth = row[colnum+1];
506                                        // int depth = std::stoi(nestDepth);
507                                        // while(depth>0){
508                                        //      std::string cc2 = ccHandler.getCC();
509                                        //      std::vector<int> randoms;
510                                        //      randoms.push_back(rand() % 200);
511                                        //      randoms.push_back(rand() % 200);
512                                        //      sort(randoms.begin(), randoms.end());
513                                        //      re = '(?:' + re + cc2 + ')' + '{' + to_string(randoms[0]) + ',' + to_string(randoms[1]) + '}';
514                                        //      --depth;
515                                        // }
516                                        if (!re.empty())
517                                        fullRE.push_back(re);
518                                }
519                                else if (header[colnum] == "repeat_n_more" ){
520                                        random = rand() % 200;
521                                        re = getRepMore(cc, random);
522                                        if (!re.empty())
523                                        fullRE.push_back(re);
524                                }
525                                else if (header[colnum] == "backref"){
526                                        bref = true;
527                                }
528                                else if (header[colnum] == "join" ){
529                                        std::string cc2 = ccHandler.getCC();
530                                        re = getJoin(cc, cc2);
531                                        if (!re.empty())
532                                        fullRE.push_back(re);
533                                }
534                                else if (header[colnum] == "look_ahead"){
535                                        re = getLookAhead(cc);
536                                        if (!re.empty())
537                                        assertions.push_back(re);
538                                }
539                                else if (header[colnum] == "nlook_ahead"){
540                                        if (cc == ".") {
541                                                continue;
542                                        }
543                                        else {
544                                                re = getNegativeLookAhead(cc);
545                                                if (!re.empty())
546                                                assertions.push_back(re);
547                                        }
548                                }
549                                else if (header[colnum] == "look_behind"){
550                                        re = getLookBehind(cc);
551                                        if (!re.empty())
552                                        assertions.push_back(re);
553                                }
554                                else if (header[colnum] == "nlook_behind"){
555                                        if (cc == ".") {
556                                                continue;
557                                        }
558                                        else {
559                                                re = getNegativeLookBehind(cc);
560                                                if (!re.empty())
561                                                assertions.push_back(re);
562                                        }
563                                }
564                        }
565                        else {
566
567                                // if (header[colnum] == "boundary") {
568                                //      re = getBoundary();
569                                //      if (!re.empty())
570                                //      assertions.push_back(re +"\\s");
571                                // }
572                                // else if (header[colnum] == "notBoundary") {
573                                //      std::string front = getAssertionCoating("[^\\s\\t\\n]");
574                                //      re = getNotBoundary();
575                                //      if (!re.empty())
576                                //      assertions.push_back(re + front);
577                                // }
578                                if (header[colnum] == "start"){
579                                                first = "^";
580                                }
581                                else if (header[colnum] == "end"){
582                                                last = "$";
583                                }
584                        }
585
586                }
587                colnum++;
588        }
589
590        vector<string> ccList = ccHandler.getRemainingCC();
591        while(!ccList.empty()){
592                fullRE.push_back(ccList.back());
593                ccList.pop_back();
594        }
595        if(!fullRE.empty()){
596
597                if (bref){
598                        random = rand() % fullRE.size();
599                        fullRE[random] = getBackRef(fullRE[random]);
600                        std::copy (assertions.begin(), assertions.end(), std::back_inserter(fullRE));
601                        std::random_shuffle(fullRE.begin(), fullRE.end());
602                        fullRE.push_back("\\1");
603                }
604                else {
605                        std::copy (assertions.begin(), assertions.end(), std::back_inserter(fullRE)); //to avoid nesting assertions.
606                        std::random_shuffle(fullRE.begin(), fullRE.end());
607                }
608                string sre= first + stringifyLine(fullRE) + last;
609                return sre;
610        }
611        else {
612                return "";
613        }
614}
615
616std::vector<string> RegexGen::parseFlags(std::vector<string> header, std::vector<string> row){
617        std::vector<string> flags;
618        int colnum = 0;
619        for (auto col : row){
620                if (col != "false"){
621                        if (header[colnum] == "-c"
622                                || header[colnum] == "-i"
623                                // || header[colnum] == "-w"
624                                // || header[colnum] == "-x"
625                                || header[colnum] == "-e"
626                                || header[colnum] == "-f"){
627                                flags.push_back(header[colnum]);
628                        }
629                        else if (header[colnum] == "syntax"){
630                                flags.push_back(col);
631                        }
632                }
633                colnum++;
634        }
635        return flags;
636}
637
Note: See TracBrowser for help on using the repository browser.