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

Last change on this file since 5781 was 5781, checked in by cameron, 16 months ago

Small fixes

File size: 4.0 KB
RevLine 
[5769]1#include <re/re_re.h>
[5267]2#include "re_name_resolve.h"
[5083]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>
[5763]8#include <re/re_range.h>
[5083]9#include <re/re_diff.h>
10#include <re/re_intersect.h>
11#include <re/re_assertion.h>
12#include <re/re_analysis.h>
[5769]13#include <re/re_group.h>
[5083]14#include <re/re_memoizer.hpp>
15#include <UCD/resolve_properties.h>
[5233]16#include <boost/container/flat_set.hpp>
[5083]17#include <sstream>
18
[5233]19using namespace boost::container;
[5267]20using namespace llvm;
[5233]21
[5083]22namespace re {
23 
[5234]24static inline CC * extractCC(RE * re) {
[5233]25    if (isa<CC>(re)) {
26        return cast<CC>(re);
27    } else if (isa<Name>(re)) {
[5234]28        return extractCC(cast<Name>(re)->getDefinition());
[5083]29    }
30    return nullptr;
31}
32
[5233]33struct NameResolver {
[5732]34    RE * resolve(RE * re) {
[5233]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)) {
[5234]42                        name->setDefinition(resolve(name->getDefinition()));
[5233]43                    } else {
[5751]44                        name->setDefinition(makeCC(UCD::resolveUnicodeSet(name)));
[5091]45                    }
[5158]46                } else {
[5234]47                    throw std::runtime_error("All non-unicode-property Name objects should have been defined prior to Unicode property resolution.");
[5158]48                }
49            } else {
[5233]50                return *f;
[5158]51            }
[5233]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(); ) {
[5646]60                RE * item = resolve(*ai);
61                if (CC * cc = extractCC(item)) {
[5233]62                    if (unionCC == nullptr) {
63                        unionCC = cc;
64                    } else {
65                        unionCC = makeCC(unionCC, cc);
66                        name << '+';
67                    }
[5646]68                    if (LLVM_LIKELY(isa<Name>(item))) {
69                        Name * n = cast<Name>(item);
[5233]70                        if (n->hasNamespace()) {
71                            name << n->getNamespace() << ':';
72                        }
73                        name << n->getName();
[5646]74                    } else if (isa<CC>(item)) {
[5781]75                        name << cast<CC>(item)->canonicalName(CC_type::UnicodeClass);
[5233]76                    }
77                    ai = alt->erase(ai);
[5158]78                } else {
[5646]79                    *ai++ = item;
[5158]80                }
81            }
[5233]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()));
[5763]92        } else if (Range * rg = dyn_cast<Range>(re)) {
93            rg->setLo(resolve(rg->getLo()));
94            rg->setHi(resolve(rg->getHi()));
[5233]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()));
[5769]101        } else if (Group * g = dyn_cast<Group>(re)) {
102            g->setRE(resolve(g->getRE()));
[5158]103        }
[5233]104        return re;
[5083]105    }
106
[5233]107private:
108    Memoizer                mMemoizer;
109};
[5083]110   
[5646]111RE * resolveNames(RE * re) {
[5565]112    NameResolver nameResolver;
113    return nameResolver.resolve(re);   
[5083]114}
115
116}
Note: See TracBrowser for help on using the repository browser.