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

Last change on this file was 6232, checked in by cameron, 7 months ago

Use RE_Transformer for reverse

File size: 2.9 KB
Line 
1/*
2 *  Copyright (c) 2018 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/re_toolchain.h>
22#include <llvm/Support/ErrorHandling.h>
23#include <map>
24
25
26using namespace llvm;
27
28namespace re {
29   
30    using CaptureMap = std::map<std::string, Name *>;
31
32class ReverseTransformer : public RE_Transformer {
33public:
34    ReverseTransformer() : RE_Transformer("Reverse") {}
35    RE * transformName(Name * n) override {
36        Name::Type nType = n ->getType();
37        if (nType == Name::Type::Capture) {
38            std::string cname = n->getName();
39            auto f = mCaptureMap.find(cname);
40            if (f != mCaptureMap.end()) {
41                return makeReference(f->second->getName(), f->second);
42            }
43            else {
44                std::string newName = "\\" + std::to_string(mCaptureMap.size() + 1);
45                Name * capture = makeCapture(newName, transform(n->getDefinition()));
46                mCaptureMap.emplace(cname, capture);
47                return capture;
48            }
49        }
50        if (nType == Name::Type::Reference) {
51            Name * referent = cast<Name>(n->getDefinition());
52            std::string cname = referent->getName();
53            auto f = mCaptureMap.find(cname);
54            if (f != mCaptureMap.end()) {
55                return makeReference(f->second->getName(), f->second);
56            }
57            else {
58                std::string newName = "\\" + std::to_string(mCaptureMap.size() + 1);
59                Name * capture = makeCapture(newName, transform(referent->getDefinition()));
60                mCaptureMap.emplace(cname, capture);
61                return capture;
62            }
63        }
64        return n;
65    }
66    RE * transformSeq (Seq * seq) override {
67        std::vector<RE*> list;
68        for (auto i = seq->rbegin(); i != seq->rend(); ++i) {
69            list.push_back(transform(*i));
70        }
71        return makeSeq(list.begin(), list.end());
72    }
73    RE * transformStart (Start *) override { return makeEnd();}
74    RE * transformEnd (End *) override { return makeStart();}
75    RE * transformAssertion (Assertion * a) override {
76        RE * asserted = a->getAsserted();
77        RE * reversed = transform(asserted);
78        if ((a->getKind() == Assertion::Kind::Boundary) && (reversed == asserted)) {
79            return a;
80        }
81        return makeAssertion(reversed, Assertion::reverseKind(a->getKind()), a->getSense());
82    }
83   
84private:
85    CaptureMap mCaptureMap;
86};
87
88RE * reverse(RE * re) {
89    return ReverseTransformer().transformRE(re);
90}
91
92}
Note: See TracBrowser for help on using the repository browser.