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

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

Removed CC_NameMap

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