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

Last change on this file since 5802 was 5802, checked in by cameron, 14 months ago

Allow RE compiler to handle any Unicode CCs not previously translated

File size: 5.9 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>
[5802]16#include <cc/alphabet.h>
[5233]17#include <boost/container/flat_set.hpp>
[5083]18#include <sstream>
19
[5233]20using namespace boost::container;
[5267]21using namespace llvm;
[5233]22
[5083]23namespace re {
24 
[5234]25static inline CC * extractCC(RE * re) {
[5233]26    if (isa<CC>(re)) {
27        return cast<CC>(re);
28    } else if (isa<Name>(re)) {
[5234]29        return extractCC(cast<Name>(re)->getDefinition());
[5083]30    }
31    return nullptr;
32}
33
[5233]34struct NameResolver {
[5786]35    RE * resolveUnicodeProperties(RE * re) {
[5233]36        if (Name * name = dyn_cast<Name>(re)) {
37            auto f = mMemoizer.find(name);
38            if (f == mMemoizer.end()) {
39                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
[5786]40                    name->setDefinition(resolveUnicodeProperties(name->getDefinition()));
[5233]41                } else if (LLVM_LIKELY(name->getType() == Name::Type::UnicodeProperty || name->getType() == Name::Type::ZeroWidth)) {
42                    if (UCD::resolvePropertyDefinition(name)) {
[5786]43                        name->setDefinition(resolveUnicodeProperties(name->getDefinition()));
[5233]44                    } else {
[5802]45                        name->setDefinition(makeCC(UCD::resolveUnicodeSet(name), &cc::Unicode));
[5091]46                    }
[5158]47                } else {
[5786]48                    UndefinedNameError(name);
[5158]49                }
50            } else {
[5233]51                return *f;
[5158]52            }
[5233]53        } else if (Seq * seq = dyn_cast<Seq>(re)) {
54            for (auto si = seq->begin(); si != seq->end(); ++si) {
[5786]55                *si = resolveUnicodeProperties(*si);
56            }
57        } else if (Alt * alt = dyn_cast<Alt>(re)) {
58            for (auto ai = alt->begin(); ai != alt->end(); ++ai) {
59                *ai = resolveUnicodeProperties(*ai);
60            }
61        } else if (Rep * rep = dyn_cast<Rep>(re)) {
62            rep->setRE(resolveUnicodeProperties(rep->getRE()));
63        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
64            a->setAsserted(resolveUnicodeProperties(a->getAsserted()));
65        } else if (Range * rg = dyn_cast<Range>(re)) {
66            rg->setLo(resolveUnicodeProperties(rg->getLo()));
67            rg->setHi(resolveUnicodeProperties(rg->getHi()));
68        } else if (Diff * diff = dyn_cast<Diff>(re)) {
69            diff->setLH(resolveUnicodeProperties(diff->getLH()));
70            diff->setRH(resolveUnicodeProperties(diff->getRH()));
71        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
72            ix->setLH(resolveUnicodeProperties(ix->getLH()));
73            ix->setRH(resolveUnicodeProperties(ix->getRH()));
74        } else if (Group * g = dyn_cast<Group>(re)) {
75            g->setRE(resolveUnicodeProperties(g->getRE()));
76        }
77        return re;
78    }
79   
80    RE * resolve(RE * re) {
81        if (Name * name = dyn_cast<Name>(re)) {
82            auto f = mMemoizer.find(name);
83            if (f == mMemoizer.end()) {
84                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
85                    name->setDefinition(resolve(name->getDefinition()));
86                } else {
87                    UndefinedNameError(name);
88                }
89            } else {
90                return *f;
91            }
92        } else if (Seq * seq = dyn_cast<Seq>(re)) {
93            for (auto si = seq->begin(); si != seq->end(); ++si) {
[5233]94                *si = resolve(*si);
95            }
96        } else if (Alt * alt = dyn_cast<Alt>(re)) {
97            CC * unionCC = nullptr;
98            std::stringstream name;
99            for (auto ai = alt->begin(); ai != alt->end(); ) {
[5646]100                RE * item = resolve(*ai);
101                if (CC * cc = extractCC(item)) {
[5233]102                    if (unionCC == nullptr) {
103                        unionCC = cc;
104                    } else {
105                        unionCC = makeCC(unionCC, cc);
106                        name << '+';
107                    }
[5646]108                    if (LLVM_LIKELY(isa<Name>(item))) {
109                        Name * n = cast<Name>(item);
[5233]110                        if (n->hasNamespace()) {
111                            name << n->getNamespace() << ':';
112                        }
113                        name << n->getName();
[5646]114                    } else if (isa<CC>(item)) {
[5781]115                        name << cast<CC>(item)->canonicalName(CC_type::UnicodeClass);
[5233]116                    }
117                    ai = alt->erase(ai);
[5158]118                } else {
[5646]119                    *ai++ = item;
[5158]120                }
121            }
[5233]122            if (unionCC) {
123                alt->push_back(resolve(makeName(name.str(), unionCC)));
124            }
125            if (alt->size() == 1) {
126                return alt->front();
127            }
128        } else if (Rep * rep = dyn_cast<Rep>(re)) {
129            rep->setRE(resolve(rep->getRE()));
130        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
131            a->setAsserted(resolve(a->getAsserted()));
[5763]132        } else if (Range * rg = dyn_cast<Range>(re)) {
133            rg->setLo(resolve(rg->getLo()));
134            rg->setHi(resolve(rg->getHi()));
[5233]135        } else if (Diff * diff = dyn_cast<Diff>(re)) {
136            diff->setLH(resolve(diff->getLH()));
137            diff->setRH(resolve(diff->getRH()));
138        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
139            ix->setLH(resolve(ix->getLH()));
140            ix->setRH(resolve(ix->getRH()));
[5769]141        } else if (Group * g = dyn_cast<Group>(re)) {
142            g->setRE(resolve(g->getRE()));
[5158]143        }
[5233]144        return re;
[5083]145    }
[5786]146   
[5233]147private:
148    Memoizer                mMemoizer;
149};
[5083]150   
[5786]151    RE * resolveUnicodeProperties(RE * re) {
152        NameResolver nameResolver;
153        return nameResolver.resolveUnicodeProperties(re);
154    }
155   
156    RE * resolveNames(RE * re) {
157        NameResolver nameResolver;
158        return nameResolver.resolve(re);
159    }
160   
[5083]161}
Note: See TracBrowser for help on using the repository browser.