Ignore:
Timestamp:
Dec 21, 2016, 3:53:58 PM (2 years ago)
Author:
nmedfort
Message:

Bug fixes for Carry Manager and issues reported by Fahad

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/re/re_name_resolve.cpp

    r5158 r5233  
    1414#include <UCD/ucd_compiler.hpp>
    1515#include <UCD/resolve_properties.h>
    16 #include <unordered_set>
     16#include <boost/container/flat_set.hpp>
    1717#include <sstream>
     18
     19#include <re/printer_re.h>
     20#include <iostream>
     21
     22using NameMap = UCD::UCDCompiler::NameMap;
     23
     24using namespace boost::container;
    1825
    1926namespace re {
    2027 
    21 static inline CC * getDefinitionIfCC(RE * re) {
    22     if (LLVM_LIKELY(isa<Name>(re))) {
    23         Name * name = cast<Name>(re);
    24         if (name->getDefinition() && isa<CC>(name->getDefinition())) {
    25             return cast<CC>(name->getDefinition());
    26         }
     28static inline CC * getDefinition(RE * re) {
     29    if (isa<CC>(re)) {
     30        return cast<CC>(re);
     31    } else if (isa<Name>(re)) {
     32        return getDefinition(cast<Name>(re)->getDefinition());
    2733    }
    2834    return nullptr;
    2935}
    3036
    31 Name * ZeroWidth = nullptr;
     37struct NameResolver {
    3238
    33 RE * resolve(RE * re) {
    34     Memoizer memoizer;
    35     if (Name * name = dyn_cast<Name>(re)) {
    36         auto f = memoizer.find(name);
    37         if (f == memoizer.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                     if (name->getType() == Name::Type::ZeroWidth) {
    43                         ZeroWidth = name;
     39    RE * resolve(RE * re) {
     40        if (Name * name = dyn_cast<Name>(re)) {
     41            auto f = mMemoizer.find(name);
     42            if (f == mMemoizer.end()) {
     43                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
     44                    name->setDefinition(resolve(name->getDefinition()));
     45                } else if (LLVM_LIKELY(name->getType() == Name::Type::UnicodeProperty || name->getType() == Name::Type::ZeroWidth)) {
     46                    if (UCD::resolvePropertyDefinition(name)) {
     47                        if (name->getType() == Name::Type::ZeroWidth) {
     48                            mZeroWidth = name;
     49                        }
     50                        resolve(name->getDefinition());
     51                    } else {
     52                        #ifndef DISABLE_PREGENERATED_UCD_FUNCTIONS
     53                        if (AlgorithmOptionIsSet(UsePregeneratedUnicode)) {
     54                            const std::string functionName = UCD::resolvePropertyFunction(name);
     55                            const UCD::ExternalProperty & ep = UCD::resolveExternalProperty(functionName);
     56                            Call * call = mPB.createCall(Prototype::Create(functionName, std::get<1>(ep), std::get<2>(ep), std::get<0>(ep)), mCCCompiler.getBasisBits());
     57                            name->setCompiled(call);
     58                        } else {
     59                        #endif
     60                            name->setDefinition(makeCC(UCD::resolveUnicodeSet(name)));
     61                        #ifndef DISABLE_PREGENERATED_UCD_FUNCTIONS
     62                        }
     63                        #endif
    4464                    }
    45                     resolve(name->getDefinition());
    4665                } else {
    47                     #ifndef DISABLE_PREGENERATED_UCD_FUNCTIONS
    48                     if (AlgorithmOptionIsSet(UsePregeneratedUnicode)) {
    49                         const std::string functionName = UCD::resolvePropertyFunction(name);
    50                         const UCD::ExternalProperty & ep = UCD::resolveExternalProperty(functionName);
    51                         Call * call = mPB.createCall(Prototype::Create(functionName, std::get<1>(ep), std::get<2>(ep), std::get<0>(ep)), mCCCompiler.getBasisBits());
    52                         name->setCompiled(call);
    53                     } else {
    54                     #endif
    55                         name->setDefinition(makeCC(UCD::resolveUnicodeSet(name)));
    56                     #ifndef DISABLE_PREGENERATED_UCD_FUNCTIONS
    57                     }
    58                     #endif
     66                throw std::runtime_error("All non-unicode-property Name objects should have been defined prior to Unicode property resolution.");
    5967                }
    6068            } else {
    61             throw std::runtime_error("All non-unicode-property Name objects should have been defined prior to Unicode property resolution.");
     69                return *f;
    6270            }
    63         } else {
    64             return *f;
    65         }
    66     } else if (Seq * seq = dyn_cast<Seq>(re)) {
    67         for (auto si = seq->begin(); si != seq->end(); ++si) {
    68             *si = resolve(*si);
    69         }
    70     } else if (Alt * alt = dyn_cast<Alt>(re)) {
    71         CC * unionCC = nullptr;
    72         std::stringstream name;
    73         for (auto ai = alt->begin(); ai != alt->end(); ) {
    74             RE * re = resolve(*ai);
    75             if (CC * cc = getDefinitionIfCC(re)) {
    76                 if (unionCC == nullptr) {
    77                     unionCC = cc;
     71        } else if (Seq * seq = dyn_cast<Seq>(re)) {
     72            for (auto si = seq->begin(); si != seq->end(); ++si) {
     73                *si = resolve(*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 = resolve(*ai);
     80                if (CC * cc = getDefinition(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(UnicodeClass);
     95                    }
     96                    ai = alt->erase(ai);
    7897                } else {
    79                     unionCC = makeCC(unionCC, cc);
    80                     name << '+';
     98                    *ai++ = re;
    8199                }
    82                 Name * n = cast<Name>(re);
    83                 if (n->hasNamespace()) {
    84                     name << n->getNamespace() << ':';
    85                 }
    86                 name << n->getName();
    87                 ai = alt->erase(ai);
    88             } else {
    89                 *ai++ = re;
     100            }
     101            if (unionCC) {
     102                alt->push_back(resolve(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(resolve(rep->getRE()));
     109        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
     110            a->setAsserted(resolve(a->getAsserted()));
     111        } else if (Diff * diff = dyn_cast<Diff>(re)) {
     112            diff->setLH(resolve(diff->getLH()));
     113            diff->setRH(resolve(diff->getRH()));
     114            CC * lh = getDefinition(diff->getLH());
     115            CC * rh = getDefinition(diff->getRH());
     116            if (lh && rh) {
     117                return resolve(makeName("diff", subtractCC(lh, rh)));
     118            }
     119        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
     120            ix->setLH(resolve(ix->getLH()));
     121            ix->setRH(resolve(ix->getRH()));
     122            CC * lh = getDefinition(ix->getLH());
     123            CC * rh = getDefinition(ix->getRH());
     124            if (lh && rh) {
     125                return resolve(makeName("intersect", intersectCC(lh, rh)));
    90126            }
    91127        }
    92         if (unionCC) {
    93             alt->push_back(makeName(name.str(), unionCC));
    94         }
    95         if (alt->size() == 1) {
    96             return alt->front();
    97         }
    98     } else if (Rep * rep = dyn_cast<Rep>(re)) {
    99         rep->setRE(resolve(rep->getRE()));
    100     } else if (Assertion * a = dyn_cast<Assertion>(re)) {
    101         a->setAsserted(resolve(a->getAsserted()));
    102     } else if (Diff * diff = dyn_cast<Diff>(re)) {
    103         diff->setLH(resolve(diff->getLH()));
    104         diff->setRH(resolve(diff->getRH()));
    105         CC * lh = getDefinitionIfCC(diff->getLH());
    106         CC * rh = getDefinitionIfCC(diff->getRH());
    107         if (lh && rh) {
    108             return resolve(makeName("diff", subtractCC(lh, rh)));
    109         }
    110     } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
    111         ix->setLH(resolve(ix->getLH()));
    112         ix->setRH(resolve(ix->getRH()));
    113         CC * lh = getDefinitionIfCC(ix->getLH());
    114         CC * rh = getDefinitionIfCC(ix->getRH());
    115         if (lh && rh) {
    116             return resolve(makeName("intersect", intersectCC(lh, rh)));
     128        return re;
     129    }
     130
     131    void gather(RE * re) {
     132        assert ("RE object cannot be null!" && re);
     133        if (isa<Name>(re)) {
     134            if (mVisited.insert(cast<Name>(re)).second) {
     135                if (isa<CC>(cast<Name>(re)->getDefinition())) {
     136                    mNameMap.emplace(cast<Name>(re), nullptr);
     137                } else {
     138                    gather(cast<Name>(re)->getDefinition());
     139                }
     140            }
     141        } else if (isa<Seq>(re)) {
     142            for (RE * item : *cast<Seq>(re)) {
     143                gather(item);
     144            }
     145        } else if (isa<Alt>(re)) {
     146            for (RE * item : *cast<Alt>(re)) {
     147                gather(item);
     148            }
     149        } else if (isa<Rep>(re)) {
     150            gather(cast<Rep>(re)->getRE());
     151        } else if (isa<Assertion>(re)) {
     152            gather(cast<Assertion>(re)->getAsserted());
     153        } else if (isa<Diff>(re)) {
     154            gather(cast<Diff>(re)->getLH());
     155            gather(cast<Diff>(re)->getRH());
     156        } else if (isa<Intersect>(re)) {
     157            gather(cast<Intersect>(re)->getLH());
     158            gather(cast<Intersect>(re)->getRH());
    117159        }
    118160    }
    119     return re;
    120 }
    121161
    122 UCD::UCDCompiler::NameMap nameMap;
    123 std::unordered_set<Name *> visited;
     162    NameResolver(NameMap & nameMap, Name *& zeroWidth)
     163    : mZeroWidth(zeroWidth)
     164    , mNameMap(nameMap) {
     165
     166    }
     167
     168private:
     169
     170    Name *&                 mZeroWidth;
     171    NameMap &               mNameMap;
     172    Memoizer                mMemoizer;
     173    flat_set<Name *>        mVisited;
     174
     175};
    124176   
    125 void gather(RE * re) {
    126     assert ("RE object cannot be null!" && re);
    127     if (isa<Name>(re)) {
    128         if (visited.insert(cast<Name>(re)).second) {
    129             if (isa<CC>(cast<Name>(re)->getDefinition())) {
    130                 nameMap.emplace(cast<Name>(re), nullptr);
    131             } else {
    132                 gather(cast<Name>(re)->getDefinition());
    133             }
    134         }
    135     } else if (isa<Seq>(re)) {
    136         for (RE * item : *cast<Seq>(re)) {
    137             gather(item);
    138         }
    139     } else if (isa<Alt>(re)) {
    140         for (RE * item : *cast<Alt>(re)) {
    141             gather(item);
    142         }
    143     } else if (isa<Rep>(re)) {
    144         gather(cast<Rep>(re)->getRE());
    145     } else if (isa<Assertion>(re)) {
    146         gather(cast<Assertion>(re)->getAsserted());
    147     } else if (isa<Diff>(re)) {
    148         gather(cast<Diff>(re)->getLH());
    149         gather(cast<Diff>(re)->getRH());
    150     } else if (isa<Intersect>(re)) {
    151         gather(cast<Intersect>(re)->getLH());
    152         gather(cast<Intersect>(re)->getRH());
    153     }
    154 }
    155    
    156 UCD::UCDCompiler::NameMap resolveNames(RE * &re, Name * &zerowidth) {
    157 
    158     ZeroWidth = nullptr;
    159     re = resolve(re);
    160     gather(re);
    161     zerowidth = ZeroWidth;
    162    
     177NameMap resolveNames(RE *& re, Name *& zeroWidth) {
     178    NameMap nameMap;
     179    NameResolver nameResolver(nameMap, zeroWidth);
     180    re = nameResolver.resolve(re);
     181    nameResolver.gather(re);
    163182    return nameMap;
    164183   
Note: See TracChangeset for help on using the changeset viewer.