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

Last change on this file was 5812, checked in by nmedfort, 2 months ago

Bug fix for RE local + some clean up of RE local and the RE Compiler

File size: 4.5 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 <llvm/Support/ErrorHandling.h>
22#include <map>
23
24
25using namespace llvm;
26
27namespace re {
28
29using CaptureMap = std::map<std::string, re::Name *>;
30
31RE * reverse(RE * re, CaptureMap & captureMap) {
32    if (isa<CC>(re)) {
33        return re;
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(*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(*i, captureMap));
46        }
47        return makeAlt(list.begin(), list.end());
48    } else if (Rep * rep = dyn_cast<Rep>(re)) {
49        return makeRep(reverse(rep->getRE(), captureMap), rep->getLB(), rep->getUB());
50    } else if (Group * g = dyn_cast<Group>(re)) {
51        return makeGroup(g->getMode(), reverse(g->getRE(), captureMap), g->getSense());
52    } else if (Diff * diff = dyn_cast<Diff>(re)) {
53        return makeDiff(reverse(diff->getLH(), captureMap), reverse(diff->getRH(), captureMap));
54    } else if (Intersect * e = dyn_cast<Intersect>(re)) {
55        return makeIntersect(reverse(e->getLH(), captureMap), reverse(e->getRH(), captureMap));
56    } else if (Assertion * a = dyn_cast<Assertion>(re)) {
57        return makeAssertion(reverse(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::Unicode:
65                return makeName(cast<CC>(n->getDefinition()));
66            case Name::Type::UnicodeProperty:
67                return makeName(n->getNamespace(), n->getName(), Name::Type::UnicodeProperty);
68            case Name::Type::ZeroWidth:
69                return makeZeroWidth(n->getName(), reverse(n->getDefinition(), captureMap));
70            case Name::Type::Capture:
71                {
72                    std::string cname = n->getName();
73                    auto f = captureMap.find(cname);
74                    if (f != captureMap.end()) {
75                        return makeReference(f->second->getName(), f->second);
76                    }
77                    else {
78                        std::string newName = "\\" + std::to_string(captureMap.size() + 1);
79                        Name * capture = makeCapture(newName, reverse(n->getDefinition(), captureMap));
80                        captureMap.insert(std::make_pair(cname, capture));
81                        return capture;
82                    }
83                }
84            case Name::Type::Reference:
85                {
86                    Name * referent = cast<Name>(n->getDefinition());
87                    std::string cname = referent->getName();
88                    auto f = captureMap.find(cname);
89                    if (f != captureMap.end()) {
90                       return makeReference(f->second->getName(), f->second);
91                    }
92                    else {
93                        std::string newName = "\\" + std::to_string(captureMap.size() + 1);
94                        Name * capture = makeCapture(newName, reverse(referent->getDefinition(), captureMap));
95                        captureMap.insert(std::make_pair(cname, capture));
96                        return capture;
97                    }
98                }
99            case Name::Type::Unknown:
100                return makeName(n->getName(), n->getDefinition());
101            default:
102                llvm::report_fatal_error("re::reverse: unhandled Name type");
103        }
104    } else if (isa<Any>(re)) {
105        return makeAny();
106    } else {
107        llvm::report_fatal_error("re::reverse: unhandled regexp type");
108    }
109
110}
111
112RE * reverse(RE * re) {
113    CaptureMap captureMap;
114    return reverse(re, captureMap);
115}
116
117}
Note: See TracBrowser for help on using the repository browser.