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

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

Generic RE_Transformer

File size: 8.2 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_utility.h>
18#include <re/re_memoizer.hpp>
19#include <UCD/resolve_properties.h>
20#include <cc/alphabet.h>
21#include <boost/container/flat_set.hpp>
22#include <llvm/Support/ErrorHandling.h>
23
24
25using namespace boost::container;
26using namespace llvm;
27
28namespace re {
29 
30struct NameResolver {
31    RE * resolveUnicodeProperties(RE * re) {
32        if (Name * name = dyn_cast<Name>(re)) {
33            auto f = mMemoizer.find(name);
34            if (f == mMemoizer.end()) {
35                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
36                    name->setDefinition(resolveUnicodeProperties(name->getDefinition()));
37                } else if (LLVM_LIKELY(name->getType() == Name::Type::UnicodeProperty || name->getType() == Name::Type::ZeroWidth)) {
38                    if (UCD::resolvePropertyDefinition(name)) {
39                        name->setDefinition(resolveUnicodeProperties(name->getDefinition()));
40                    } else {
41                        name->setDefinition(makeCC(UCD::resolveUnicodeSet(name), &cc::Unicode));
42                    }
43                } else {
44                    UndefinedNameError(name);
45                }
46                re = mMemoizer.memoize(name);
47            } else {
48                return *f;
49            }
50        } else if (Vector * vec = dyn_cast<Vector>(re)) {
51            for (RE *& re : *vec) {
52                re = resolveUnicodeProperties(re);
53            }
54        } else if (Rep * rep = dyn_cast<Rep>(re)) {
55            rep->setRE(resolveUnicodeProperties(rep->getRE()));
56        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
57            a->setAsserted(resolveUnicodeProperties(a->getAsserted()));
58        } else if (Range * rg = dyn_cast<Range>(re)) {
59            return makeRange(resolveUnicodeProperties(rg->getLo()),
60                             resolveUnicodeProperties(rg->getHi()));
61        } else if (Diff * diff = dyn_cast<Diff>(re)) {
62            diff->setLH(resolveUnicodeProperties(diff->getLH()));
63            diff->setRH(resolveUnicodeProperties(diff->getRH()));
64        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
65            ix->setLH(resolveUnicodeProperties(ix->getLH()));
66            ix->setRH(resolveUnicodeProperties(ix->getRH()));
67        } else if (Group * g = dyn_cast<Group>(re)) {
68            g->setRE(resolveUnicodeProperties(g->getRE()));
69        }
70        return re;
71    }
72   
73    RE * resolve(RE * re) {
74        if (Name * name = dyn_cast<Name>(re)) {
75            auto f = mMemoizer.find(name);
76            if (f == mMemoizer.end()) {
77                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
78                    name->setDefinition(resolve(name->getDefinition()));
79                } else {
80                    UndefinedNameError(name);
81                }
82                re = mMemoizer.memoize(name);
83            } else {
84                return *f;
85            }
86        } else if (Vector * vec = dyn_cast<Vector>(re)) {
87            for (RE *& re : *vec) {
88                re = resolve(re);
89            }
90        } else if (Rep * rep = dyn_cast<Rep>(re)) {
91            rep->setRE(resolve(rep->getRE()));
92        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
93            a->setAsserted(resolve(a->getAsserted()));
94        } else if (Range * rg = dyn_cast<Range>(re)) {
95            return makeRange(resolve(rg->getLo()), resolve(rg->getHi()));
96        } else if (Diff * diff = dyn_cast<Diff>(re)) {
97            diff->setLH(resolve(diff->getLH()));
98            diff->setRH(resolve(diff->getRH()));
99        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
100            ix->setLH(resolve(ix->getLH()));
101            ix->setRH(resolve(ix->getRH()));
102        } else if (Group * g = dyn_cast<Group>(re)) {
103            g->setRE(resolve(g->getRE()));
104        }
105        return re;
106    }
107   
108private:
109    Memoizer                mMemoizer;
110};
111   
112    RE * resolveUnicodeProperties(RE * re) {
113        NameResolver nameResolver;
114        return nameResolver.resolveUnicodeProperties(re);
115    }
116   
117    RE * resolveNames(RE * re) {
118        NameResolver nameResolver;
119        return nameResolver.resolve(re);
120    }
121   
122   
123   
124bool hasAnchor(const RE * re) {
125    if (const Alt * alt = dyn_cast<Alt>(re)) {
126        for (const RE * re : *alt) {
127            if (hasAnchor(re)) {
128                return true;
129            }
130        }
131        return false;
132    } else if (const Seq * seq = dyn_cast<Seq>(re)) {
133        for (const RE * re : *seq) {
134            if (hasAnchor(re)) {
135                return true;
136            }
137        }
138        return false;
139    } else if (const Rep * rep = dyn_cast<Rep>(re)) {
140        return hasAnchor(rep->getRE());
141    } else if (isa<Start>(re)) {
142        return true;
143    } else if (isa<End>(re)) {
144        return true;
145    } else if (const Assertion * a = dyn_cast<Assertion>(re)) {
146        return hasAnchor(a->getAsserted());
147    } else if (const Diff * diff = dyn_cast<Diff>(re)) {
148        return hasAnchor(diff->getLH()) || hasAnchor(diff->getRH());
149    } else if (const Intersect * e = dyn_cast<Intersect>(re)) {
150        return hasAnchor(e->getLH()) || hasAnchor(e->getRH());
151    } else if (isa<Any>(re)) {
152        return false;
153    } else if (isa<CC>(re)) {
154        return false;
155    } else if (const Group * g = dyn_cast<Group>(re)) {
156        return hasAnchor(g->getRE());
157    } else if (const Name * n = dyn_cast<Name>(re)) {
158        return hasAnchor(n->getDefinition());
159    }
160    return false; // otherwise
161}
162
163struct AnchorResolution {
164    RE * mAnchorRE;
165    bool mIsNegated;
166    RE * resolve(RE * r);
167};
168   
169RE * AnchorResolution::resolve(RE * r) {
170    if (hasAnchor(r)) {
171        if (const Alt * alt = dyn_cast<Alt>(r)) {
172            std::vector<RE *> list;
173            list.reserve(alt->size());
174            for (RE * item : *alt) {
175                item = resolve(item);
176                list.push_back(item);
177            }
178            return makeAlt(list.begin(), list.end());
179        } else if (const Seq * seq = dyn_cast<Seq>(r)) {
180            std::vector<RE *> list;
181            list.reserve(seq->size());
182            for (RE * item : *seq) {
183                item = resolve(item);
184                list.push_back(item);
185            }
186            return makeSeq(list.begin(), list.end());
187        } else if (Assertion * a = dyn_cast<Assertion>(r)) {
188            return makeAssertion(resolve(a->getAsserted()), a->getKind(), a->getSense());
189        } else if (Rep * rep = dyn_cast<Rep>(r)) {
190            return makeRep(resolve(rep->getRE()), rep->getLB(), rep->getUB());
191        } else if (Diff * diff = dyn_cast<Diff>(r)) {
192            return makeDiff(resolve(diff->getLH()), resolve(diff->getRH()));
193        } else if (Intersect * e = dyn_cast<Intersect>(r)) {
194            return makeIntersect(resolve(e->getLH()), resolve(e->getRH()));
195        } else if (isa<Start>(r)) {
196            if (mIsNegated) {
197                return makeNegativeLookBehindAssertion(mAnchorRE);
198            } else {
199                return makeAlt({makeSOT(), makeLookBehindAssertion(mAnchorRE)});
200            }
201        } else if (isa<End>(r)) {
202            if (mIsNegated) {
203                return makeNegativeLookAheadAssertion(mAnchorRE);
204            } else {
205                return makeAlt({makeEOT(), makeLookAheadAssertion(mAnchorRE)});
206            }
207        }
208    }
209    return r;
210}
211
212RE * resolveAnchors(RE * r, RE * breakRE) {
213    AnchorResolution a;
214    if (const CC * cc = dyn_cast<CC>(breakRE)) {
215        a.mIsNegated = true;
216        if (cc->getAlphabet() == &cc::Unicode) {
217            a.mAnchorRE = makeDiff(makeCC(0, 0x10FFFF), breakRE);
218        } else if (cc->getAlphabet() == &cc::Byte) {
219            a.mAnchorRE = makeDiff(makeByte(0, 0xFF), breakRE);
220        } else {
221            llvm::report_fatal_error("resolveAnchors: unexpected alphabet " + cc->getAlphabet()->getName());
222        }
223    } else {
224        a.mIsNegated = false;
225        a.mAnchorRE = breakRE;
226    }
227    return a.resolve(r);
228}
229                                                       
230}
Note: See TracBrowser for help on using the repository browser.