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

Last change on this file since 5763 was 5763, checked in by cameron, 19 months ago

Range RE objects

File size: 3.9 KB
Line 
1#include "re_name_resolve.h"
2#include <re/re_name.h>
3#include <re/re_alt.h>
4#include <re/re_cc.h>
5#include <re/re_seq.h>
6#include <re/re_rep.h>
7#include <re/re_range.h>
8#include <re/re_diff.h>
9#include <re/re_intersect.h>
10#include <re/re_assertion.h>
11#include <re/re_analysis.h>
12#include <re/re_memoizer.hpp>
13#include <UCD/ucd_compiler.hpp>
14#include <UCD/resolve_properties.h>
15#include <boost/container/flat_set.hpp>
16#include <sstream>
17
18using namespace boost::container;
19using namespace llvm;
20
21namespace re {
22 
23static inline CC * extractCC(RE * re) {
24    if (isa<CC>(re)) {
25        return cast<CC>(re);
26    } else if (isa<Name>(re)) {
27        return extractCC(cast<Name>(re)->getDefinition());
28    }
29    return nullptr;
30}
31
32struct NameResolver {
33    RE * resolve(RE * re) {
34        if (Name * name = dyn_cast<Name>(re)) {
35            auto f = mMemoizer.find(name);
36            if (f == mMemoizer.end()) {
37                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
38                    name->setDefinition(resolve(name->getDefinition()));
39                } else if (LLVM_LIKELY(name->getType() == Name::Type::UnicodeProperty || name->getType() == Name::Type::ZeroWidth)) {
40                    if (UCD::resolvePropertyDefinition(name)) {
41                        name->setDefinition(resolve(name->getDefinition()));
42                    } else {
43                        name->setDefinition(makeCC(UCD::resolveUnicodeSet(name)));
44                    }
45                } else {
46                    throw std::runtime_error("All non-unicode-property Name objects should have been defined prior to Unicode property resolution.");
47                }
48            } else {
49                return *f;
50            }
51        } else if (Seq * seq = dyn_cast<Seq>(re)) {
52            for (auto si = seq->begin(); si != seq->end(); ++si) {
53                *si = resolve(*si);
54            }
55        } else if (Alt * alt = dyn_cast<Alt>(re)) {
56            CC * unionCC = nullptr;
57            std::stringstream name;
58            for (auto ai = alt->begin(); ai != alt->end(); ) {
59                RE * item = resolve(*ai);
60                if (CC * cc = extractCC(item)) {
61                    if (unionCC == nullptr) {
62                        unionCC = cc;
63                    } else {
64                        unionCC = makeCC(unionCC, cc);
65                        name << '+';
66                    }
67                    if (LLVM_LIKELY(isa<Name>(item))) {
68                        Name * n = cast<Name>(item);
69                        if (n->hasNamespace()) {
70                            name << n->getNamespace() << ':';
71                        }
72                        name << n->getName();
73                    } else if (isa<CC>(item)) {
74                        name << cast<CC>(item)->canonicalName(UnicodeClass);
75                    }
76                    ai = alt->erase(ai);
77                } else {
78                    *ai++ = item;
79                }
80            }
81            if (unionCC) {
82                alt->push_back(resolve(makeName(name.str(), unionCC)));
83            }
84            if (alt->size() == 1) {
85                return alt->front();
86            }
87        } else if (Rep * rep = dyn_cast<Rep>(re)) {
88            rep->setRE(resolve(rep->getRE()));
89        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
90            a->setAsserted(resolve(a->getAsserted()));
91        } else if (Range * rg = dyn_cast<Range>(re)) {
92            rg->setLo(resolve(rg->getLo()));
93            rg->setHi(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        }
101        return re;
102    }
103
104private:
105    Memoizer                mMemoizer;
106};
107   
108RE * resolveNames(RE * re) {
109    NameResolver nameResolver;
110    return nameResolver.resolve(re);   
111}
112
113}
Note: See TracBrowser for help on using the repository browser.