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

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

Regular expression toolchain progress

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