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

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

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

File size: 4.5 KB
RevLine 
[5493]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>
[5777]16#include <re/re_group.h>
[5763]17#include <re/re_range.h>
[5493]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
[5812]24
[5493]25using namespace llvm;
26
27namespace re {
28
[5812]29using CaptureMap = std::map<std::string, re::Name *>;
30
31RE * reverse(RE * re, CaptureMap & captureMap) {
32    if (isa<CC>(re)) {
[5805]33        return re;
[5763]34    } else if (Range * rg = dyn_cast<Range>(re)) {
35        return makeRange(rg->getLo(), rg->getHi());
[5493]36    } else if (Seq * seq = dyn_cast<Seq>(re)) {
37        std::vector<RE*> list;
38        for (auto i = seq->rbegin(); i != seq->rend(); ++i) {
[5812]39            list.push_back(reverse(*i, captureMap));
[5493]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) {
[5812]45            list.push_back(reverse(*i, captureMap));
[5493]46        }
47        return makeAlt(list.begin(), list.end());
48    } else if (Rep * rep = dyn_cast<Rep>(re)) {
[5812]49        return makeRep(reverse(rep->getRE(), captureMap), rep->getLB(), rep->getUB());
[5777]50    } else if (Group * g = dyn_cast<Group>(re)) {
[5812]51        return makeGroup(g->getMode(), reverse(g->getRE(), captureMap), g->getSense());
[5493]52    } else if (Diff * diff = dyn_cast<Diff>(re)) {
[5812]53        return makeDiff(reverse(diff->getLH(), captureMap), reverse(diff->getRH(), captureMap));
[5493]54    } else if (Intersect * e = dyn_cast<Intersect>(re)) {
[5812]55        return makeIntersect(reverse(e->getLH(), captureMap), reverse(e->getRH(), captureMap));
[5493]56    } else if (Assertion * a = dyn_cast<Assertion>(re)) {
[5812]57        return makeAssertion(reverse(a->getAsserted(), captureMap), Assertion::reverseKind(a->getKind()), a->getSense());
[5493]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()) {
[5630]64            case Name::Type::Unicode:
65                return makeName(cast<CC>(n->getDefinition()));
[5493]66            case Name::Type::UnicodeProperty:
67                return makeName(n->getNamespace(), n->getName(), Name::Type::UnicodeProperty);
68            case Name::Type::ZeroWidth:
[5812]69                return makeZeroWidth(n->getName(), reverse(n->getDefinition(), captureMap));
70            case Name::Type::Capture:
[5493]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);
[5812]79                        Name * capture = makeCapture(newName, reverse(n->getDefinition(), captureMap));
[5493]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);
[5812]94                        Name * capture = makeCapture(newName, reverse(referent->getDefinition(), captureMap));
[5493]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) {
[5812]113    CaptureMap captureMap;
114    return reverse(re, captureMap);
[5493]115}
[5812]116
[5493]117}
Note: See TracBrowser for help on using the repository browser.