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

Last change on this file since 6196 was 6196, checked in by cameron, 6 months ago

Remove debugging messsage

File size: 9.6 KB
Line 
1/*
2 *  Copyright (c) 2018 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 <re/re_re.h>
7#include "resolve_properties.h"
8#include <re/re_alt.h>
9#include <re/re_any.h>
10#include <re/re_name.h>
11#include <re/re_diff.h>
12#include <re/re_start.h>
13#include <re/re_end.h>
14#include <re/re_cc.h>
15#include <re/re_seq.h>
16#include <re/re_assertion.h>
17#include <re/parsers/parser.h>
18#include <re/re_name_resolve.h>
19#include <re/grapheme_clusters.h>
20#include <re/re_compiler.h>
21#include "UCD/PropertyAliases.h"
22#include "UCD/PropertyObjects.h"
23#include "UCD/PropertyObjectTable.h"
24#include "UCD/PropertyValueAliases.h"
25#include <llvm/Support/ErrorHandling.h>
26#include <llvm/Support/raw_ostream.h>
27
28using namespace UCD;
29using namespace re;
30using namespace llvm;
31
32namespace UCD {
33   
34void UnicodePropertyExpressionError(std::string errmsg) {
35    llvm::report_fatal_error(errmsg);
36}
37
38bool resolvePropertyDefinition(Name * const property) {
39    if (property->hasNamespace()) {
40        auto propit = alias_map.find(property->getNamespace());
41        if (propit == alias_map.end()) {
42            UnicodePropertyExpressionError("Expected a property name but '" + property->getNamespace() + "' was found instead");
43        }
44        auto theprop = propit->second;
45        if (isa<BinaryPropertyObject>(property_object_table[theprop])){
46            auto valit = Binary_ns::aliases_only_map.find(property->getName());
47            if (valit != Binary_ns::aliases_only_map.end()) {
48                if (valit->second == Binary_ns::N) {
49                    Name * binprop = makeName(property_enum_name[theprop], Name::Type::UnicodeProperty);
50                    property->setDefinition(makeDiff(makeAny(), binprop));
51                    return true;
52                }
53            }
54        }
55    } else {
56        const std::string value = property->getName();
57        // Try special cases of Unicode TR #18
58        if ((value == "any") || (value == ".")) {
59            property->setDefinition(makeCC(0, 0x10FFFF));
60            return true;
61        } else if (value == "ascii") {
62            property->setDefinition(makeName("blk", "ascii", Name::Type::UnicodeProperty));
63            return true;
64        } else if (value == "assigned") {
65            Name * unassigned = makeName("cn", Name::Type::UnicodeProperty);
66            property->setDefinition(makeDiff(makeAny(), unassigned));
67            return true;
68        } else if (value == "\\b{g}") {
69            RE * gcb = generateGraphemeClusterBoundaryRule();
70            property->setDefinition(resolveUnicodeNames(gcb));
71            return true;
72        } else if (value == "^s") {  // "start anchor (^) in single-line mode"
73            property->setDefinition(makeNegativeLookBehindAssertion(makeCC(0, 0x10FFFF)));
74            return true;
75        } else if (value == "$s") { // "end anchor ($) in single-line mode"
76            property->setDefinition(makeNegativeLookAheadAssertion(makeCC(0, 0x10FFFF)));
77            return true;
78        }
79    }
80    return false;
81}
82
83const std::string & getPropertyValueGrepString(const std::string & prop) {
84    auto propit = alias_map.find(canonicalize_value_name(prop));
85    if (propit == alias_map.end()) {
86        UnicodePropertyExpressionError("Expected a property name, but '" + prop + "' found instead");
87    }
88    auto theprop = propit->second;
89    if (EnumeratedPropertyObject * p = dyn_cast<EnumeratedPropertyObject>(property_object_table[theprop])){
90        return p->GetPropertyValueGrepString();
91    } else if (BinaryPropertyObject * p = dyn_cast<BinaryPropertyObject>(property_object_table[theprop])) {
92        return p->GetPropertyValueGrepString();
93    }
94
95    UnicodePropertyExpressionError("Property " + property_full_name[theprop] + " recognized but not supported in icgrep 1.0");
96}
97
98UnicodeSet resolveUnicodeSet(Name * const name) {
99    if (name->getType() == Name::Type::UnicodeProperty) {
100        std::string prop = name->getNamespace();
101        std::string value = name->getName();
102        if (prop.length() > 0) {
103            prop = canonicalize_value_name(prop);
104            auto propit = alias_map.find(prop);
105            if (propit == alias_map.end()) {
106                UnicodePropertyExpressionError("Expected a property name, but '" + name->getNamespace() + "' found instead");
107            }
108            auto propObj = property_object_table[propit->second];
109            if ((value.length() > 0) && (value[0] == '/')) {
110                // resolve a regular expression
111                re::RE * propValueRe = RE_Parser::parse(value.substr(1), re::DEFAULT_MODE, re::PCRE, false);
112                propValueRe = re::resolveUnicodeNames(propValueRe);  // Recursive name resolution may be required.
113                return propObj->GetCodepointSetMatchingPattern(propValueRe);
114            }
115            if ((value.length() > 0) && (value[0] == '@')) {
116                // resolve a @property@ or @identity@ expression.
117                std::string otherProp = canonicalize_value_name(value.substr(1));
118                if (otherProp == "identity") {
119                    return propObj->GetReflexiveSet();
120                }
121                auto propit = alias_map.find(prop);
122                if (propit == alias_map.end()) {
123                    UnicodePropertyExpressionError("Expected a property name, but '" + value.substr(1) + "' found instead");
124                }
125                auto propObj2 = property_object_table[propit->second];
126                if (isa<BinaryPropertyObject>(propObj) && isa<BinaryPropertyObject>(propObj2)) {
127                    return ~(cast<BinaryPropertyObject>(propObj)->GetCodepointSet(UCD::Binary_ns::Y) ^
128                             cast<BinaryPropertyObject>(propObj2)->GetCodepointSet(UCD::Binary_ns::Y));
129                }
130                else {
131                    UnicodePropertyExpressionError("unsupported");
132                }
133            }
134            else {
135                return propObj->GetCodepointSet(value);
136            }
137        }
138        else {
139            // No namespace (property) name.   Try as a general category.
140            std::string canon = canonicalize_value_name(value);
141            const auto & gcobj = cast<EnumeratedPropertyObject>(property_object_table[gc]);
142            int valcode = gcobj->GetPropertyValueEnumCode(canon);
143            if (valcode >= 0) {
144                return gcobj->GetCodepointSet(valcode);
145            }
146            const auto & scObj = cast<EnumeratedPropertyObject>(property_object_table[sc]);
147            valcode = scObj->GetPropertyValueEnumCode(canon);
148            if (valcode >= 0) {
149                return scObj->GetCodepointSet(valcode);
150            }
151            // Try as a binary property.
152           
153            auto propit = alias_map.find(canon);
154            if (propit != alias_map.end()) {
155                auto theprop = propit->second;
156                if (BinaryPropertyObject * p = dyn_cast<BinaryPropertyObject>(property_object_table[theprop])) {
157                    return p->GetCodepointSet(Binary_ns::Y);
158                }
159                else {
160                    UnicodePropertyExpressionError("Error: property " + property_full_name[theprop] + " specified without a value");
161                }
162            }
163            // Try special cases of Unicode TR #18
164            // Now compatibility properties of UTR #18 Annex C
165                   
166            else if (canon == ".") return UnicodeSet(0, 0x10FFFF);
167            else if (canon == "alnum") {
168                Name * digit = makeName("nd", Name::Type::UnicodeProperty);
169                Name * alpha = makeName("alphabetic", Name::Type::UnicodeProperty);
170                return resolveUnicodeSet(digit) + resolveUnicodeSet(alpha);
171            } else if (canon == "xdigit") {
172                Name * digit = makeName("nd", Name::Type::UnicodeProperty);
173                Name * hexdigit = makeName("hexdigit", Name::Type::UnicodeProperty);
174                return resolveUnicodeSet(digit) + resolveUnicodeSet(hexdigit);
175            } else if (canon == "blank") {
176                Name * space_sep = makeName("space_separator", Name::Type::UnicodeProperty);
177                return resolveUnicodeSet(space_sep) + UnicodeSet(0x09) /* tab */;
178            } else if (canon == "print") {
179                Name * graph = makeName("graph", Name::Type::UnicodeProperty);
180                Name * space_sep = makeName("space_separator", Name::Type::UnicodeProperty);
181                return resolveUnicodeSet(graph) + resolveUnicodeSet(space_sep);
182            } else if (canon == "word") {
183                Name * alnum = makeName("alnum", Name::Type::UnicodeProperty);
184                Name * mark = makeName("mark", Name::Type::UnicodeProperty);
185                Name * conn = makeName("connectorpunctuation", Name::Type::UnicodeProperty);
186                Name * join = makeName("joincontrol", Name::Type::UnicodeProperty);
187                return resolveUnicodeSet(alnum) + resolveUnicodeSet(mark) + resolveUnicodeSet(conn) + resolveUnicodeSet(join);
188            } else if (canon == "graph") {
189                Name * space = makeName("space", Name::Type::UnicodeProperty);
190                Name * ctrl = makeName("control", Name::Type::UnicodeProperty);
191                Name * surr = makeName("surrogate", Name::Type::UnicodeProperty);
192                Name * unassigned = makeName("cn", Name::Type::UnicodeProperty);
193                return ~(resolveUnicodeSet(space) + resolveUnicodeSet(ctrl) + resolveUnicodeSet(surr) + resolveUnicodeSet(unassigned));
194            }
195
196
197        }
198    }
199    UnicodePropertyExpressionError("Expected a general category, script or binary property name, but '" + name->getName() + "' found instead");
200}
201
202}
Note: See TracBrowser for help on using the repository browser.