Changeset 4809


Ignore:
Timestamp:
Sep 30, 2015, 3:18:09 PM (2 years ago)
Author:
nmedfort
Message:

Refactored UCD property resolution.

Location:
icGREP/icgrep-devel/icgrep
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/UCD/resolve_properties.cpp

    r4737 r4809  
    2828namespace UCD {
    2929
    30 Name * resolveProperty(const std::string prop, const std::string value, re::RE_Parser * parser) {
    31     auto propit = alias_map.find(prop);
    32     if (propit == alias_map.end()) {
    33         throw UnicodePropertyExpressionError("Expected a property name but '" + prop + "' was found instead");
     30RE * resolvePropertyDefinition(Name * const property) {
     31    if (property->hasNamespace()) {
     32        auto propit = alias_map.find(property->getNamespace());
     33        if (propit == alias_map.end()) {
     34            throw UnicodePropertyExpressionError("Expected a property name but '" + property->getNamespace() + "' was found instead");
     35        }
     36        auto theprop = propit->second;
     37        if (isa<BinaryPropertyObject>(property_object_table[theprop])){
     38            auto valit = Binary_ns::aliases_only_map.find(property->getName());
     39            if (valit != Binary_ns::aliases_only_map.end()) {
     40                if (valit->second == Binary_ns::N) {
     41                    Name * binprop = makeName(property_enum_name[theprop], Name::Type::UnicodeProperty);
     42                    property->setDefinition(makeDiff(makeAny(), binprop));
     43                }
     44            }
     45        }
     46    } else {
     47        const std::string value = property->getName();
     48        // Try special cases of Unicode TR #18
     49        if (value == "any") {
     50            property->setDefinition(makeAny());
     51        }
     52        else if (value == "ascii") {
     53            property->setDefinition(makeName("blk", "ascii", Name::Type::UnicodeProperty));
     54        }
     55        else if (value == "assigned") {
     56            Name * unassigned = makeName("cn", Name::Type::UnicodeProperty);
     57            property->setDefinition(makeDiff(makeAny(), unassigned));
     58        }
     59        // Now compatibility properties of UTR #18 Annex C
     60        else if (value == "xdigit") {
     61            Name * digit = makeName("nd", Name::Type::UnicodeProperty);
     62            Name * hexdigit = makeName("hexdigit", Name::Type::UnicodeProperty);
     63            property->setDefinition(makeAlt({digit, hexdigit}));
     64        }
     65        else if (value == "alnum") {
     66            Name * digit = makeName("nd", Name::Type::UnicodeProperty);
     67            Name * alpha = makeName("alphabetic", Name::Type::UnicodeProperty);
     68            property->setDefinition(makeAlt({digit, alpha}));
     69        }
     70        else if (value == "blank") {
     71            Name * space_sep = makeName("space_separator", Name::Type::UnicodeProperty);
     72            CC * tab = makeCC(0x09);
     73            property->setDefinition(makeAlt({space_sep, tab}));
     74        }
     75        else if (value == "graph") {
     76            Name * space = makeName("space", Name::Type::UnicodeProperty);
     77            Name * ctrl = makeName("control", Name::Type::UnicodeProperty);
     78            Name * surr = makeName("surrogate", Name::Type::UnicodeProperty);
     79            Name * unassigned = makeName("cn", Name::Type::UnicodeProperty);
     80            property->setDefinition(makeDiff(makeAny(), makeAlt({space, ctrl, surr, unassigned})));
     81        }
     82        else if (value == "print") {
     83            Name * graph = makeName("graph", Name::Type::UnicodeProperty);
     84            Name * space_sep = makeName("space_separator", Name::Type::UnicodeProperty);
     85            property->setDefinition(makeAlt({graph, space_sep}));
     86        }
     87        else if (value == "word") {
     88            Name * alnum = makeName("alnum", Name::Type::UnicodeProperty);
     89            Name * mark = makeName("mark", Name::Type::UnicodeProperty);
     90            Name * conn = makeName("connectorpunctuation", Name::Type::UnicodeProperty);
     91            Name * join = makeName("joincontrol", Name::Type::UnicodeProperty);
     92            property->setDefinition(makeAlt({alnum, mark, conn, join}));
     93        }
    3494    }
    35 
    36     Name * property = makeName(prop, value, Name::Type::UnicodeProperty);
    37 
    38     auto theprop = propit->second;
    39    
    40    
    41     if (EnumeratedPropertyObject * p = dyn_cast<EnumeratedPropertyObject>(property_object_table[theprop])){
    42         int valcode = p->GetPropertyValueEnumCode(value);
    43         if (valcode < 0) {
    44             throw UnicodePropertyExpressionError("Erroneous property value '" + value + "' for " + property_full_name[theprop] + " property");
    45         }
    46         property->setFunctionName("__get_" + property_enum_name[theprop] + "_" + p->GetValueEnumName(valcode));
    47     }
    48     else if (theprop == scx) {
    49         // Script extension property identified
    50         int valcode = GetPropertyValueEnumCode(sc, value);
    51         if (valcode < 0) {
    52             throw UnicodePropertyExpressionError("Erroneous property value for script_extension property");
    53         }
    54         property->setFunctionName("__get_scx_" + SC_ns::enum_names[valcode]);
    55     }
    56     else if (isa<BinaryPropertyObject>(property_object_table[theprop])){
    57         auto valit = Binary_ns::aliases_only_map.find(value);
    58         if (valit == Binary_ns::aliases_only_map.end()) {
    59             throw UnicodePropertyExpressionError("Erroneous property value for binary property " + property_full_name[theprop]);
    60         }
    61         if (valit->second == Binary_ns::Y) {
    62             property->setFunctionName("__get_" + property_enum_name[theprop] + "_Y");
     95    return property->getDefinition();
     96}
     97
     98std::string resolvePropertyFunction(Name * const property) {
     99    const std::string value = property->getName();
     100    std::string functionName;
     101    if (property->hasNamespace()) {
     102        auto propit = alias_map.find(property->getNamespace());
     103        if (propit == alias_map.end()) {
     104            throw UnicodePropertyExpressionError("Expected a property name but '" + property->getNamespace() + "' was found instead");
     105        }
     106        auto theprop = propit->second;
     107        if (EnumeratedPropertyObject * p = dyn_cast<EnumeratedPropertyObject>(property_object_table[theprop])){
     108            int valcode = p->GetPropertyValueEnumCode(value);
     109            if (valcode < 0) {
     110                throw UnicodePropertyExpressionError("Erroneous property value '" + value + "' for " + property_full_name[theprop] + " property");
     111            }
     112            functionName = "__get_" + property_enum_name[theprop] + "_" + p->GetValueEnumName(valcode);
     113        }
     114        else if (theprop == scx) {
     115            // Script extension property identified
     116            int valcode = GetPropertyValueEnumCode(sc, value);
     117            if (valcode < 0) {
     118                throw UnicodePropertyExpressionError("Erroneous property value for script_extension property");
     119            }
     120            functionName = "__get_scx_" + SC_ns::enum_names[valcode];
     121        }
     122        else if (isa<BinaryPropertyObject>(property_object_table[theprop])){
     123            auto valit = Binary_ns::aliases_only_map.find(value);
     124            if (valit == Binary_ns::aliases_only_map.end()) {
     125                throw UnicodePropertyExpressionError("Erroneous property value for binary property " + property_full_name[theprop]);
     126            }
     127            if (valit->second == Binary_ns::Y) {
     128                functionName = "__get_" + property_enum_name[theprop] + "_Y";
     129            } else {
     130                throw UnicodePropertyExpressionError("Unexpected property value for binary property " + property_full_name[theprop]);
     131            }
    63132        }
    64133        else {
    65             Name * binprop = parser->createName("__get_" + property_enum_name[theprop] + "_Y");
    66             property->setDefinition(makeDiff(makeAny(), binprop));
    67         }
    68     }
    69     else {
    70         throw UnicodePropertyExpressionError("Property " + property_full_name[theprop] + " recognized but not supported in icgrep 1.0");
    71     }
    72     return property;
    73 }
    74 
    75 Name * resolveProperty(const std::string value, re::RE_Parser * parser) {
    76 
    77     // No namespace (property) name.
    78 
    79     Name * property = makeName(value, Name::Type::UnicodeProperty);
    80 
    81     // Try special cases of Unicode TR #18
    82     if (value == "any") {
    83         property->setDefinition(makeAny());
    84     }
    85     else if (value == "ascii") {
    86         property->setDefinition(parser->createName("blk", "ascii"));
    87     }
    88     else if (value == "assigned") {
    89         Name * unassigned = parser->createName("cn");
    90         property->setDefinition(makeDiff(makeAny(), unassigned));
    91     }
    92     // Now compatibility properties of UTR #18 Annex C
    93     else if (value == "xdigit") {
    94         Name * digit = parser->createName("nd");
    95         Name * hexdigit = parser->createName("hexdigit");
    96         property->setDefinition(makeAlt({digit, hexdigit}));
    97     }
    98     else if (value == "alnum") {
    99         Name * digit = parser->createName("nd");
    100         Name * alpha = parser->createName("alphabetic");
    101         property->setDefinition(makeAlt({digit, alpha}));
    102     }
    103     else if (value == "blank") {
    104         Name * space_sep = parser->createName("space_separator");
    105         CC * tab = makeCC(0x09);
    106         property->setDefinition(makeAlt({space_sep, tab}));
    107     }
    108     else if (value == "graph") {
    109         Name * space = parser->createName("space");
    110         Name * ctrl = parser->createName("control");
    111         Name * surr = parser->createName("surrogate");
    112         Name * unassigned = parser->createName("cn");
    113         property->setDefinition(makeDiff(makeAny(), makeAlt({space, ctrl, surr, unassigned})));
    114     }
    115     else if (value == "print") {
    116         Name * graph = parser->createName("graph");
    117         Name * space_sep = parser->createName("space_separator");
    118         property->setDefinition(makeAlt({graph, space_sep}));
    119     }
    120     else if (value == "word") {
    121         Name * alnum = parser->createName("alnum");
    122         Name * mark = parser->createName("mark");
    123         Name * conn = parser->createName("connectorpunctuation");
    124         Name * join = parser->createName("joincontrol");
    125         property->setDefinition(makeAlt({alnum, mark, conn, join}));
    126     }
    127     else { // Try as a general category, script or binary property.
     134            throw UnicodePropertyExpressionError("Property " + property_full_name[theprop] + " recognized but not supported in icgrep 1.0");
     135        }
     136    } else { // No namespace (property) name.
     137        // Try as a general category, script or binary property.
    128138        int valcode;
    129139        if ((valcode = GetPropertyValueEnumCode(gc, value)) >= 0) {
    130             property->setFunctionName("__get_gc_" + GC_ns::enum_names[valcode]);
     140            functionName = "__get_gc_" + GC_ns::enum_names[valcode];
    131141        }
    132142        else if ((valcode = GetPropertyValueEnumCode(sc, value)) >= 0) {
    133             property->setFunctionName("__get_sc_" + SC_ns::enum_names[valcode]);
     143            functionName = "__get_sc_" + SC_ns::enum_names[valcode];
    134144        }
    135145        else { // Try as a binary property.
     
    138148                auto theprop = propit->second;
    139149                if (isa<BinaryPropertyObject>(property_object_table[theprop])) {
    140                     property->setFunctionName("__get_" + property_enum_name[theprop] + "_Y");
     150                    functionName = "__get_" + property_enum_name[theprop] + "_Y";
    141151                }
    142152                else {
     
    149159        }
    150160    }
    151     return property;
     161    assert (functionName.length() > 0);
     162    return std::move(functionName);
    152163}
    153164
  • icGREP/icgrep-devel/icgrep/UCD/resolve_properties.h

    r4737 r4809  
    55
    66namespace re {
    7     class Name;
    8     class RE_Parser;
     7    class RE;
     8    class Name;   
    99}
    1010
     
    1919    const std::string _msg;
    2020};
    21 re::Name * resolveProperty(const std::string value, re::RE_Parser * parser);
    22 re::Name * resolveProperty(const std::string prop, const std::string value, re::RE_Parser * parser);
     21
     22re::RE * resolvePropertyDefinition(re::Name * const property);
     23std::string resolvePropertyFunction(re::Name * const property);
    2324UCD::UnicodeSet resolveUnicodeSet(re::Name * const name);
    2425
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_automultiplexing.cpp

    r4808 r4809  
    2525using namespace boost::numeric::ublas;
    2626
    27 #define PRINT_DEBUG_OUTPUT
     27// #define PRINT_DEBUG_OUTPUT
    2828
    2929#if !defined(NDEBUG) && !defined(PRINT_DEBUG_OUTPUT)
  • icGREP/icgrep-devel/icgrep/re/re_compiler.cpp

    r4808 r4809  
    4646                     cl::desc("set mod64 approximate mode"), cl::cat(fREcompilationOptions));
    4747#ifndef DISABLE_PREGENERATED_UCD_FUNCTIONS
    48 static cl::opt<bool> UsePregeneratedUnicode("use-pregenerated-unicode", cl::init(false),
     48static cl::opt<bool> UsePregeneratedUnicode("use-pregenerated-unicode", cl::init(true),
    4949                     cl::desc("use fixed pregenerated Unicode character class sets instead"), cl::cat(fREcompilationOptions));
    5050#endif
     
    180180
    181181void RE_Compiler::gatherUnicodePropertyNames(RE * re, NameSet & nameSet) {
    182     if (Name * name = dyn_cast<Name>(re)) {
    183         if (name->getDefinition()) {
    184             gatherUnicodePropertyNames(name->getDefinition(), nameSet);
    185         } else if (name->getType() == Name::Type::UnicodeProperty) {
    186             nameSet.insert(name);
    187         }
    188     } else if (Seq* seq = dyn_cast<Seq>(re)) {
    189         for (RE * re : *seq) {
    190             gatherUnicodePropertyNames(re, nameSet);
    191         }
    192     } else if (Alt * alt = dyn_cast<Alt>(re)) {
    193         for (RE * re : *alt) {
    194             gatherUnicodePropertyNames(re, nameSet);
    195         }
    196     } else if (Rep * rep = dyn_cast<Rep>(re)) {
    197         gatherUnicodePropertyNames(rep->getRE(), nameSet);
    198     } else if (Assertion * a = dyn_cast<Assertion>(re)) {
    199         gatherUnicodePropertyNames(a->getAsserted(), nameSet);
    200     } else if (Diff * diff = dyn_cast<Diff>(re)) {
    201         gatherUnicodePropertyNames(diff->getLH(), nameSet);
    202         gatherUnicodePropertyNames(diff->getRH(), nameSet);
    203     } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
    204         gatherUnicodePropertyNames(ix->getLH(), nameSet);
    205         gatherUnicodePropertyNames(ix->getRH(), nameSet);
    206     }
     182
     183    struct UnicodePropertyNameMap {
     184        using PropertyMap = std::map<std::string, Name *>;
     185        using NamespacedPropertyMap = std::map<std::pair<std::string, std::string>, Name *>;
     186        void process(RE * re) {
     187            if (Name * name = dyn_cast<Name>(re)) {
     188                if (name->getDefinition()) {
     189                    process(name->getDefinition());
     190                    return;
     191                }
     192                if (name->hasNamespace()) {
     193                    const auto f = mNamespacedPropertyMap.find(std::make_pair(name->getNamespace(), name->getName()));
     194                    if (f != mNamespacedPropertyMap.end()) {
     195                        if (f->second != name) {
     196                            name->setDefinition(f->second);
     197                        }
     198                        return;
     199                    }
     200                    mNamespacedPropertyMap.insert(std::make_pair(std::make_pair(name->getNamespace(), name->getName()), name));
     201                } else {
     202                    const auto f = mPropertyMap.find(name->getName());
     203                    if (f != mPropertyMap.end()) {
     204                        if (f->second != name) {
     205                            name->setDefinition(f->second);
     206                        }
     207                        return;
     208                    }
     209                    mPropertyMap.insert(std::make_pair(name->getName(), name));
     210                }
     211                if (name->getType() == Name::Type::UnicodeProperty) {
     212                    RE * definition = UCD::resolvePropertyDefinition(name);
     213                    if (definition) {
     214                        process(definition);
     215                    } else {
     216                        mNameSet.insert(name);
     217                    }
     218                }
     219            } else if (Seq* seq = dyn_cast<Seq>(re)) {
     220                for (RE * re : *seq) {
     221                    process(re);
     222                }
     223            } else if (Alt * alt = dyn_cast<Alt>(re)) {
     224                for (RE * re : *alt) {
     225                    process(re);
     226                }
     227            } else if (Rep * rep = dyn_cast<Rep>(re)) {
     228                process(rep->getRE());
     229            } else if (Assertion * a = dyn_cast<Assertion>(re)) {
     230                process(a->getAsserted());
     231            } else if (Diff * diff = dyn_cast<Diff>(re)) {
     232                process(diff->getLH());
     233                process(diff->getRH());
     234            } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
     235                process(ix->getLH());
     236                process(ix->getRH());
     237            }
     238
     239        }
     240
     241        UnicodePropertyNameMap(NameSet & nameSet) : mNameSet(nameSet) {}
     242
     243    private:
     244        NameSet &                   mNameSet;
     245        PropertyMap                 mPropertyMap;
     246        NamespacedPropertyMap       mNamespacedPropertyMap;
     247    } ;
     248
     249    UnicodePropertyNameMap(nameSet).process(re);
    207250}
    208251
     
    213256    if (UsePregeneratedUnicode) {
    214257        for (Name * name : nameSet) {
    215             const UCD::ExternalProperty & ep = UCD::resolveExternalProperty(name->getFunctionName());
    216             Call * call = mPB.createCall(Prototype::Create(name->getFunctionName(), std::get<1>(ep), std::get<2>(ep), std::get<0>(ep)), mCCCompiler.getBasisBits());
     258            const std::string functionName = UCD::resolvePropertyFunction(name);
     259            const UCD::ExternalProperty & ep = UCD::resolveExternalProperty(functionName);
     260            Call * call = mPB.createCall(Prototype::Create(functionName, std::get<1>(ep), std::get<2>(ep), std::get<0>(ep)), mCCCompiler.getBasisBits());
    217261            name->setCompiled(mPB.createAnd(call, mPB.createNot(UNICODE_LINE_BREAK ? mUnicodeLineBreak : mLineFeed)));
    218262        }
  • icGREP/icgrep-devel/icgrep/re/re_name.h

    r4808 r4809  
    3333    };
    3434    std::string getNamespace() const;
     35    bool hasNamespace() const;
    3536    std::string getName() const;
    36     void setFunctionName(const std::string &);
    37     std::string getFunctionName() const;
    38 
    3937    Type getType() const;
    4038    RE * getDefinition() const;
     
    5856    , mNameLength(nameLength)
    5957    , mName(replicateString(name, nameLength))
    60     , mFunctionNameLength(0)
    61     , mFunctionName(nullptr)
    6258    , mType(type)
    6359    , mDefiningRE(defn)
     
    8076    const length_t      mNameLength;
    8177    const char * const  mName;
    82     length_t            mFunctionNameLength;
    83     const char *        mFunctionName;
    8478    const Type          mType;
    8579    RE *                mDefiningRE;
     
    9185}
    9286
     87inline bool Name::hasNamespace() const {
     88    return (mNamespaceLength != 0);
     89}
     90
    9391inline std::string Name::getName() const {
    9492    return std::string(mName, mNameLength);
    95 }
    96 
    97 inline std::string Name::getFunctionName() const {
    98     return std::string(mFunctionName, mFunctionNameLength);
    99 }
    100 
    101 inline void Name::setFunctionName(const std::string & n) {
    102     mFunctionNameLength = n.length();
    103     mFunctionName = replicateString(n.c_str(), n.length());
    10493}
    10594   
     
    113102
    114103inline void Name::setDefinition(RE * d) {
     104    assert (d != this);
    115105    mDefiningRE = d;
    116106}
  • icGREP/icgrep-devel/icgrep/re/re_parser.cpp

    r4806 r4809  
    520520        return f->second;
    521521    }
    522 
    523     Name * property = UCD::resolveProperty(value, this);
    524 
     522    Name * property = makeName(value, Name::Type::UnicodeProperty);
    525523    mNameMap.insert(std::make_pair(std::move(key), property));
    526 
    527524    return property;
    528525}
    529526
    530527Name * RE_Parser::createName(const std::string prop, const std::string value) {
    531 
    532528    auto key = std::make_pair(prop, value);
    533 
    534529    auto f = mNameMap.find(key);
    535530    if (f != mNameMap.end()) {
    536531        return f->second;
    537532    }
    538 
    539     Name * property = UCD::resolveProperty(prop, value, this);
    540 
     533    Name * property = makeName(prop, value, Name::Type::UnicodeProperty);
    541534    mNameMap.insert(std::make_pair(std::move(key), property));
    542 
    543535    return property;
    544536}
  • icGREP/icgrep-devel/icgrep/re/re_parser.h

    r4798 r4809  
    3838{
    3939public:
    40 
    41     friend Name * UCD::resolveProperty(const std::string, RE_Parser *);
    42     friend Name * UCD::resolveProperty(const std::string, const std::string, RE_Parser *);
    4340
    4441    static RE * parse(const std::string &input_string, ModeFlagSet initialFlags);
Note: See TracChangeset for help on using the changeset viewer.