source: icGREP/icgrep-devel/icgrep/combine/regexGen.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: 16.6 KB
Line 
1#include "regexGen.h"
2#include "stringGen.h"
3#include "propGen.h"
4
5
6#include <string>
7#include <vector>
8#include <fstream>
9#include <boost/algorithm/string/split.hpp>
10#include <boost/algorithm/string/predicate.hpp>
11#include <iostream>
12#include <algorithm>
13
14#include <stdlib.h>
15#include <time.h>
16#include <stdio.h>
17#include <re/re_diff.h>
18#include <re/re_any.h>
19#include <re/re_parser.h>
20
21
22
23using namespace std;
24
25class CC {
26        std::vector<string> ccList;
27        std::vector<string> usedCC;
28        re::RE_Syntax syntax;
29public:
30        CC(std::vector<string> &params, std::vector<string> &values, re::RE_Syntax syntax){
31                this->syntax = syntax;
32                parseCC(params, values);
33        }
34
35        std::string getCC(){
36                int random;
37                std::string cc;
38                if (!ccList.empty()){
39                        random = rand() % ccList.size();
40                        cc = ccList[random];
41                        ccList.erase(ccList.begin()+random);
42                        usedCC.push_back(cc);
43                        return cc;
44                }
45                else if (!usedCC.empty()){
46                        random = rand() % usedCC.size();
47                        cc = usedCC[random];
48                        return cc;
49                }
50                else return "C";
51        }
52
53        std::vector<string> getRemainingCC(){
54                return ccList;
55        }
56private:
57
58        void parseCC(std::vector<string> params, std::vector<string> values){
59                int colnum = 0;
60                for(auto col : values){
61                        if ((col != "false") && (col!= "off")){
62                                string cc;
63                                if (params[colnum] == "wordC") {
64                                        ccList.push_back(getWord());
65                                }
66                                else if (params[colnum] == "notWordC") {
67                                        ccList.push_back(getNotWord());
68                                }
69                                else if (params[colnum] == "whitespace") {
70                                        ccList.push_back(getWhitespace());
71                                }
72                                else if (params[colnum] == "notWhitespace") {
73                                        ccList.push_back(getNotWhitespace());
74                                }
75                                else if (params[colnum] == "tab") {
76                                        ccList.push_back(getTab());
77                                }
78                                else if (params[colnum] == "digit") {
79                                        ccList.push_back(getDigit());
80                                }
81                                else if (params[colnum] == "notDigit") {
82                                        ccList.push_back(getNotDigit());
83                                }
84                                else if (params[colnum] == "any") {
85                                        ccList.push_back(getAny());
86                                }
87                                else if (params[colnum] == "unicodeC"){
88                                        ccList.push_back(getUnicodeCodepoint());
89                                }
90                                else if (params[colnum] == "range"){
91                                        ccList.push_back(getRange());
92                                }
93                                else if (params[colnum] == "posix"){
94                                        ccList.push_back(getPosix(col));
95                                }
96                                else if (params[colnum] == "property") {
97                                        ccList.push_back(getProperty(col));
98                                }
99                                else if (params[colnum] == "notProperty") {
100                                        ccList.push_back(getNotProperty(col));
101                                }
102                                else if (params[colnum] == "nameProperty") {
103                                        ccList.push_back(getUnicodeName());
104                                }
105
106                        }
107                        ++colnum;
108                }
109        }
110
111        string getWord(){
112                if (syntax == re::RE_Syntax::BRE){
113                        return "w";
114                }
115                else return "\\w";
116        }
117        string getNotWord(){
118                if (syntax == re::RE_Syntax::BRE){
119                        return "notWord";
120                }
121                else return "\\W";
122        }
123        string getWhitespace(){
124                return "\\s";
125        }
126        string getNotWhitespace(){
127                return "\\S";
128        }
129        string getTab(){
130                if (syntax != re::RE_Syntax::PCRE){
131                        return "t";
132                }
133                else return "\\t";
134        }
135        string getDigit(){
136                if (syntax != re::RE_Syntax::PCRE){
137                        return "d";
138                }
139                else return "\\d";
140        }
141        string getNotDigit(){
142                if (syntax != re::RE_Syntax::PCRE){
143                        return "D";
144                }
145                else return "\\D";
146        }
147        string getAny(){
148                return ".";
149        }
150        string getPosix(string value){
151                        return "[[:" + value + ":]]";
152        }
153
154        std::string getCharacterName(){
155                int random = rand() % 28179;
156                ifstream file;
157                file.open("../icgrep/combine/UnicodeNames.txt");
158                string line;
159                for (int i = 0; i <= random ; i++){
160                        if (!getline(file, line)) {
161                                cerr << "Error in extracting Unicode property names!\n";
162                        }
163                }
164                file.close();
165                return line;
166        }
167        std::string getProperty(string type){
168
169                if (syntax == re::RE_Syntax::PCRE) {
170                        // vector<string> prop = {"L", "Ll", "Lu", "Lt", "Lm", "Lo", "M", "Mn",
171                        //                                                                                       "Mc", "Me", "Z", "Zs", "Zl", "Zp", "S", "Sm", "Sc",
172                        //                                                                                       "Sk", "So", "N", "Nd", "Nl", "No", "P", "Pd", "Ps",
173                        //                                                                                       "Pe", "Pi", "Pf", "Pc", "Po", "C", "Cc", "Cf", "Co",
174                        //                                                                                 "Cs", "Cn"};
175                        PropGen p;
176                        string regex = "";
177                        if (type == "string"){
178                                regex = "abc";
179                        }
180                        return "\\p{" + p.getPropertyValue(type, regex) + "}" ;
181                }
182                else {
183                        return "p";
184                }
185        }
186        std::string getNotProperty(string type){
187                if (syntax == re::RE_Syntax::PCRE) {
188                        // vector<string> prop = {"L", "Ll", "Lu", "Lt", "Lm", "Lo", "M", "Mn",
189                        //                                                                                       "Mc", "Me", "Z", "Zs", "Zl", "Zp", "S", "Sm", "Sc",
190                        //                                                                                       "Sk", "So", "N", "Nd", "Nl", "No", "P", "Pd", "Ps",
191                        //                                                                                       "Pe", "Pi", "Pf", "Pc", "Po", "C", "Cc", "Cf", "Co",
192                        //                                                                                 "Cs", "Cn"};
193                        // int random = rand() % prop.size();
194                        // return "\\p{" + prop[random] + "}" ;
195                        string regex = "";
196                        if (type == "string"){
197                                regex = "abc";
198                        }
199                        PropGen p;
200                        return "\\P{" + p.getPropertyValue(type, regex) + "}" ;
201                }
202                else {
203                        return "P";
204                }
205        }
206        std::string getUnicodeName(){
207                if (syntax == re::RE_Syntax::PCRE) {
208                        return "\\N{^" + getCharacterName() + "$}" ;
209                }
210                else {
211                        return "N";
212                }
213        }
214        std::string getUnicodeCodepoint(){
215                if (syntax != re::RE_Syntax::PCRE) {
216                        return "u";
217                }
218                else {
219                        int random = rand() % 16544;
220                        ifstream file;
221                        file.open("../icgrep/combine/Unicode.txt");
222                        string line;
223                        for (int i = 0; i <= random ; i++){
224                                if (!getline(file, line)) {
225                                        cerr << "Error in extracting Unicode codepoints!\n";
226                                }
227                        }
228                        file.close();
229                        return "\\u" + line;
230                }
231        }
232        std::string getUnicodeRange(){
233
234                int random1 = rand() % 16544;
235                int random2 = rand() % 16544;
236                if (random1 > random2){
237                        std::swap(random1, random2);
238                }
239                ifstream file;
240                file.open("../icgrep/combine/Unicode.txt");
241                string line1;
242                string line2;
243                for (int i = 0; i < random2 ; i++){
244                        if (!getline(file, line2)) {
245                                cerr << "Error in extracting Unicode codepoints!\n";
246                        }
247                        if (random1 == i){
248                                line1 = line2;
249                        }
250                }
251                file.close();
252                return "[\\u" + line1 + "-\\u" + line2 + "]";
253
254        }
255        std::string getRange(){
256
257                if (syntax != re::RE_Syntax::PCRE){
258                        std::vector<string> lists = {"[a-zA-Z0-9]","[A-Za-z]","[0-9]"};
259                        int random = rand() % lists.size();
260                        return lists[random];
261                }
262                else {
263                        return getUnicodeRange();
264                }
265        }
266};
267
268RegexGen::RegexGen(std::vector<string> param, std::vector<string> val): mParameters(param), mValues(val) {
269        try{
270                syntax = getSyntax();
271                RE = parseRE();
272                flags = parseFlags();
273                fileType = getFileTy();
274        }
275        catch (...){
276                syntax = re::RE_Syntax::PCRE;
277                RE = "Could Not Generate RE";
278        }
279}
280
281string RegexGen::stringifyLine(vector<string> elements, string separator){
282        string line = "";
283        bool sep = false;
284        for (auto e : elements){
285                line += sep? separator + e : e;
286                sep = true;
287        }
288        return line;
289}
290
291
292std::string RegexGen::getList(string cc1, string cc2, string cc3){
293        if (syntax == re::RE_Syntax::BRE) {
294                return "l";
295        }
296        else if (syntax == re::RE_Syntax::ERE){
297                if(cc1.find("[")!= string::npos) cc1 = "a";
298                if(cc2.find("[")!= string::npos) cc2 = "b";
299                if(cc3.find("[")!= string::npos) cc3 = "c";
300                return "[" + cc1 + cc2 + cc3 + "]";
301        }
302        else {
303                return "[" + cc1 + cc2 + cc3 + "]";
304        }
305
306}
307std::string RegexGen::getNList(string cc1, string cc2, string cc3){
308        if (syntax == re::RE_Syntax::BRE) {
309                return "L";
310        }
311        else if (syntax == re::RE_Syntax::ERE){
312                if(cc1.find("[")!= string::npos) cc1 = "1";
313                if(cc2.find("[")!= string::npos) cc2 = "2";
314                if(cc3.find("[")!= string::npos) cc3 = "3";
315
316        }
317        string ret = "[^" + cc1 + cc2 + cc3 + "]";
318        if (getAssertionCoating(ret) != ret){
319                return ret;
320        }
321        return ret;
322}
323
324
325string RegexGen::getZeroOrOne(string cc){
326        if (syntax == re::RE_Syntax::BRE) {
327                return cc+ "\\?";
328        }
329        else {
330                return cc + "?" ;
331        }
332}
333string RegexGen::getZeroOrMore(string cc){
334                return cc + "*" ;
335}
336string RegexGen::getOneOrMore(string cc){
337        if (syntax == re::RE_Syntax::BRE) {
338                return cc+ "\\+";
339        }
340        else {
341                return cc + "+" ;
342        }
343}
344string RegexGen::getRep(string cc, string size){
345        int rep;
346        if (size == "small"){
347                rep = rand() % 10 + 1;
348        }
349        else if (size == "medium"){
350                rep = rand() % 100 + 1;
351        }
352        else if (syntax != re::RE_Syntax::PCRE){
353                rep = rand() % 255 + 1;
354        }
355        else {
356                rep = rand() % 1000 + 1;
357        }
358
359        if (syntax == re::RE_Syntax::BRE) {
360                return cc + "\\{" + to_string(rep) + "\\}";
361        }
362        else {
363                return cc + "{" + to_string(rep) + "}";
364        }
365}
366string RegexGen::getRepNM(string cc, string size){
367        int lb;
368        int ub;
369        if (size == "small-small"){
370                lb = rand() % 10;
371                ub = rand() % 10 + 1;
372        }
373        else if (size == "small- medium"){
374                lb = rand() % 10;
375                ub = rand() % 100 + 1;
376        }
377        else if (size == "small-large"){
378                lb = rand() % 10;
379                ub = rand() % 255 + 1;
380        }
381        else if (size == "medium-meduim"){
382                lb = rand() % 100;
383                ub = rand() % 100 + 1;
384        }
385        else if (size == "medium-large"){
386                lb = rand() % 100;
387                if (syntax != re::RE_Syntax::PCRE){
388                        ub = rand() % 255 + 1;
389                }
390                else {
391                        ub = rand() % 1000 + 1;
392                }
393        }
394        else {
395                if (syntax != re::RE_Syntax::PCRE){
396                        lb = rand() % 255;
397                        ub = rand() % 255 + 1;
398                }
399                else {
400                        lb = rand() % 1000;
401                        ub = rand() % 1000 + 1;
402                }
403
404        }
405        if (lb > ub) {
406                std::swap(lb, ub);
407        }
408        if (syntax == re::RE_Syntax::BRE) {
409                return cc + "\\{" + to_string(lb) + ',' + to_string(ub) + "\\}";
410        }
411        else {
412                return cc + "{" + to_string(lb) + ',' + to_string(ub) + "}";
413        }
414}
415string RegexGen::getRepMore(string cc, string size){
416        int lb;
417        if (size == "small"){
418                lb = rand() % 10 + 1;
419        }
420        else if (size == "medium"){
421                lb = rand() % 100 + 1;
422        }
423        else {
424                if (syntax != re::RE_Syntax::PCRE){
425                        lb = rand() % 255 + 1;
426                }
427                else {
428                        lb = rand() % 1000 + 1;
429                }
430        }
431
432        if (syntax == re::RE_Syntax::BRE) {
433                return cc + "\\{" + to_string(lb) + ",\\}";
434        }
435        else {
436                return cc + "{" + to_string(lb) + ",}";
437        }
438}
439string RegexGen::getJoin(string LS, string RS){
440        if (syntax == re::RE_Syntax::BRE) {
441                return "\\(" + LS + "\\|" + RS + "\\)";
442        }
443        else {
444                return "(" + LS + "|" + RS + ")";
445        }
446}
447string RegexGen::getBackRef(string cc){
448        if (syntax == re::RE_Syntax::BRE) {
449                return "\\(" + cc + "\\)";
450        }
451        else {
452                return "(" + cc + ")";
453        }
454
455}
456string RegexGen::getAssertionCoating(string cc){
457        return cc;
458}
459
460string RegexGen::getNegativeAssertionCoating(string cc){
461        if (cc == "\\s"){
462                return "\\S";
463        }
464        else if (cc == "\\S"){
465                return "\\s";
466        }
467        else if (cc == "\\t"){
468                return "\\S";
469        }
470        else if (cc == "\\w"){
471                return "\\W";
472        }
473        else if (cc == "\\W"){
474                return "\\w";
475        }
476        else if (cc == "\\d"){
477                return "\\D";
478        }
479        else if (cc == "\\D"){
480                return "\\d";
481        }
482        else if (cc.find("\\p") == 0){
483                return "\\P" + cc.substr(2);
484        }
485        else {
486                return "";
487        }
488}
489
490string RegexGen::getLookAhead(string cc){
491        if (syntax == re::RE_Syntax::PCRE) {
492                std::string tail = getAssertionCoating(cc);
493                return "(?=" + cc + ")" + tail;
494        }
495        return "la";
496}
497string RegexGen::getNegativeLookAhead(string cc){
498        if (syntax == re::RE_Syntax::PCRE) {
499                std::string tail = getNegativeAssertionCoating(cc);
500                return "(?!" + cc + ")" + tail;
501        }
502        return "nla";
503}
504string RegexGen::getLookBehind(string cc){
505        if (syntax == re::RE_Syntax::PCRE) {
506                std::string front = getAssertionCoating(cc);
507                return front + "(?<=" + cc + ")";
508        }
509        return "lb";
510}
511string RegexGen::getNegativeLookBehind(string cc){
512        if (syntax == re::RE_Syntax::PCRE) {
513                std::string front = getNegativeAssertionCoating(cc);
514                return front + "(?<!" + cc + ")";
515        }
516        return "nlb";
517}
518
519string RegexGen::getWordBegin(){
520        if (syntax == re::RE_Syntax::PCRE){
521                return "\\W\\<\\w";
522        }
523        else return "wb";
524}
525string RegexGen::getWordEnd(){
526        if (syntax == re::RE_Syntax::PCRE){
527                return "\\w\\>\\W";
528        }
529        else return "we";
530}
531
532
533bool RegexGen::usesCC(std::string op){
534        std::vector<string> set = {"zeroOrOne","zeroOrMore","oneOrMore","repeat_n","repeat_nm","repeat_n_more","repeat_m_less",
535                                                        "list", "nList", "backref", "join", "look_ahead", "mlook_ahead", "look_behind", "nlook_behind" "look_ahead",
536                                                        "mlook_ahead", "look_behind", "nlook_behind"};
537
538        if(std::find(set.begin(), set.end(), op) != set.end()){
539                return true;
540        }
541        else return false;
542}
543
544re::RE_Syntax RegexGen::getSyntax(){
545        int colnum = 0;
546        for(auto col : mValues){
547                if (mParameters[colnum] == "syntax") {
548                        if (col == "-G"){
549                                return re::RE_Syntax::BRE;
550                        }
551                        else if (col == "-E"){
552                                return re::RE_Syntax::ERE;
553                        }
554                        else if (col == "-P"){
555                                return re::RE_Syntax::PCRE;
556                        }
557                        else if (col == "-F"){
558                                return re::RE_Syntax::FixedStrings;
559                        }
560                }
561                colnum++;
562        }
563        return re::RE_Syntax::PCRE;
564}
565RegexGen::FileType RegexGen::getFileTy(){
566        int colnum = 0;
567        for(auto col : mValues){
568                if (mParameters[colnum] == "fileType") {
569                        if (col == "s"){
570                                return FileType::SMALL;
571                        }
572                        else if (col == "m"){
573                                return FileType::MEDIUM;
574                        }
575                        else if (col == "l"){
576                                return FileType::LARGE;
577                        }
578                }
579                colnum++;
580        }
581        //default
582        return FileType::SMALL;
583}
584
585
586std::string RegexGen::parseRE(){
587
588        std::vector<string> fullRE;
589        std::vector<string> assertions;
590        CC ccHandler(mParameters,mValues, syntax);
591        int random;
592        bool bref = false;
593        string first = "";
594        string last = "";
595        std::string re;
596        for (int colnum = 0; colnum < mValues.size(); colnum++){
597                auto col = mValues[colnum];
598                if (col != "false" && col != "off"){
599                        string cc;
600                        if (usesCC(mParameters[colnum])){
601
602                                cc = ccHandler.getCC();
603                                if (mParameters[colnum] == "zeroOrOne"  ){
604                                        re = getZeroOrOne(cc);
605                                        if (!re.empty())
606                                        fullRE.push_back(re);
607                                }
608                                else if (mParameters[colnum] == "zeroOrMore"){
609                                        re = getZeroOrMore(cc);
610                                        if (!re.empty())
611                                        fullRE.push_back(re);
612                                }
613                                else if (mParameters[colnum] == "oneOrMore"){
614                                        re = getOneOrMore(cc);
615                                        if (!re.empty())
616                                        fullRE.push_back(re);
617                                }
618                                else if (mParameters[colnum] == "repeat_n"){
619                                        re = getRep(cc, col);
620                                        if (!re.empty())
621                                        fullRE.push_back(re);
622                                }
623                                else if (mParameters[colnum] == "repeat_nm" ){
624                                        re = getRepNM(cc, col);
625                                        if (!re.empty())
626                                        fullRE.push_back(re);
627                                }
628                                else if (mParameters[colnum] == "repeat_n_more" ){
629                                        re = getRepMore(cc, col);
630                                        if (!re.empty())
631                                        fullRE.push_back(re);
632                                }
633                                else if (mParameters[colnum] == "list"){
634                                        string cc1 = ccHandler.getCC();
635                                        string cc2 = ccHandler.getCC();
636                                        fullRE.push_back(getList(cc, cc1, cc2));
637                                }
638                                else if (mParameters[colnum] == "nList"){
639                                        string cc1 = ccHandler.getCC();
640                                        string cc2 = ccHandler.getCC();
641                                        auto ret = getNList(cc, cc1, cc2);
642                                        if (ret!= "")
643                                                fullRE.push_back(ret);
644                                }
645                                else if (mParameters[colnum] == "backref"){
646                                        bref = true;
647                                }
648                                else if (mParameters[colnum] == "join" ){
649                                        std::string cc2 = ccHandler.getCC();
650                                        re = getJoin(cc, cc2);
651                                        if (!re.empty())
652                                        fullRE.push_back(re);
653                                }
654                                else if (mParameters[colnum] == "look_ahead"){
655                                        re = getLookAhead(cc);
656                                        if (!re.empty())
657                                        assertions.push_back(re);
658                                }
659                                else if (mParameters[colnum] == "nlook_ahead"){
660                                        if (cc == ".") {
661                                                continue;
662                                        }
663                                        else {
664                                                re = getNegativeLookAhead(cc);
665                                                if (!re.empty())
666                                                assertions.push_back(re);
667                                        }
668                                }
669                                else if (mParameters[colnum] == "look_behind"){
670                                        re = getLookBehind(cc);
671                                        if (!re.empty())
672                                        assertions.push_back(re);
673                                }
674                                else if (mParameters[colnum] == "nlook_behind"){
675                                        if (cc == ".") {
676                                                continue;
677                                        }
678                                        else {
679                                                re = getNegativeLookBehind(cc);
680                                                if (!re.empty())
681                                                assertions.push_back(re);
682                                        }
683                                }
684                        }
685                        else {
686
687                                if (mParameters[colnum] == "start"){
688                                                first = "^";
689                                }
690                                else if (mParameters[colnum] == "end"){
691                                                last = "$";
692                                }
693                                else if (mParameters[colnum] == "word_begin") {
694                                        fullRE.push_back(getWordBegin());
695                                }
696                                else if (mParameters[colnum] == "word_end") {
697                                        fullRE.push_back(getWordEnd());
698                                }
699                        }
700                }
701        }
702
703        vector<string> ccList = ccHandler.getRemainingCC();
704        while(!ccList.empty()){
705                fullRE.push_back(ccList.back());
706                ccList.pop_back();
707        }
708        if(!fullRE.empty()){
709
710                if (bref && !fullRE.empty()){
711                        random = rand() % fullRE.size();
712                        fullRE[random] = getBackRef(fullRE[random]);
713                        std::copy (assertions.begin(), assertions.end(), std::back_inserter(fullRE));
714                        std::random_shuffle(fullRE.begin(), fullRE.end());
715                        fullRE.push_back("\\1");
716                }
717                else {
718                        std::copy (assertions.begin(), assertions.end(), std::back_inserter(fullRE)); //to avoid nesting assertions.
719                        std::random_shuffle(fullRE.begin(), fullRE.end());
720                }
721                string sre= first + stringifyLine(fullRE) + last;
722                return sre;
723        }
724        else {
725                return "";
726        }
727}
728
729std::vector<string> RegexGen::parseFlags(){
730        std::vector<string> flags;
731        for (int colnum = 0; colnum < mValues.size(); colnum++){
732                auto col = mValues[colnum];
733                if ((col != "false") && (col != "off")){
734                        if (mParameters[colnum] == "-c"
735                         || mParameters[colnum] == "-i"
736                         || mParameters[colnum] == "-v"
737                         || mParameters[colnum] == "-x"
738                         || mParameters[colnum] == "-w"
739                         || mParameters[colnum] == "-e"
740                         || mParameters[colnum] == "-f"){
741                                flags.push_back(mParameters[colnum]);
742                        }
743                        else if (mParameters[colnum] == "-t"){
744                                        flags.push_back("-t=" + col);
745                        }
746                        else if (mParameters[colnum] == "-BlockSize"){
747                                        flags.push_back("-BlockSize=" + col);
748                        }
749                        else if (mParameters[colnum] == "syntax"){
750                                        flags.push_back(col);
751                        }
752                }
753        }
754        return flags;
755}
Note: See TracBrowser for help on using the repository browser.