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

Last change on this file since 5206 was 5158, checked in by cameron, 3 years ago

Support for enumeration basis sets

File size: 5.7 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 <unordered_set>
17#include <sstream>
18
19namespace re {
20 
21static inline CC * getDefinitionIfCC(RE * re) {
22    if (LLVM_LIKELY(isa<Name>(re))) {
23        Name * name = cast<Name>(re);
24        if (name->getDefinition() && isa<CC>(name->getDefinition())) {
25            return cast<CC>(name->getDefinition());
26        }
27    }
28    return nullptr;
29}
30
31Name * ZeroWidth = nullptr;
32
33RE * resolve(RE * re) {
34    Memoizer memoizer;
35    if (Name * name = dyn_cast<Name>(re)) {
36        auto f = memoizer.find(name);
37        if (f == memoizer.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                        ZeroWidth = name;
44                    }
45                    resolve(name->getDefinition());
46                } else {
47                    #ifndef DISABLE_PREGENERATED_UCD_FUNCTIONS
48                    if (AlgorithmOptionIsSet(UsePregeneratedUnicode)) {
49                        const std::string functionName = UCD::resolvePropertyFunction(name);
50                        const UCD::ExternalProperty & ep = UCD::resolveExternalProperty(functionName);
51                        Call * call = mPB.createCall(Prototype::Create(functionName, std::get<1>(ep), std::get<2>(ep), std::get<0>(ep)), mCCCompiler.getBasisBits());
52                        name->setCompiled(call);
53                    } else {
54                    #endif
55                        name->setDefinition(makeCC(UCD::resolveUnicodeSet(name)));
56                    #ifndef DISABLE_PREGENERATED_UCD_FUNCTIONS
57                    }
58                    #endif
59                }
60            } else {
61            throw std::runtime_error("All non-unicode-property Name objects should have been defined prior to Unicode property resolution.");
62            }
63        } else {
64            return *f;
65        }
66    } else if (Seq * seq = dyn_cast<Seq>(re)) {
67        for (auto si = seq->begin(); si != seq->end(); ++si) {
68            *si = resolve(*si);
69        }
70    } else if (Alt * alt = dyn_cast<Alt>(re)) {
71        CC * unionCC = nullptr;
72        std::stringstream name;
73        for (auto ai = alt->begin(); ai != alt->end(); ) {
74            RE * re = resolve(*ai);
75            if (CC * cc = getDefinitionIfCC(re)) {
76                if (unionCC == nullptr) {
77                    unionCC = cc;
78                } else {
79                    unionCC = makeCC(unionCC, cc);
80                    name << '+';
81                }
82                Name * n = cast<Name>(re);
83                if (n->hasNamespace()) {
84                    name << n->getNamespace() << ':';
85                }
86                name << n->getName();
87                ai = alt->erase(ai);
88            } else {
89                *ai++ = re;
90            }
91        }
92        if (unionCC) {
93            alt->push_back(makeName(name.str(), unionCC));
94        }
95        if (alt->size() == 1) {
96            return alt->front();
97        }
98    } else if (Rep * rep = dyn_cast<Rep>(re)) {
99        rep->setRE(resolve(rep->getRE()));
100    } else if (Assertion * a = dyn_cast<Assertion>(re)) {
101        a->setAsserted(resolve(a->getAsserted()));
102    } else if (Diff * diff = dyn_cast<Diff>(re)) {
103        diff->setLH(resolve(diff->getLH()));
104        diff->setRH(resolve(diff->getRH()));
105        CC * lh = getDefinitionIfCC(diff->getLH());
106        CC * rh = getDefinitionIfCC(diff->getRH());
107        if (lh && rh) {
108            return resolve(makeName("diff", subtractCC(lh, rh)));
109        }
110    } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
111        ix->setLH(resolve(ix->getLH()));
112        ix->setRH(resolve(ix->getRH()));
113        CC * lh = getDefinitionIfCC(ix->getLH());
114        CC * rh = getDefinitionIfCC(ix->getRH());
115        if (lh && rh) {
116            return resolve(makeName("intersect", intersectCC(lh, rh)));
117        }
118    }
119    return re;
120}
121
122UCD::UCDCompiler::NameMap nameMap;
123std::unordered_set<Name *> visited;
124   
125void gather(RE * re) {
126    assert ("RE object cannot be null!" && re);
127    if (isa<Name>(re)) {
128        if (visited.insert(cast<Name>(re)).second) {
129            if (isa<CC>(cast<Name>(re)->getDefinition())) {
130                nameMap.emplace(cast<Name>(re), nullptr);
131            } else {
132                gather(cast<Name>(re)->getDefinition());
133            }
134        }
135    } else if (isa<Seq>(re)) {
136        for (RE * item : *cast<Seq>(re)) {
137            gather(item);
138        }
139    } else if (isa<Alt>(re)) {
140        for (RE * item : *cast<Alt>(re)) {
141            gather(item);
142        }
143    } else if (isa<Rep>(re)) {
144        gather(cast<Rep>(re)->getRE());
145    } else if (isa<Assertion>(re)) {
146        gather(cast<Assertion>(re)->getAsserted());
147    } else if (isa<Diff>(re)) {
148        gather(cast<Diff>(re)->getLH());
149        gather(cast<Diff>(re)->getRH());
150    } else if (isa<Intersect>(re)) {
151        gather(cast<Intersect>(re)->getLH());
152        gather(cast<Intersect>(re)->getRH());
153    } 
154}
155   
156UCD::UCDCompiler::NameMap resolveNames(RE * &re, Name * &zerowidth) {
157
158    ZeroWidth = nullptr;
159    re = resolve(re);
160    gather(re);
161    zerowidth = ZeroWidth;
162   
163    return nameMap;
164   
165}
166
167}
Note: See TracBrowser for help on using the repository browser.