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

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

Small fixes

File size: 4.5 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<const CC *> & 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 (CC * cc = dyn_cast<CC>(re)) {
42            const auto index = find(UnicodeSets.begin(), UnicodeSets.end(), cc) - UnicodeSets.begin();
43            const auto exclusive_IDs = exclusiveSetIDs[index];
44            CC * CC_union = makeCC();
45            for (auto i : exclusive_IDs) {
46                CC_union = makeCC(CC_union, makeCC(i));
47            }
48            return CC_union;
49        } else if (Name * name = dyn_cast<Name>(re)) {
50            auto f = memoizer.find(name);
51            if (f == memoizer.end()) {
52                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
53                    if (CC * cc = dyn_cast<CC>(name->getDefinition())) {
54                        const auto index = find(UnicodeSets.begin(), UnicodeSets.end(), cc) - UnicodeSets.begin();
55                        const auto exclusive_IDs = exclusiveSetIDs[index];
56                        CC * CC_union = makeCC();
57                        for (auto i : exclusive_IDs) {
58                            CC_union = makeCC(CC_union, makeCC(i));
59                        }
60                        name->setDefinition(CC_union);
61                    } else {
62                        multiplex(name->getDefinition());
63                    }
64                } else {
65                    throw std::runtime_error("All non-unicode-property Name objects should have been defined prior to Unicode property resolution.");
66                }
67                return memoizer.memoize(name);
68            } else {
69                return *f;
70            }
71        } else if (Seq * seq = dyn_cast<Seq>(re)) {
72            for (auto si = seq->begin(); si != seq->end(); ++si) {
73                *si = multiplex(*si);
74            }
75        } else if (Alt * alt = dyn_cast<Alt>(re)) {
76            CC * unionCC = nullptr;
77            std::stringstream name;
78            for (auto ai = alt->begin(); ai != alt->end(); ) {
79                RE * re = multiplex(*ai);
80                if (CC * cc = extractCC(re)) {
81                    if (unionCC == nullptr) {
82                        unionCC = cc;
83                    } else {
84                        unionCC = makeCC(unionCC, cc);
85                        name << '+';
86                    }
87                    if (LLVM_LIKELY(isa<Name>(re))) {
88                        Name * n = cast<Name>(re);
89                        if (n->hasNamespace()) {
90                            name << n->getNamespace() << ':';
91                        }
92                        name << n->getName();
93                    } else if (isa<CC>(re)) {
94                        name << cast<CC>(re)->canonicalName(CC_type::UnicodeClass);
95                    }
96                    ai = alt->erase(ai);
97                } else {
98                    *ai++ = re;
99                }
100            }
101            if (unionCC) {
102                alt->push_back(multiplex(makeName(name.str(), unionCC)));
103            }
104            if (alt->size() == 1) {
105                return alt->front();
106            }
107        } else if (Rep * rep = dyn_cast<Rep>(re)) {
108            rep->setRE(multiplex(rep->getRE()));
109        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
110            a->setAsserted(multiplex(a->getAsserted()));
111        } else if (Diff * diff = dyn_cast<Diff>(re)) {
112            diff->setLH(multiplex(diff->getLH()));
113            diff->setRH(multiplex(diff->getRH()));
114        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
115            ix->setLH(multiplex(ix->getLH()));
116            ix->setRH(multiplex(ix->getRH()));
117        }
118        return re;
119    };
120
121    return multiplex(re);
122}   
123
124}
Note: See TracBrowser for help on using the repository browser.