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

Last change on this file was 5911, checked in by nmedfort, 3 months ago

Warning removal

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