Ignore:
Timestamp:
Jul 12, 2015, 12:10:59 AM (4 years ago)
Author:
nmedfort
Message:

Moved 'resolveProperties' into CC_NameMap as a single call for each unique Name.

File:
1 moved

Legend:

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

    r4659 r4660  
    44 *  icgrep is a trademark of International Characters.
    55 */
    6 
    7 #include <string>
     6#include "resolve_properties.h"
    87#include <re/re_re.h>
    98#include <re/re_alt.h>
     
    2423#include "UCD/PropertyValueAliases.h"
    2524#include <boost/algorithm/string/case_conv.hpp>
    26 #include "resolve_properties.h"
     25#include <string>
     26#include <iostream>
    2727
    2828using namespace UCD;
     
    4747}
    4848
    49 void resolveProperties(RE * re) {
    50     if (Alt * alt = dyn_cast<Alt>(re)) {
    51         for (auto item : *alt) {
    52             resolveProperties(item);
     49void resolveProperty(Name * name) {
     50    const std::string prop = canonicalize_value_name(name->getNamespace());
     51    const std::string value = canonicalize_value_name(name->getName());
     52    if (prop.length() != 0) {
     53        auto propit = alias_map.find(prop);
     54        if (propit == alias_map.end()) {
     55            throw UnicodePropertyExpressionError("Expected a property name, but '" + name->getNamespace() + "' found instead");
     56        }
     57        auto theprop = propit->second;
     58        if (theprop == gc) {
     59            // General Category
     60            int valcode = GetPropertyValueEnumCode(gc, value);
     61            if (valcode < 0) {
     62                throw UnicodePropertyExpressionError("Erroneous property value for general_category property");
     63            }
     64            name->setFunctionName("__get_gc_" + GC_ns::enum_names[valcode]);
     65        }
     66        else if (theprop == sc) {
     67            // Script property identified
     68            int valcode = GetPropertyValueEnumCode(sc, value);
     69            if (valcode < 0) {
     70                throw UnicodePropertyExpressionError("Erroneous property value for script property");
     71            }
     72            name->setFunctionName("__get_sc_" + SC_ns::enum_names[valcode]);
     73        }
     74        else if (theprop == scx) {
     75            // Script extension property identified
     76            int valcode = GetPropertyValueEnumCode(sc, value);
     77            if (valcode < 0) {
     78                throw UnicodePropertyExpressionError("Erroneous property value for script_extension property");
     79            }
     80            name->setFunctionName("__get_scx_" + SC_ns::enum_names[valcode]);
     81        }
     82        else if (theprop == blk) {
     83            // Block property identified
     84            int valcode = GetPropertyValueEnumCode(blk, value);
     85            if (valcode < 0) {
     86                 throw UnicodePropertyExpressionError("Erroneous property value for block property");
     87            }
     88            name->setFunctionName("__get_blk_" + BLK_ns::enum_names[valcode]);
     89        }
     90        else if (isa<BinaryPropertyObject>(property_object_table[theprop])){
     91            auto valit = Binary_ns::aliases_only_map.find(value);
     92            if (valit == Binary_ns::aliases_only_map.end()) {
     93                throw UnicodePropertyExpressionError("Erroneous property value for binary property " + property_full_name[theprop]);
     94            }
     95            if (valit->second == Binary_ns::Y) {
     96                name->setFunctionName("__get_" + lowercase(property_enum_name[theprop]) + "_Y");
     97                return;
     98            }
     99            else {
     100                Name * binprop = makeName("__get_" + lowercase(property_enum_name[theprop]) + "_Y", Name::Type::UnicodeProperty);
     101                name->setDefinition(makeDiff(makeAny(), binprop));
     102                return;
     103            }
     104        }
     105        else {
     106            throw UnicodePropertyExpressionError("Property " + property_full_name[theprop] + " recognized, but not supported in icgrep 1.0");
    53107        }
    54108    }
    55     else if (Seq * seq = dyn_cast<Seq>(re)) {
    56         for (auto item : *seq) {
    57             resolveProperties(item);
     109    else {
     110
     111        // No namespace (property) name.   Try as a general category.
     112        int valcode = GetPropertyValueEnumCode(gc, value);
     113        if (valcode >= 0) {
     114            name->setFunctionName("__get_gc_" + GC_ns::enum_names[valcode]);
     115            return;
     116        }
     117        valcode = GetPropertyValueEnumCode(sc, value);
     118        if (valcode >= 0) {
     119            name->setFunctionName("__get_sc_" + SC_ns::enum_names[valcode]);
     120            return;
     121        }
     122        // Try as a binary property.
     123        auto propit = alias_map.find(value);
     124        if (propit != alias_map.end()) {
     125            auto theprop = propit->second;
     126            if (isa<BinaryPropertyObject>(property_object_table[theprop])) {
     127                name->setFunctionName("__get_" + lowercase(property_enum_name[theprop]) + "_Y");
     128                return;
     129            }
     130            else {
     131                throw UnicodePropertyExpressionError("Error: property " + property_full_name[theprop] + " specified without a value");
     132            }
     133        }
     134        // Now try special cases of Unicode TR #18
     135        else if (value == "any") {
     136            name->setDefinition(makeAny());
     137            return;
     138        }
     139        else if (value == "assigned") {
     140            Name * Cn = makeName("Cn", Name::Type::UnicodeProperty);
     141            name->setDefinition(makeDiff(makeAny(), Cn));
     142            return;
     143        }
     144        else if (value == "ascii") {
     145            name->setFunctionName("__get_blk_ASCII");
     146            return;
     147        }
     148        // Now compatibility properties of UTR #18 Annex C
     149        else if (value == "xdigit") {
     150            Name * Nd = makeName("Nd", Name::Type::UnicodeProperty);
     151            Name * hexdigit = makeName("Hex_digit", Name::Type::UnicodeProperty);
     152            name->setDefinition(makeAlt({Nd, hexdigit}));
     153            return;
     154        }
     155        else if (value == "alnum") {
     156            Name * digit = makeName("Nd", Name::Type::UnicodeProperty);
     157            Name * alpha = makeName("alphabetic", Name::Type::UnicodeProperty);
     158            name->setDefinition(makeAlt({digit, alpha}));
     159            return;
     160        }
     161        else if (value == "blank") {
     162            Name * space_sep = makeName("space_separator", Name::Type::UnicodeProperty);
     163            CC * tab = makeCC(0x09);
     164            name->setDefinition(makeAlt({space_sep, tab}));
     165            return;
     166        }
     167        else if (value == "graph") {
     168            Name * space = makeName("space", Name::Type::UnicodeProperty);
     169            Name * ctrl = makeName("control", Name::Type::UnicodeProperty);
     170            Name * surr = makeName("surrogate", Name::Type::UnicodeProperty);
     171            Name * unassigned = makeName("Cn", Name::Type::UnicodeProperty);
     172            Name * nongraph = makeName("[^graph]", Name::Type::UnicodeProperty);
     173            nongraph->setDefinition(makeAlt({space, ctrl, surr, unassigned}));
     174            name->setDefinition(makeDiff(makeAny(), nongraph));
     175            return;
     176        }
     177        else if (value == "print") {
     178            Name * graph = makeName("graph", Name::Type::UnicodeProperty);
     179            Name * space_sep = makeName("space_separator", Name::Type::UnicodeProperty);
     180            name->setDefinition(makeAlt({graph, space_sep}));
     181            return;
     182        }
     183        else if (value == "word") {
     184            Name * alnum = makeName("alnum", Name::Type::UnicodeProperty);
     185            Name * mark = makeName("mark", Name::Type::UnicodeProperty);
     186            Name * conn = makeName("Connector_Punctuation", Name::Type::UnicodeProperty);
     187            Name * join = makeName("Join_Control", Name::Type::UnicodeProperty);
     188            name->setDefinition(makeAlt({alnum, mark, conn, join}));
     189            return;
     190        }
     191        else {
     192            throw UnicodePropertyExpressionError("Expected a general category, script or binary property name, but '" + name->getName() + "' found instead");
    58193        }
    59194    }
    60     else if (Rep * rep = dyn_cast<Rep>(re)) {
    61         resolveProperties(rep->getRE());
    62     }
    63     else if (Assertion * a = dyn_cast<Assertion>(re)) {
    64         resolveProperties(a->getAsserted());
    65     }
    66     else if (Diff * diff = dyn_cast<Diff>(re)) {
    67         resolveProperties(diff->getRH());
    68         resolveProperties(diff->getLH());
    69     }
    70     else if (Intersect * e = dyn_cast<Intersect>(re)) {
    71         resolveProperties(e->getRH());
    72         resolveProperties(e->getLH());
    73     }
    74     else if (Name * name = dyn_cast<Name>(re)) {
    75         if (name->getType() == Name::Type::UnicodeProperty) {
    76             const std::string prop = canonicalize_value_name(name->getNamespace());
    77             const std::string value = canonicalize_value_name(name->getName());
    78             if (prop.length() != 0) {
    79                 auto propit = alias_map.find(prop);
    80                 if (propit == alias_map.end()) {
    81                     throw UnicodePropertyExpressionError("Expected a property name, but '" + name->getNamespace() + "' found instead");
    82                 }
    83                 auto theprop = propit->second;
    84                 if (theprop == gc) {
    85                     // General Category
    86                     int valcode = GetPropertyValueEnumCode(gc, value);
    87                     if (valcode < 0) {
    88                         throw UnicodePropertyExpressionError("Erroneous property value for general_category property");
    89                     }                   
    90                     name->setName("__get_gc_" + GC_ns::enum_names[valcode]);
    91                 }
    92                 else if (theprop == sc) {
    93                     // Script property identified
    94                     int valcode = GetPropertyValueEnumCode(sc, value);
    95                     if (valcode < 0) {
    96                         throw UnicodePropertyExpressionError("Erroneous property value for script property");
    97                     }
    98                     name->setName("__get_sc_" + SC_ns::enum_names[valcode]);
    99                 }
    100                 else if (theprop == scx) {
    101                     // Script extension property identified
    102                     int valcode = GetPropertyValueEnumCode(sc, value);
    103                     if (valcode < 0) {
    104                         throw UnicodePropertyExpressionError("Erroneous property value for script_extension property");
    105                     }
    106                     name->setName("__get_scx_" + SC_ns::enum_names[valcode]);
    107                 }
    108                 else if (theprop == blk) {
    109                     // Block property identified
    110                     int valcode = GetPropertyValueEnumCode(blk, value);
    111                     if (valcode < 0) {
    112                          throw UnicodePropertyExpressionError("Erroneous property value for block property");
    113                     }
    114                     name->setName("__get_blk_" + BLK_ns::enum_names[valcode]);
    115                 }
    116                 else if (isa<BinaryPropertyObject>(property_object_table[theprop])){
    117                     auto valit = Binary_ns::aliases_only_map.find(value);
    118                     if (valit == Binary_ns::aliases_only_map.end()) {
    119                         throw UnicodePropertyExpressionError("Erroneous property value for binary property " + property_full_name[theprop]);
    120                     }
    121                     if (valit->second == Binary_ns::Y) {
    122                         name->setName("__get_" + lowercase(property_enum_name[theprop]) + "_Y");
    123                         return;
    124                     }
    125                     else {
    126                         Name * binprop = makeName("__get_" + lowercase(property_enum_name[theprop]) + "_Y", Name::Type::UnicodeProperty);
    127                         name->setDefinition(makeDiff(makeAny(), binprop));
    128                         return;
    129                     }
    130                 }
    131                 else {
    132                     throw UnicodePropertyExpressionError("Property " + property_full_name[theprop] + " recognized, but not supported in icgrep 1.0");
    133                 }
    134             }
    135             else {
    136                 // No namespace (property) name.   Try as a general category.
    137                 int valcode = GetPropertyValueEnumCode(gc, value);
    138                 if (valcode >= 0) {
    139                     name->setName("__get_gc_" + GC_ns::enum_names[valcode]);
    140                     return;
    141                 }
    142                 valcode = GetPropertyValueEnumCode(sc, value);
    143                 if (valcode >= 0) {
    144                     name->setName("__get_sc_" + SC_ns::enum_names[valcode]);
    145                     return;
    146                 }
    147                 // Try as a binary property.
    148                 auto propit = alias_map.find(value);
    149                 if (propit != alias_map.end()) {
    150                     auto theprop = propit->second;
    151                     if (isa<BinaryPropertyObject>(property_object_table[theprop])) {
    152                         name->setName("__get_" + lowercase(property_enum_name[theprop]) + "_Y");
    153                         return;
    154                     }
    155                     else {
    156                         throw UnicodePropertyExpressionError("Error: property " + property_full_name[theprop] + " specified without a value");
    157                     }
    158                 }
    159                 // Now try special cases of Unicode TR #18
    160                 else if (value == "any") {
    161                     name->setDefinition(makeAny());
    162                     return;
    163                 }
    164                 else if (value == "assigned") {
    165                     Name * Cn = makeName("Cn", Name::Type::UnicodeProperty);
    166                     resolveProperties(Cn);
    167                     name->setDefinition(makeDiff(makeAny(), Cn));
    168                     return;
    169                 }
    170                 else if (value == "ascii") {
    171                     name->setName("__get_blk_ASCII");
    172                     return;
    173                 }
    174                 // Now compatibility properties of UTR #18 Annex C
    175                 else if (value == "xdigit") {
    176                     Name * Nd = makeName("Nd", Name::Type::UnicodeProperty);
    177                     resolveProperties(Nd);
    178                     Name * hexdigit = makeName("Hex_digit", Name::Type::UnicodeProperty);
    179                     resolveProperties(hexdigit);
    180                     name->setDefinition(makeAlt({Nd, hexdigit}));
    181                     return;
    182                 }
    183                 else if (value == "alnum") {
    184                     Name * digit = makeName("Nd", Name::Type::UnicodeProperty);
    185                     resolveProperties(digit);
    186                     Name * alpha = makeName("alphabetic", Name::Type::UnicodeProperty);
    187                     resolveProperties(alpha);
    188                     name->setDefinition(makeAlt({digit, alpha}));
    189                     return;
    190                 }
    191                 else if (value == "blank") {
    192                     Name * space_sep = makeName("space_separator", Name::Type::UnicodeProperty);
    193                     resolveProperties(space_sep);
    194                     CC * tab = makeCC(0x09);
    195                     name->setDefinition(makeAlt({space_sep, tab}));
    196                     return;
    197                 }
    198                 else if (value == "graph") {
    199                     Name * space = makeName("space", Name::Type::UnicodeProperty);
    200                     resolveProperties(space);
    201                     Name * ctrl = makeName("control", Name::Type::UnicodeProperty);
    202                     resolveProperties(ctrl);
    203                     Name * surr = makeName("surrogate", Name::Type::UnicodeProperty);
    204                     resolveProperties(surr);
    205                     Name * unassigned = makeName("Cn", Name::Type::UnicodeProperty);
    206                     resolveProperties(unassigned);
    207                     Name * nongraph = makeName("[^graph]", Name::Type::UnicodeProperty);
    208                     nongraph->setDefinition(makeAlt({space, ctrl, surr, unassigned}));
    209                     name->setDefinition(makeDiff(makeAny(), nongraph));
    210                     return;
    211                 }
    212                 else if (value == "print") {
    213                     Name * graph = makeName("graph", Name::Type::UnicodeProperty);
    214                     resolveProperties(graph);
    215                     Name * space_sep = makeName("space_separator", Name::Type::UnicodeProperty);
    216                     resolveProperties(space_sep);
    217                     std::vector<RE *> alts = {graph, space_sep};
    218                     name->setDefinition(makeAlt(alts.begin(), alts.end()));
    219                     return;
    220                 }
    221                 else if (value == "word") {
    222                     Name * alnum = makeName("alnum", Name::Type::UnicodeProperty);
    223                     resolveProperties(alnum);
    224                     Name * mark = makeName("mark", Name::Type::UnicodeProperty);
    225                     resolveProperties(mark);
    226                     Name * conn = makeName("Connector_Punctuation", Name::Type::UnicodeProperty);
    227                     resolveProperties(conn);
    228                     Name * join = makeName("Join_Control", Name::Type::UnicodeProperty);
    229                     resolveProperties(join);
    230                     name->setDefinition(makeAlt({alnum, mark, conn, join}));
    231                     return;
    232                 }
    233                 else {
    234                     throw UnicodePropertyExpressionError("Expected a general category, script or binary property name, but '" + name->getName() + "' found instead");
    235                 }
    236             }
    237 
    238             //name->setCompiled(compileCC(cast<CC>(d), mCG));
    239         }
    240     }
    241     else if (!isa<CC>(re) && !isa<Start>(re) && !isa<End>(re) && !isa<Any>(re)) {
    242         throw UnicodePropertyExpressionError("Unknown RE type in resolveProperties.");
    243     }
    244195}
    245196
    246197UnicodeSet resolveUnicodeSet(Name * const name) {
    247 
    248198    if (name->getType() == Name::Type::UnicodeProperty) {
    249199        std::string prop = name->getNamespace();
Note: See TracChangeset for help on using the changeset viewer.