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

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

Small fixes

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