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

Last change on this file since 5786 was 5786, checked in by cameron, 13 months ago

Decouple Unicode property support from re_compiler; initial support for (?-m) flag

File size: 5.9 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_memoizer.hpp>
15#include <UCD/resolve_properties.h>
16#include <boost/container/flat_set.hpp>
17#include <sstream>
18
19using namespace boost::container;
20using namespace llvm;
21
22namespace re {
23 
24static inline CC * extractCC(RE * re) {
25    if (isa<CC>(re)) {
26        return cast<CC>(re);
27    } else if (isa<Name>(re)) {
28        return extractCC(cast<Name>(re)->getDefinition());
29    }
30    return nullptr;
31}
32
33struct NameResolver {
34    RE * resolveUnicodeProperties(RE * re) {
35        if (Name * name = dyn_cast<Name>(re)) {
36            auto f = mMemoizer.find(name);
37            if (f == mMemoizer.end()) {
38                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
39                    name->setDefinition(resolveUnicodeProperties(name->getDefinition()));
40                } else if (LLVM_LIKELY(name->getType() == Name::Type::UnicodeProperty || name->getType() == Name::Type::ZeroWidth)) {
41                    if (UCD::resolvePropertyDefinition(name)) {
42                        name->setDefinition(resolveUnicodeProperties(name->getDefinition()));
43                    } else {
44                        name->setDefinition(makeCC(UCD::resolveUnicodeSet(name)));
45                    }
46                } else {
47                    UndefinedNameError(name);
48                }
49            } else {
50                return *f;
51            }
52        } else if (Seq * seq = dyn_cast<Seq>(re)) {
53            for (auto si = seq->begin(); si != seq->end(); ++si) {
54                *si = resolveUnicodeProperties(*si);
55            }
56        } else if (Alt * alt = dyn_cast<Alt>(re)) {
57            for (auto ai = alt->begin(); ai != alt->end(); ++ai) {
58                *ai = resolveUnicodeProperties(*ai);
59            }
60        } else if (Rep * rep = dyn_cast<Rep>(re)) {
61            rep->setRE(resolveUnicodeProperties(rep->getRE()));
62        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
63            a->setAsserted(resolveUnicodeProperties(a->getAsserted()));
64        } else if (Range * rg = dyn_cast<Range>(re)) {
65            rg->setLo(resolveUnicodeProperties(rg->getLo()));
66            rg->setHi(resolveUnicodeProperties(rg->getHi()));
67        } else if (Diff * diff = dyn_cast<Diff>(re)) {
68            diff->setLH(resolveUnicodeProperties(diff->getLH()));
69            diff->setRH(resolveUnicodeProperties(diff->getRH()));
70        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
71            ix->setLH(resolveUnicodeProperties(ix->getLH()));
72            ix->setRH(resolveUnicodeProperties(ix->getRH()));
73        } else if (Group * g = dyn_cast<Group>(re)) {
74            g->setRE(resolveUnicodeProperties(g->getRE()));
75        }
76        return re;
77    }
78   
79    RE * resolve(RE * re) {
80        if (Name * name = dyn_cast<Name>(re)) {
81            auto f = mMemoizer.find(name);
82            if (f == mMemoizer.end()) {
83                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
84                    name->setDefinition(resolve(name->getDefinition()));
85                } else {
86                    UndefinedNameError(name);
87                }
88            } else {
89                return *f;
90            }
91        } else if (Seq * seq = dyn_cast<Seq>(re)) {
92            for (auto si = seq->begin(); si != seq->end(); ++si) {
93                *si = resolve(*si);
94            }
95        } else if (Alt * alt = dyn_cast<Alt>(re)) {
96            CC * unionCC = nullptr;
97            std::stringstream name;
98            for (auto ai = alt->begin(); ai != alt->end(); ) {
99                RE * item = resolve(*ai);
100                if (CC * cc = extractCC(item)) {
101                    if (unionCC == nullptr) {
102                        unionCC = cc;
103                    } else {
104                        unionCC = makeCC(unionCC, cc);
105                        name << '+';
106                    }
107                    if (LLVM_LIKELY(isa<Name>(item))) {
108                        Name * n = cast<Name>(item);
109                        if (n->hasNamespace()) {
110                            name << n->getNamespace() << ':';
111                        }
112                        name << n->getName();
113                    } else if (isa<CC>(item)) {
114                        name << cast<CC>(item)->canonicalName(CC_type::UnicodeClass);
115                    }
116                    ai = alt->erase(ai);
117                } else {
118                    *ai++ = item;
119                }
120            }
121            if (unionCC) {
122                alt->push_back(resolve(makeName(name.str(), unionCC)));
123            }
124            if (alt->size() == 1) {
125                return alt->front();
126            }
127        } else if (Rep * rep = dyn_cast<Rep>(re)) {
128            rep->setRE(resolve(rep->getRE()));
129        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
130            a->setAsserted(resolve(a->getAsserted()));
131        } else if (Range * rg = dyn_cast<Range>(re)) {
132            rg->setLo(resolve(rg->getLo()));
133            rg->setHi(resolve(rg->getHi()));
134        } else if (Diff * diff = dyn_cast<Diff>(re)) {
135            diff->setLH(resolve(diff->getLH()));
136            diff->setRH(resolve(diff->getRH()));
137        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
138            ix->setLH(resolve(ix->getLH()));
139            ix->setRH(resolve(ix->getRH()));
140        } else if (Group * g = dyn_cast<Group>(re)) {
141            g->setRE(resolve(g->getRE()));
142        }
143        return re;
144    }
145   
146private:
147    Memoizer                mMemoizer;
148};
149   
150    RE * resolveUnicodeProperties(RE * re) {
151        NameResolver nameResolver;
152        return nameResolver.resolveUnicodeProperties(re);
153    }
154   
155    RE * resolveNames(RE * re) {
156        NameResolver nameResolver;
157        return nameResolver.resolve(re);
158    }
159   
160}
Note: See TracBrowser for help on using the repository browser.