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

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

Partial check-in for avoidance of compiling Pablo/LLVM code to determine the Kernel struct type when using a cached object. Inactive RE alternation minimization check in.

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_diff.h>
17#include <re/re_intersect.h>
18#include <re/re_assertion.h>
19#include <re/printer_re.h>
20#include <llvm/Support/ErrorHandling.h>
21#include <llvm/Support/raw_ostream.h>
22#include <llvm/Support/Debug.h>
23#include <map>
24
25using namespace llvm;
26
27namespace re {
28
29RE * reverse_helper(RE * re, std::map<std::string, Name *> & captureMap) {
30    if (CC * cc = dyn_cast<CC>(re)) {
31        return makeCC(cc, makeCC());
32    } else if (Seq * seq = dyn_cast<Seq>(re)) {
33        std::vector<RE*> list;
34        for (auto i = seq->rbegin(); i != seq->rend(); ++i) {
35            list.push_back(reverse_helper(*i, captureMap));
36        }
37        return makeSeq(list.begin(), list.end());
38    } else if (Alt * alt = dyn_cast<Alt>(re)) {
39        std::vector<RE*> list;
40        for (auto i = alt->begin(); i != alt->end(); ++i) {
41            list.push_back(reverse_helper(*i, captureMap));
42        }
43        return makeAlt(list.begin(), list.end());
44    } else if (Rep * rep = dyn_cast<Rep>(re)) {
45        return makeRep(reverse_helper(rep->getRE(), captureMap), rep->getLB(), rep->getUB());
46    } else if (Diff * diff = dyn_cast<Diff>(re)) {
47        return makeDiff(reverse_helper(diff->getLH(), captureMap), reverse_helper(diff->getRH(), captureMap));
48    } else if (Intersect * e = dyn_cast<Intersect>(re)) {
49        return makeIntersect(reverse_helper(e->getLH(), captureMap), reverse_helper(e->getRH(), captureMap));
50    } else if (Assertion * a = dyn_cast<Assertion>(re)) {
51        return makeAssertion(reverse_helper(a->getAsserted(), captureMap), Assertion::reverseKind(a->getKind()), a->getSense());
52    } else if (isa<Start>(re)) {
53        return makeEnd();
54    } else if (isa<End>(re)) {
55        return makeStart();
56    } else if (Name * n = dyn_cast<Name>(re)) {
57        switch (n->getType()) {
58            case Name::Type::Byte:
59            case Name::Type::Unicode:
60                return makeName(cast<CC>(n->getDefinition()));
61            case Name::Type::UnicodeProperty:
62                return makeName(n->getNamespace(), n->getName(), Name::Type::UnicodeProperty);
63            case Name::Type::ZeroWidth:
64                return makeZeroWidth(n->getName(), reverse_helper(n->getDefinition(), captureMap));
65            case Name::Type::Capture: 
66                {
67                    std::string cname = n->getName();
68                    auto f = captureMap.find(cname);
69                    if (f != captureMap.end()) {
70                        return makeReference(f->second->getName(), f->second);
71                    }
72                    else {
73                        std::string newName = "\\" + std::to_string(captureMap.size() + 1);
74                        Name * capture = makeCapture(newName, reverse_helper(n->getDefinition(), captureMap));
75                        captureMap.insert(std::make_pair(cname, capture));
76                        return capture;
77                    }
78                }
79            case Name::Type::Reference:
80                {
81                    Name * referent = cast<Name>(n->getDefinition());
82                    std::string cname = referent->getName();
83                    auto f = captureMap.find(cname);
84                    if (f != captureMap.end()) {
85                       return makeReference(f->second->getName(), f->second);
86                    }
87                    else {
88                        std::string newName = "\\" + std::to_string(captureMap.size() + 1);
89                        Name * capture = makeCapture(newName, reverse_helper(referent->getDefinition(), captureMap));
90                        captureMap.insert(std::make_pair(cname, capture));
91                        return capture;
92                    }
93                }
94            case Name::Type::Unknown:
95                return makeName(n->getName(), n->getDefinition());
96            default:
97                llvm::report_fatal_error("re::reverse: unhandled Name type");
98        }
99    } else if (isa<Any>(re)) {
100        return makeAny();
101    } else {
102        llvm::report_fatal_error("re::reverse: unhandled regexp type");
103    }
104
105}
106
107RE * reverse(RE * re) {
108    std::map<std::string, Name *> captureMap;
109    return reverse_helper(re, captureMap);
110}
111}
Note: See TracBrowser for help on using the repository browser.