source: icGREP/icgrep-devel/icgrep/re/re_name_resolve.cpp @ 5418

Last change on this file since 5418 was 5267, checked in by nmedfort, 3 years ago

Code clean-up. Removed Pablo Call, SetIthBit? and Prototype.

File size: 5.8 KB
Line 
1#include "re_name_resolve.h"
2#include <re/re_name.h>
3#include <re/re_alt.h>
4#include <re/re_cc.h>
5#include <re/re_seq.h>
6#include <re/re_rep.h>
7#include <re/re_diff.h>
8#include <re/re_intersect.h>
9#include <re/re_assertion.h>
10#include <re/re_analysis.h>
11#include <re/re_memoizer.hpp>
12#include <UCD/ucd_compiler.hpp>
13#include <UCD/resolve_properties.h>
14#include <boost/container/flat_set.hpp>
15#include <sstream>
16
17using NameMap = UCD::UCDCompiler::NameMap;
18
19using namespace boost::container;
20using namespace llvm;
21
22namespace re {
23 
24static inline CC * extractCC(RE * re) {
25    if (isa<CC>(re)) {
26        return cast<CC>(re);
27    } else if (isa<Name>(re)) {
28        return extractCC(cast<Name>(re)->getDefinition());
29    }
30    return nullptr;
31}
32
33struct NameResolver {
34    RE * resolve(RE * re) {
35        if (Name * name = dyn_cast<Name>(re)) {
36            auto f = mMemoizer.find(name);
37            if (f == mMemoizer.end()) {
38                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
39                    name->setDefinition(resolve(name->getDefinition()));
40                } else if (LLVM_LIKELY(name->getType() == Name::Type::UnicodeProperty || name->getType() == Name::Type::ZeroWidth)) {
41                    if (UCD::resolvePropertyDefinition(name)) {
42                        if (name->getType() == Name::Type::ZeroWidth) {
43                            mZeroWidth = name;
44                        }
45                        name->setDefinition(resolve(name->getDefinition()));
46                    } else {
47                        name->setDefinition(makeCC(UCD::resolveUnicodeSet(name)));
48                    }
49                } else {
50                    throw std::runtime_error("All non-unicode-property Name objects should have been defined prior to Unicode property resolution.");
51                }
52            } else {
53                return *f;
54            }
55        } else if (Seq * seq = dyn_cast<Seq>(re)) {
56            for (auto si = seq->begin(); si != seq->end(); ++si) {
57                *si = resolve(*si);
58            }
59        } else if (Alt * alt = dyn_cast<Alt>(re)) {
60            CC * unionCC = nullptr;
61            std::stringstream name;
62            for (auto ai = alt->begin(); ai != alt->end(); ) {
63                RE * re = resolve(*ai);
64                if (CC * cc = extractCC(re)) {
65                    if (unionCC == nullptr) {
66                        unionCC = cc;
67                    } else {
68                        unionCC = makeCC(unionCC, cc);
69                        name << '+';
70                    }
71                    if (LLVM_LIKELY(isa<Name>(re))) {
72                        Name * n = cast<Name>(re);
73                        if (n->hasNamespace()) {
74                            name << n->getNamespace() << ':';
75                        }
76                        name << n->getName();
77                    } else if (isa<CC>(re)) {
78                        name << cast<CC>(re)->canonicalName(UnicodeClass);
79                    }
80                    ai = alt->erase(ai);
81                } else {
82                    *ai++ = re;
83                }
84            }
85            if (unionCC) {
86                alt->push_back(resolve(makeName(name.str(), unionCC)));
87            }
88            if (alt->size() == 1) {
89                return alt->front();
90            }
91        } else if (Rep * rep = dyn_cast<Rep>(re)) {
92            rep->setRE(resolve(rep->getRE()));
93        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
94            a->setAsserted(resolve(a->getAsserted()));
95        } else if (Diff * diff = dyn_cast<Diff>(re)) {
96            diff->setLH(resolve(diff->getLH()));
97            diff->setRH(resolve(diff->getRH()));
98            CC * lh = extractCC(diff->getLH());
99            CC * rh = extractCC(diff->getRH());
100            if (lh && rh) {
101                return resolve(makeName("diff", subtractCC(lh, rh)));
102            }
103        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
104            ix->setLH(resolve(ix->getLH()));
105            ix->setRH(resolve(ix->getRH()));
106            CC * lh = extractCC(ix->getLH());
107            CC * rh = extractCC(ix->getRH());
108            if (lh && rh) {
109                return resolve(makeName("intersect", intersectCC(lh, rh)));
110            }
111        }
112        return re;
113    }
114
115    void gather(RE * re) {
116        assert ("RE object cannot be null!" && re);
117        if (isa<Name>(re)) {
118            if (mVisited.insert(cast<Name>(re)).second) {
119                if (isa<CC>(cast<Name>(re)->getDefinition())) {
120                    mNameMap.emplace(cast<Name>(re), nullptr);
121                } else {
122                    gather(cast<Name>(re)->getDefinition());
123                }
124            }
125        } else if (isa<Seq>(re)) {
126            for (RE * item : *cast<Seq>(re)) {
127                gather(item);
128            }
129        } else if (isa<Alt>(re)) {
130            for (RE * item : *cast<Alt>(re)) {
131                gather(item);
132            }
133        } else if (isa<Rep>(re)) {
134            gather(cast<Rep>(re)->getRE());
135        } else if (isa<Assertion>(re)) {
136            gather(cast<Assertion>(re)->getAsserted());
137        } else if (isa<Diff>(re)) {
138            gather(cast<Diff>(re)->getLH());
139            gather(cast<Diff>(re)->getRH());
140        } else if (isa<Intersect>(re)) {
141            gather(cast<Intersect>(re)->getLH());
142            gather(cast<Intersect>(re)->getRH());
143        }
144    }
145
146    NameResolver(NameMap & nameMap, Name *& zeroWidth)
147    : mZeroWidth(zeroWidth)
148    , mNameMap(nameMap) {
149
150    }
151
152private:
153
154    Name *&                 mZeroWidth;
155    NameMap &               mNameMap;
156    Memoizer                mMemoizer;
157    flat_set<Name *>        mVisited;
158
159};
160   
161NameMap resolveNames(RE *& re, Name *& zeroWidth) {
162    NameMap nameMap;
163    NameResolver nameResolver(nameMap, zeroWidth);
164    re = nameResolver.resolve(re);
165    nameResolver.gather(re);
166    return nameMap;
167   
168}
169
170}
Note: See TracBrowser for help on using the repository browser.