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

Last change on this file since 5234 was 5234, checked in by nmedfort, 2 years ago

Modified memory alignment mechanism for GetPropertyValueGrepString? + misc. changes.

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