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

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

different updates to CoRE

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