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

Last change on this file since 5763 was 5763, checked in by cameron, 19 months ago

Range RE objects

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