source: icGREP/icgrep-devel/icgrep/UCD/resolve_properties.cpp @ 4829

Last change on this file since 4829 was 4829, checked in by nmedfort, 4 years ago

Back-up check in

File size: 10.2 KB
RevLine 
[4380]1/*
[4388]2 *  Copyright (c) 2015 International Characters.
[4380]3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
[4660]6#include "resolve_properties.h"
[4380]7#include <re/re_alt.h>
[4626]8#include <re/re_any.h>
[4380]9#include <re/re_name.h>
10#include <re/re_diff.h>
11#include "UCD/PropertyAliases.h"
12#include "UCD/PropertyObjects.h"
13#include "UCD/PropertyObjectTable.h"
14#include "UCD/PropertyValueAliases.h"
[4660]15#include <string>
16#include <iostream>
[4380]17
[4618]18using namespace UCD;
[4626]19using namespace re;
[4390]20
[4380]21
[4627]22inline int GetPropertyValueEnumCode(const UCD::property_t type, const std::string & value) {
23    return property_object_table[type]->GetPropertyValueEnumCode(value);
24}
25
[4673]26namespace UCD {
27
[4814]28bool resolvePropertyDefinition(Name * const property) {
[4809]29    if (property->hasNamespace()) {
30        auto propit = alias_map.find(property->getNamespace());
31        if (propit == alias_map.end()) {
32            throw UnicodePropertyExpressionError("Expected a property name but '" + property->getNamespace() + "' was found instead");
33        }
34        auto theprop = propit->second;
35        if (isa<BinaryPropertyObject>(property_object_table[theprop])){
36            auto valit = Binary_ns::aliases_only_map.find(property->getName());
37            if (valit != Binary_ns::aliases_only_map.end()) {
38                if (valit->second == Binary_ns::N) {
39                    Name * binprop = makeName(property_enum_name[theprop], Name::Type::UnicodeProperty);
40                    property->setDefinition(makeDiff(makeAny(), binprop));
[4814]41                    return true;
[4809]42                }
43            }
44        }
45    } else {
46        const std::string value = property->getName();
47        // Try special cases of Unicode TR #18
48        if (value == "any") {
49            property->setDefinition(makeAny());
[4814]50            return true;
51        } else if (value == "ascii") {
[4809]52            property->setDefinition(makeName("blk", "ascii", Name::Type::UnicodeProperty));
[4814]53            return true;
54        } else if (value == "assigned") {
[4809]55            Name * unassigned = makeName("cn", Name::Type::UnicodeProperty);
56            property->setDefinition(makeDiff(makeAny(), unassigned));
[4814]57            return true;
[4809]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}));
[4814]64            return true;
65        } else if (value == "alnum") {
[4809]66            Name * digit = makeName("nd", Name::Type::UnicodeProperty);
67            Name * alpha = makeName("alphabetic", Name::Type::UnicodeProperty);
68            property->setDefinition(makeAlt({digit, alpha}));
[4814]69            return true;
70        } else if (value == "blank") {
[4809]71            Name * space_sep = makeName("space_separator", Name::Type::UnicodeProperty);
72            CC * tab = makeCC(0x09);
73            property->setDefinition(makeAlt({space_sep, tab}));
[4814]74            return true;
75        } else if (value == "graph") {
[4809]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})));
[4814]81            return true;
82        } else if (value == "print") {
[4809]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}));
[4814]86            return true;
87        } else if (value == "word") {
[4809]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}));
[4814]93            return true;
[4809]94        }
[4673]95    }
[4814]96    return false;
[4809]97}
[4673]98
[4809]99std::string resolvePropertyFunction(Name * const property) {
100    const std::string value = property->getName();
101    std::string functionName;
102    if (property->hasNamespace()) {
103        auto propit = alias_map.find(property->getNamespace());
104        if (propit == alias_map.end()) {
105            throw UnicodePropertyExpressionError("Expected a property name but '" + property->getNamespace() + "' was found instead");
[4380]106        }
[4809]107        auto theprop = propit->second;
108        if (EnumeratedPropertyObject * p = dyn_cast<EnumeratedPropertyObject>(property_object_table[theprop])){
109            int valcode = p->GetPropertyValueEnumCode(value);
110            if (valcode < 0) {
111                throw UnicodePropertyExpressionError("Erroneous property value '" + value + "' for " + property_full_name[theprop] + " property");
112            }
113            functionName = "__get_" + property_enum_name[theprop] + "_" + p->GetValueEnumName(valcode);
[4660]114        }
[4809]115        else if (theprop == scx) {
116            // Script extension property identified
117            int valcode = GetPropertyValueEnumCode(sc, value);
118            if (valcode < 0) {
119                throw UnicodePropertyExpressionError("Erroneous property value for script_extension property");
120            }
121            functionName = "__get_scx_" + SC_ns::enum_names[valcode];
[4660]122        }
[4809]123        else if (isa<BinaryPropertyObject>(property_object_table[theprop])){
124            auto valit = Binary_ns::aliases_only_map.find(value);
125            if (valit == Binary_ns::aliases_only_map.end()) {
126                throw UnicodePropertyExpressionError("Erroneous property value for binary property " + property_full_name[theprop]);
127            }
128            if (valit->second == Binary_ns::Y) {
129                functionName = "__get_" + property_enum_name[theprop] + "_Y";
130            } else {
131                throw UnicodePropertyExpressionError("Unexpected property value for binary property " + property_full_name[theprop]);
132            }
[4660]133        }
134        else {
[4809]135            throw UnicodePropertyExpressionError("Property " + property_full_name[theprop] + " recognized but not supported in icgrep 1.0");
[4660]136        }
[4809]137    } else { // No namespace (property) name.
138        // Try as a general category, script or binary property.
[4661]139        int valcode;
140        if ((valcode = GetPropertyValueEnumCode(gc, value)) >= 0) {
[4809]141            functionName = "__get_gc_" + GC_ns::enum_names[valcode];
[4380]142        }
[4673]143        else if ((valcode = GetPropertyValueEnumCode(sc, value)) >= 0) {
[4809]144            functionName = "__get_sc_" + SC_ns::enum_names[valcode];
[4660]145        }
[4673]146        else { // Try as a binary property.
147            auto propit = alias_map.find(value);
148            if (propit != alias_map.end()) {
149                auto theprop = propit->second;
150                if (isa<BinaryPropertyObject>(property_object_table[theprop])) {
[4809]151                    functionName = "__get_" + property_enum_name[theprop] + "_Y";
[4673]152                }
153                else {
154                    throw UnicodePropertyExpressionError("Error: property " + property_full_name[theprop] + " specified without a value");
155                }
[4660]156            }
157            else {
[4673]158                throw UnicodePropertyExpressionError("Expected a general category, script or binary property name but '" + value + "' was found instead");
[4660]159            }
160        }
[4380]161    }
[4809]162    assert (functionName.length() > 0);
163    return std::move(functionName);
[4380]164}
165
[4626]166UnicodeSet resolveUnicodeSet(Name * const name) {
167    if (name->getType() == Name::Type::UnicodeProperty) {
168        std::string prop = name->getNamespace();
169        std::string value = canonicalize_value_name(name->getName());
170        if (prop.length() > 0) {
171            prop = canonicalize_value_name(prop);
172            auto propit = alias_map.find(prop);
173            if (propit == alias_map.end()) {
174                throw UnicodePropertyExpressionError("Expected a property name, but '" + name->getNamespace() + "' found instead");
175            }
[4631]176            auto theprop = propit->second;
[4735]177            if (EnumeratedPropertyObject * p = dyn_cast<EnumeratedPropertyObject>(property_object_table[theprop])){
178                return p->GetCodepointSet(value);
[4626]179            }
[4631]180            else if (BinaryPropertyObject * p = dyn_cast<BinaryPropertyObject>(property_object_table[theprop])){
[4626]181                auto valit = Binary_ns::aliases_only_map.find(value);
182                if (valit == Binary_ns::aliases_only_map.end()) {
183                    throw UnicodePropertyExpressionError("Erroneous property value for binary property " + property_full_name[theprop]);
184                }
[4631]185                return p->GetCodepointSet(value);
186            }           
[4626]187            throw UnicodePropertyExpressionError("Property " + property_full_name[theprop] + " recognized but not supported in icgrep 1.0");
188        }
189        else {
190            // No namespace (property) name.   Try as a general category.
[4627]191            int valcode = GetPropertyValueEnumCode(gc, value);
[4626]192            if (valcode >= 0) {
193                return cast<EnumeratedPropertyObject>(property_object_table[gc])->GetCodepointSet(valcode);
194            }
[4631]195            valcode = GetPropertyValueEnumCode(sc, value);
[4626]196            if (valcode >= 0) {
197                return cast<EnumeratedPropertyObject>(property_object_table[sc])->GetCodepointSet(valcode);
198            }
199            // Try as a binary property.
200            auto propit = alias_map.find(value);
201            if (propit != alias_map.end()) {
[4631]202                auto theprop = propit->second;
203                if (BinaryPropertyObject * p = dyn_cast<BinaryPropertyObject>(property_object_table[theprop])) {
204                    return p->GetCodepointSet(Binary_ns::Y);
[4626]205                }
206                else {
207                    throw UnicodePropertyExpressionError("Error: property " + property_full_name[theprop] + " specified without a value");
208                }
209            }
210        }
211    }
212    throw UnicodePropertyExpressionError("Expected a general category, script or binary property name, but '" + name->getName() + "' found instead");
213}
[4673]214
215}
Note: See TracBrowser for help on using the repository browser.