source: icGREP/icgrep-devel/icgrep/re/re_multiplex.cpp

Last change on this file was 5728, checked in by cameron, 13 days ago

The re::Any type now maps to a CC

File size: 4.2 KB
Line 
1#include "re_multiplex.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_diff.h>
8#include <re/re_intersect.h>
9#include <re/re_assertion.h>
10#include <re/re_analysis.h>
11#include <re/re_memoizer.hpp>
12#include <UCD/ucd_compiler.hpp>
13#include <UCD/resolve_properties.h>
14#include <boost/container/flat_set.hpp>
15#include <cc/multiplex_CCs.h>
16#include <sstream>
17#include <iostream>
18#include <functional>
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
34RE * multiplex(RE * const re,
35               const std::vector<UCD::UnicodeSet> & UnicodeSets,
36               const std::vector<std::vector<unsigned>> & exclusiveSetIDs) {
37
38    Memoizer memoizer;
39
40    std::function<RE *(RE *)> multiplex = [&](RE * const re) -> RE * {
41        if (Name * name = dyn_cast<Name>(re)) {
42            auto f = memoizer.find(name);
43            if (f == memoizer.end()) {
44                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
45                    if (CC * cc = dyn_cast<CC>(name->getDefinition())) {
46                        UCD::UnicodeSet * sets = cast<UCD::UnicodeSet>(cc);
47                        auto index = find(UnicodeSets.begin(), UnicodeSets.end(), *sets) - UnicodeSets.begin();
48                        auto exclusive_IDs = exclusiveSetIDs[index];
49                        CC * CC_union = makeCC();
50                        for (auto i : exclusive_IDs) {
51                            CC_union = makeCC(CC_union, makeCC(i));
52                        }
53                        name->setDefinition(CC_union);
54                    } else {
55                        multiplex(name->getDefinition());
56                    }
57                } else {
58                    throw std::runtime_error("All non-unicode-property Name objects should have been defined prior to Unicode property resolution.");
59                }
60                return memoizer.memoize(name);
61            } else {
62                return *f;
63            }
64        } else if (Seq * seq = dyn_cast<Seq>(re)) {
65            for (auto si = seq->begin(); si != seq->end(); ++si) {
66                *si = multiplex(*si);
67            }
68        } else if (Alt * alt = dyn_cast<Alt>(re)) {
69            CC * unionCC = nullptr;
70            std::stringstream name;
71            for (auto ai = alt->begin(); ai != alt->end(); ) {
72                RE * re = multiplex(*ai);
73                if (CC * cc = extractCC(re)) {
74                    if (unionCC == nullptr) {
75                        unionCC = cc;
76                    } else {
77                        unionCC = makeCC(unionCC, cc);
78                        name << '+';
79                    }
80                    if (LLVM_LIKELY(isa<Name>(re))) {
81                        Name * n = cast<Name>(re);
82                        if (n->hasNamespace()) {
83                            name << n->getNamespace() << ':';
84                        }
85                        name << n->getName();
86                    } else if (isa<CC>(re)) {
87                        name << cast<CC>(re)->canonicalName(UnicodeClass);
88                    }
89                    ai = alt->erase(ai);
90                } else {
91                    *ai++ = re;
92                }
93            }
94            if (unionCC) {
95                alt->push_back(multiplex(makeName(name.str(), unionCC)));
96            }
97            if (alt->size() == 1) {
98                return alt->front();
99            }
100        } else if (Rep * rep = dyn_cast<Rep>(re)) {
101            rep->setRE(multiplex(rep->getRE()));
102        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
103            a->setAsserted(multiplex(a->getAsserted()));
104        } else if (Diff * diff = dyn_cast<Diff>(re)) {
105            diff->setLH(multiplex(diff->getLH()));
106            diff->setRH(multiplex(diff->getRH()));
107        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
108            ix->setLH(multiplex(ix->getLH()));
109            ix->setRH(multiplex(ix->getRH()));
110        }
111        return re;
112    };
113
114    return multiplex(re);
115}   
116
117}
Note: See TracBrowser for help on using the repository browser.