source: icGREP/icgrep-devel/icgrep/re/re_reverse.cpp @ 5791

Last change on this file since 5791 was 5777, checked in by cameron, 20 months ago

Bug fix for re_compiler when CCs directly supplied

File size: 4.8 KB
Line 
1/*
2 *  Copyright (c) 2017 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include "re_reverse.h"
8#include <re/re_cc.h>
9#include <re/re_name.h>
10#include <re/re_start.h>
11#include <re/re_end.h>
12#include <re/re_any.h>
13#include <re/re_seq.h>
14#include <re/re_alt.h>
15#include <re/re_rep.h>
16#include <re/re_group.h>
17#include <re/re_range.h>
18#include <re/re_diff.h>
19#include <re/re_intersect.h>
20#include <re/re_assertion.h>
21#include <re/printer_re.h>
22#include <llvm/Support/ErrorHandling.h>
23#include <llvm/Support/raw_ostream.h>
24#include <llvm/Support/Debug.h>
25#include <map>
26
27using namespace llvm;
28
29namespace re {
30
31RE * reverse_helper(RE * re, std::map<std::string, Name *> & captureMap) {
32    if (CC * cc = dyn_cast<CC>(re)) {
33        return makeCC(cc, makeCC());
34    } else if (Range * rg = dyn_cast<Range>(re)) {
35        return makeRange(rg->getLo(), rg->getHi());
36    } else if (Seq * seq = dyn_cast<Seq>(re)) {
37        std::vector<RE*> list;
38        for (auto i = seq->rbegin(); i != seq->rend(); ++i) {
39            list.push_back(reverse_helper(*i, captureMap));
40        }
41        return makeSeq(list.begin(), list.end());
42    } else if (Alt * alt = dyn_cast<Alt>(re)) {
43        std::vector<RE*> list;
44        for (auto i = alt->begin(); i != alt->end(); ++i) {
45            list.push_back(reverse_helper(*i, captureMap));
46        }
47        return makeAlt(list.begin(), list.end());
48    } else if (Rep * rep = dyn_cast<Rep>(re)) {
49        return makeRep(reverse_helper(rep->getRE(), captureMap), rep->getLB(), rep->getUB());
50    } else if (Group * g = dyn_cast<Group>(re)) {
51        return makeGroup(g->getMode(), reverse_helper(g->getRE(), captureMap), g->getSense());
52    } else if (Diff * diff = dyn_cast<Diff>(re)) {
53        return makeDiff(reverse_helper(diff->getLH(), captureMap), reverse_helper(diff->getRH(), captureMap));
54    } else if (Intersect * e = dyn_cast<Intersect>(re)) {
55        return makeIntersect(reverse_helper(e->getLH(), captureMap), reverse_helper(e->getRH(), captureMap));
56    } else if (Assertion * a = dyn_cast<Assertion>(re)) {
57        return makeAssertion(reverse_helper(a->getAsserted(), captureMap), Assertion::reverseKind(a->getKind()), a->getSense());
58    } else if (isa<Start>(re)) {
59        return makeEnd();
60    } else if (isa<End>(re)) {
61        return makeStart();
62    } else if (Name * n = dyn_cast<Name>(re)) {
63        switch (n->getType()) {
64            case Name::Type::Byte:
65            case Name::Type::Unicode:
66                return makeName(cast<CC>(n->getDefinition()));
67            case Name::Type::UnicodeProperty:
68                return makeName(n->getNamespace(), n->getName(), Name::Type::UnicodeProperty);
69            case Name::Type::ZeroWidth:
70                return makeZeroWidth(n->getName(), reverse_helper(n->getDefinition(), captureMap));
71            case Name::Type::Capture: 
72                {
73                    std::string cname = n->getName();
74                    auto f = captureMap.find(cname);
75                    if (f != captureMap.end()) {
76                        return makeReference(f->second->getName(), f->second);
77                    }
78                    else {
79                        std::string newName = "\\" + std::to_string(captureMap.size() + 1);
80                        Name * capture = makeCapture(newName, reverse_helper(n->getDefinition(), captureMap));
81                        captureMap.insert(std::make_pair(cname, capture));
82                        return capture;
83                    }
84                }
85            case Name::Type::Reference:
86                {
87                    Name * referent = cast<Name>(n->getDefinition());
88                    std::string cname = referent->getName();
89                    auto f = captureMap.find(cname);
90                    if (f != captureMap.end()) {
91                       return makeReference(f->second->getName(), f->second);
92                    }
93                    else {
94                        std::string newName = "\\" + std::to_string(captureMap.size() + 1);
95                        Name * capture = makeCapture(newName, reverse_helper(referent->getDefinition(), captureMap));
96                        captureMap.insert(std::make_pair(cname, capture));
97                        return capture;
98                    }
99                }
100            case Name::Type::Unknown:
101                return makeName(n->getName(), n->getDefinition());
102            default:
103                llvm::report_fatal_error("re::reverse: unhandled Name type");
104        }
105    } else if (isa<Any>(re)) {
106        return makeAny();
107    } else {
108        llvm::report_fatal_error("re::reverse: unhandled regexp type");
109    }
110
111}
112
113RE * reverse(RE * re) {
114    std::map<std::string, Name *> captureMap;
115    return reverse_helper(re, captureMap);
116}
117}
Note: See TracBrowser for help on using the repository browser.