source: icGREP/icgrep-devel/icgrep/re/re_name.h @ 5805

Last change on this file since 5805 was 5805, checked in by cameron, 19 months ago

Name::Type::Byte removed in favor of cc::Byte alphabet; other cleanups

File size: 5.5 KB
RevLine 
[3917]1#ifndef RE_NAME_H
2#define RE_NAME_H
3
[4246]4#include <re/re_re.h>
[4335]5#include <re/re_cc.h>
[5267]6#include <llvm/Support/Casting.h>
[3917]7
[4808]8namespace UCD {
9    class UnicodeSet;
10}
[4246]11
[4194]12namespace re {
13
14class Name : public RE {
[3917]15public:
[4194]16    static inline bool classof(const RE * re) {
17        return re->getClassTypeId() == ClassTypeId::Name;
18    }
19    static inline bool classof(const void *) {
20        return false;
21    }
[4516]22    using length_t = std::string::size_type;
[4194]23    enum class Type {
[5805]24        Unicode
[4377]25        , UnicodeProperty
[5080]26        , Capture
27        , Reference
[5091]28        , ZeroWidth
[4335]29        , Unknown
[4194]30    };
[4516]31    std::string getNamespace() const;
[4809]32    bool hasNamespace() const;
[4516]33    std::string getName() const;
[4182]34    Type getType() const;
[4808]35    RE * getDefinition() const;
[4819]36    bool operator<(const Name & other) const;
37    bool operator<(const CC & other) const;
[4823]38    bool operator>(const CC & other) const;
[4818]39    void setDefinition(RE * definition);
[4194]40    virtual ~Name() {}
41protected:
[4823]42    friend Name * makeName(const std::string & name, RE * cc);
[5080]43    friend Name * makeCapture(const std::string & name, RE * captured);
44    friend Name * makeReference(const std::string & name, RE * captureName);
[5091]45    friend Name * makeZeroWidth(const std::string & name, RE * zerowidth);
[4823]46    friend Name * makeName(CC * const cc);
[5202]47    friend Name * makeName(const std::string &, Type);
48    friend Name * makeName(const std::string &, const std::string &, Type);
49    Name(const char * nameSpace, const length_t namespaceLength, const char * name, const length_t nameLength, Type type, RE * defn)
[4249]50    : RE(ClassTypeId::Name)
[4516]51    , mNamespaceLength(namespaceLength)
52    , mNamespace(replicateString(nameSpace, namespaceLength))
53    , mNameLength(nameLength)
54    , mName(replicateString(name, nameLength))
[4249]55    , mType(type)
[5234]56    , mDefinition(defn) {
[4249]57
58    }
[4516]59    inline const char * replicateString(const char * string, const length_t length) {
[5781]60        if (string && (length > 0)) {
[4516]61            char * allocated = reinterpret_cast<char*>(mAllocator.allocate(length));
62            std::memcpy(allocated, string, length);
[5781]63            return allocated;
[4516]64        }
[5781]65        return nullptr;
[4516]66    }
[4249]67
[3917]68private:
[4660]69    const length_t      mNamespaceLength;
70    const char * const  mNamespace;
71    const length_t      mNameLength;
72    const char * const  mName;
[5233]73    Type                mType;
[4818]74    RE *                mDefinition;
[3917]75};
76
[4516]77inline std::string Name::getNamespace() const {
78    return std::string(mNamespace, mNamespaceLength);
[4377]79}
80
[4809]81inline bool Name::hasNamespace() const {
82    return (mNamespaceLength != 0);
83}
84
[4516]85inline std::string Name::getName() const {
86    return std::string(mName, mNameLength);
87}
[4380]88   
[4246]89inline Name::Type Name::getType() const {
90    return mType;
[4194]91}
92
[4336]93inline RE * Name::getDefinition() const {
[4818]94    return mDefinition;
[4194]95}
96
[4818]97inline void Name::setDefinition(RE * definition) {
[5634]98    assert (definition != nullptr);
[4818]99    assert (definition != this);
100    mDefinition = definition;
[4194]101}
102
[4819]103inline bool Name::operator < (const Name & other) const {
[5267]104    if (LLVM_LIKELY(mDefinition && other.mDefinition && llvm::isa<CC>(mDefinition) && llvm::isa<CC>(other.mDefinition))) {
105        return *llvm::cast<CC>(mDefinition) < *llvm::cast<CC>(other.mDefinition);
[4819]106    } else if (mNamespaceLength < other.mNamespaceLength) {
107        return true;
108    } else if (mNamespaceLength > other.mNamespaceLength) {
109        return false;
110    } else if (mNameLength < other.mNameLength) {
111        return true;
112    } else if (mNameLength > other.mNameLength) {
113        return false;
114    }
115    const auto diff = std::memcmp(mNamespace, other.mNamespace, mNamespaceLength);
116    if (diff < 0) {
117        return true;
118    } else if (diff > 0) {
119        return false;
120    }
121    return (std::memcmp(mName, other.mName, mNameLength) < 0);
122}
123
124inline bool Name::operator < (const CC & other) const {
[5267]125    if (mDefinition && llvm::isa<CC>(mDefinition)) {
126        return *llvm::cast<CC>(mDefinition) < other;
[4819]127    }
[5630]128    return RE::ClassTypeId::Name < RE::ClassTypeId::CC;
[4819]129}
130
[4823]131inline bool Name::operator > (const CC & other) const {
[5267]132    if (mDefinition && llvm::isa<CC>(mDefinition)) {
133        return other < *llvm::cast<CC>(mDefinition);
[4823]134    }
[5630]135    return RE::ClassTypeId::CC < RE::ClassTypeId::Name;
[4823]136}
137
[4660]138inline Name * makeName(const std::string & name, const Name::Type type) {
[4516]139    return new Name(nullptr, 0, name.c_str(), name.length(), type, nullptr);
[4194]140}
141
[4660]142inline Name * makeName(const std::string & property, const std::string & value, const Name::Type type) {
[4516]143    return new Name(property.c_str(), property.length(), value.c_str(), value.length(),  type, nullptr);
[4377]144}
145
[4516]146inline Name * makeName(const std::string & name, RE * cc) {
[5267]147    if (llvm::isa<Name>(cc)) {
148        return llvm::cast<Name>(cc);
[4249]149    }
[5267]150    else if (llvm::isa<CC>(cc)) {
[5805]151        return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Unicode, cc);
[4335]152    }
[4516]153    else return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Unknown, cc);
[4194]154}
155
[4823]156inline Name * makeName(CC * const cc) {
[5805]157    const std::string name = cc->canonicalName(CC_type::UnicodeClass);
158    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Unicode, cc);
[4194]159}
160
[5797]161inline Name * makeCapture(const std::string & name, RE * captured) {
[5080]162    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Capture, captured);
[4823]163}
[5080]164   
165inline Name * makeReference(const std::string & name, RE * captureName) {
166    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::Reference, captureName);
167}
[4823]168
[5091]169inline Name * makeZeroWidth(const std::string & name, RE * zerowidth = NULL) {
170    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::ZeroWidth, zerowidth);
[5080]171}
[5091]172}
[5080]173
[3917]174#endif // RE_NAME_H
Note: See TracBrowser for help on using the repository browser.