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

Last change on this file since 5769 was 5769, checked in by cameron, 17 months ago

Decoupling case-insensitive transform from parser

File size: 4.0 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 * resolve(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(resolve(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(resolve(name->getDefinition()));
43                    } else {
44                        name->setDefinition(makeCC(UCD::resolveUnicodeSet(name)));
45                    }
46                } else {
47                    throw std::runtime_error("All non-unicode-property Name objects should have been defined prior to Unicode property resolution.");
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 = resolve(*si);
55            }
56        } else if (Alt * alt = dyn_cast<Alt>(re)) {
57            CC * unionCC = nullptr;
58            std::stringstream name;
59            for (auto ai = alt->begin(); ai != alt->end(); ) {
60                RE * item = resolve(*ai);
61                if (CC * cc = extractCC(item)) {
62                    if (unionCC == nullptr) {
63                        unionCC = cc;
64                    } else {
65                        unionCC = makeCC(unionCC, cc);
66                        name << '+';
67                    }
68                    if (LLVM_LIKELY(isa<Name>(item))) {
69                        Name * n = cast<Name>(item);
70                        if (n->hasNamespace()) {
71                            name << n->getNamespace() << ':';
72                        }
73                        name << n->getName();
74                    } else if (isa<CC>(item)) {
75                        name << cast<CC>(item)->canonicalName(UnicodeClass);
76                    }
77                    ai = alt->erase(ai);
78                } else {
79                    *ai++ = item;
80                }
81            }
82            if (unionCC) {
83                alt->push_back(resolve(makeName(name.str(), unionCC)));
84            }
85            if (alt->size() == 1) {
86                return alt->front();
87            }
88        } else if (Rep * rep = dyn_cast<Rep>(re)) {
89            rep->setRE(resolve(rep->getRE()));
90        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
91            a->setAsserted(resolve(a->getAsserted()));
92        } else if (Range * rg = dyn_cast<Range>(re)) {
93            rg->setLo(resolve(rg->getLo()));
94            rg->setHi(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   
111RE * resolveNames(RE * re) {
112    NameResolver nameResolver;
113    return nameResolver.resolve(re);   
114}
115
116}
Note: See TracBrowser for help on using the repository browser.