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

Last change on this file was 5872, checked in by cameron, 2 days ago

Decoupling CC compilers from Pablo Kernel

File size: 7.1 KB
Line 
1#include <re/re_re.h>
2#include "re_name_resolve.h"
3#include <re/re_name.h>
4#include <re/re_alt.h>
5#include <re/re_cc.h>
6#include <re/re_seq.h>
7#include <re/re_rep.h>
8#include <re/re_range.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_group.h>
14#include <re/re_start.h>
15#include <re/re_end.h>
16#include <re/re_any.h>
17#include <re/re_memoizer.hpp>
18#include <UCD/resolve_properties.h>
19#include <cc/alphabet.h>
20#include <boost/container/flat_set.hpp>
21#include <sstream>
22
23using namespace boost::container;
24using namespace llvm;
25
26namespace re {
27 
28struct NameResolver {
29    RE * resolveUnicodeProperties(RE * re) {
30        if (Name * name = dyn_cast<Name>(re)) {
31            auto f = mMemoizer.find(name);
32            if (f == mMemoizer.end()) {
33                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
34                    name->setDefinition(resolveUnicodeProperties(name->getDefinition()));
35                } else if (LLVM_LIKELY(name->getType() == Name::Type::UnicodeProperty || name->getType() == Name::Type::ZeroWidth)) {
36                    if (UCD::resolvePropertyDefinition(name)) {
37                        name->setDefinition(resolveUnicodeProperties(name->getDefinition()));
38                    } else {
39                        name->setDefinition(makeCC(UCD::resolveUnicodeSet(name), &cc::Unicode));
40                    }
41                } else {
42                    UndefinedNameError(name);
43                }
44                re = mMemoizer.memoize(name);
45            } else {
46                return *f;
47            }
48        } else if (Vector * vec = dyn_cast<Vector>(re)) {
49            for (RE *& re : *vec) {
50                re = resolveUnicodeProperties(re);
51            }
52        } else if (Rep * rep = dyn_cast<Rep>(re)) {
53            rep->setRE(resolveUnicodeProperties(rep->getRE()));
54        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
55            a->setAsserted(resolveUnicodeProperties(a->getAsserted()));
56        } else if (Range * rg = dyn_cast<Range>(re)) {
57            return makeRange(resolveUnicodeProperties(rg->getLo()),
58                             resolveUnicodeProperties(rg->getHi()));
59        } else if (Diff * diff = dyn_cast<Diff>(re)) {
60            diff->setLH(resolveUnicodeProperties(diff->getLH()));
61            diff->setRH(resolveUnicodeProperties(diff->getRH()));
62        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
63            ix->setLH(resolveUnicodeProperties(ix->getLH()));
64            ix->setRH(resolveUnicodeProperties(ix->getRH()));
65        } else if (Group * g = dyn_cast<Group>(re)) {
66            g->setRE(resolveUnicodeProperties(g->getRE()));
67        }
68        return re;
69    }
70   
71    RE * resolve(RE * re) {
72        if (Name * name = dyn_cast<Name>(re)) {
73            auto f = mMemoizer.find(name);
74            if (f == mMemoizer.end()) {
75                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
76                    name->setDefinition(resolve(name->getDefinition()));
77                } else {
78                    UndefinedNameError(name);
79                }
80                re = mMemoizer.memoize(name);
81            } else {
82                return *f;
83            }
84        } else if (Vector * vec = dyn_cast<Vector>(re)) {
85            for (RE *& re : *vec) {
86                re = resolve(re);
87            }
88        } else if (Rep * rep = dyn_cast<Rep>(re)) {
89            rep->setRE(resolve(rep->getRE()));
90        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
91            a->setAsserted(resolve(a->getAsserted()));
92        } else if (Range * rg = dyn_cast<Range>(re)) {
93            return makeRange(resolve(rg->getLo()), resolve(rg->getHi()));
94        } else if (Diff * diff = dyn_cast<Diff>(re)) {
95            diff->setLH(resolve(diff->getLH()));
96            diff->setRH(resolve(diff->getRH()));
97        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
98            ix->setLH(resolve(ix->getLH()));
99            ix->setRH(resolve(ix->getRH()));
100        } else if (Group * g = dyn_cast<Group>(re)) {
101            g->setRE(resolve(g->getRE()));
102        }
103        return re;
104    }
105   
106private:
107    Memoizer                mMemoizer;
108};
109   
110    RE * resolveUnicodeProperties(RE * re) {
111        NameResolver nameResolver;
112        return nameResolver.resolveUnicodeProperties(re);
113    }
114   
115    RE * resolveNames(RE * re) {
116        NameResolver nameResolver;
117        return nameResolver.resolve(re);
118    }
119   
120   
121   
122bool hasAnchor(const RE * re) {
123    if (const Alt * alt = dyn_cast<Alt>(re)) {
124        for (const RE * re : *alt) {
125            if (hasAnchor(re)) {
126                return true;
127            }
128        }
129        return false;
130    } else if (const Seq * seq = dyn_cast<Seq>(re)) {
131        for (const RE * re : *seq) {
132            if (hasAnchor(re)) {
133                return true;
134            }
135        }
136        return false;
137    } else if (const Rep * rep = dyn_cast<Rep>(re)) {
138        return hasAnchor(rep->getRE());
139    } else if (isa<Start>(re)) {
140        return true;
141    } else if (isa<End>(re)) {
142        return true;
143    } else if (const Assertion * a = dyn_cast<Assertion>(re)) {
144        return hasAnchor(a->getAsserted());
145    } else if (const Diff * diff = dyn_cast<Diff>(re)) {
146        return hasAnchor(diff->getLH()) || hasAnchor(diff->getRH());
147    } else if (const Intersect * e = dyn_cast<Intersect>(re)) {
148        return hasAnchor(e->getLH()) || hasAnchor(e->getRH());
149    } else if (isa<Any>(re)) {
150        return false;
151    } else if (isa<CC>(re)) {
152        return false;
153    } else if (const Group * g = dyn_cast<Group>(re)) {
154        return hasAnchor(g->getRE());
155    } else if (const Name * n = dyn_cast<Name>(re)) {
156        return hasAnchor(n->getDefinition());
157    }
158    return false; // otherwise
159}
160
161RE * resolveAnchors(RE * r, RE * breakRE) {
162    if (!hasAnchor(r)) return r;
163    if (const Alt * alt = dyn_cast<Alt>(r)) {
164        std::vector<RE *> list;
165        list.reserve(alt->size());
166        for (RE * item : *alt) {
167            item = resolveAnchors(item, breakRE);
168            list.push_back(item);
169        }
170        return makeAlt(list.begin(), list.end());
171    } else if (const Seq * seq = dyn_cast<Seq>(r)) {
172        std::vector<RE *> list;
173        list.reserve(seq->size());
174        for (RE * item : *seq) {
175            item = resolveAnchors(item, breakRE);
176            list.push_back(item);
177        }
178        return makeSeq(list.begin(), list.end());
179    } else if (Assertion * a = dyn_cast<Assertion>(r)) {
180        return makeAssertion(resolveAnchors(a->getAsserted(), breakRE), a->getKind(), a->getSense());
181    } else if (Rep * rep = dyn_cast<Rep>(r)) {
182        return makeRep(resolveAnchors(rep->getRE(), breakRE), rep->getLB(), rep->getUB());
183    } else if (Diff * diff = dyn_cast<Diff>(r)) {
184        return makeDiff(resolveAnchors(diff->getLH(), breakRE), resolveAnchors(diff->getRH(), breakRE));
185    } else if (Intersect * e = dyn_cast<Intersect>(r)) {
186        return makeIntersect(resolveAnchors(e->getLH(), breakRE), resolveAnchors(e->getRH(), breakRE));
187    } else if (isa<Start>(r)) {
188        return makeAlt({r, makeLookBehindAssertion(breakRE)});
189    } else if (isa<End>(r)) {
190        return makeAlt({r, makeLookAheadAssertion(breakRE)});
191    }
192}
193}
Note: See TracBrowser for help on using the repository browser.