source: icGREP/icgrep-devel/icgrep/re/re_utility.cpp @ 6160

Last change on this file since 6160 was 6160, checked in by cameron, 13 months ago

Generic RE_Transformer

File size: 5.6 KB
Line 
1/*
2 *  Copyright (c) 2016 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
7#include "re_utility.h"
8#include <re/re_any.h>
9#include <re/re_name.h>
10#include <re/re_cc.h>
11#include <re/re_start.h>
12#include <re/re_end.h>
13#include <re/re_alt.h>
14#include <re/re_seq.h>
15#include <re/re_diff.h>
16#include <re/re_intersect.h>
17#include <re/re_group.h>
18#include <re/re_range.h>
19#include <re/re_assertion.h>
20#include <re/printer_re.h>
21#include <llvm/Support/Casting.h>
22#include <llvm/Support/raw_ostream.h>
23#include <llvm/Support/ErrorHandling.h>
24
25namespace re {
26   
27RE * makeComplement(RE * s) {
28  return makeDiff(makeAny(), s);
29}
30
31                           
32Name * makeDigitSet() {
33    return makeName("nd", Name::Type::UnicodeProperty);
34}
35
36Name * makeAlphaNumeric() {
37    return makeName("alnum", Name::Type::UnicodeProperty);
38}
39
40Name * makeWhitespaceSet() {
41    return makeName("whitespace", Name::Type::UnicodeProperty);
42}
43
44Name * makeWordSet() {
45    return makeName("word", Name::Type::UnicodeProperty);
46}
47
48RE * makeWordBoundary() {
49    Name * wordC = makeWordSet();
50    return makeAlt({makeSeq({makeNegativeLookBehindAssertion(wordC), makeLookAheadAssertion(wordC)}),
51        makeSeq({makeLookBehindAssertion(wordC), makeNegativeLookAheadAssertion(wordC)})});
52}
53
54RE * makeWordNonBoundary() {
55    Name * wordC = makeWordSet();
56    return makeAlt({makeSeq({makeNegativeLookBehindAssertion(wordC), makeNegativeLookAheadAssertion(wordC)}),
57        makeSeq({makeLookBehindAssertion(wordC), makeLookAheadAssertion(wordC)})});
58}
59
60RE * makeWordBegin() {
61    Name * wordC = makeWordSet();
62    return makeNegativeLookBehindAssertion(wordC);
63}
64
65RE * makeWordEnd() {
66    Name * wordC = makeWordSet();
67    return makeNegativeLookAheadAssertion(wordC);
68}
69
70RE * makeUnicodeBreak() {
71    return makeAlt({makeCC(0x0A, 0x0C), makeCC(0x85), makeCC(0x2028,0x2029), makeSeq({makeCC(0x0D), makeNegativeLookAheadAssertion(makeCC(0x0A))})});
72}
73   
74   
75RE * RE_Transformer::transform(RE * re) {
76    if (llvm::isa<CC>(re)) return transformCC(llvm::cast<CC>(re));
77    else if (llvm::isa<Start>(re)) return transformStart(llvm::cast<Start>(re));
78    else if (llvm::isa<End>(re)) return transformEnd(llvm::cast<End>(re));
79    else if (llvm::isa<Name>(re)) return transformName(llvm::cast<Name>(re));
80    else if (llvm::isa<Seq>(re)) return transformSeq(llvm::cast<Seq>(re));
81    else if (llvm::isa<Alt>(re)) return transformAlt(llvm::cast<Alt>(re));
82    else if (llvm::isa<Rep>(re)) return transformRep(llvm::cast<Rep>(re));
83    else if (llvm::isa<Intersect>(re)) return transformIntersect(llvm::cast<Intersect>(re));
84    else if (llvm::isa<Diff>(re)) return transformDiff(llvm::cast<Diff>(re));
85    else if (llvm::isa<Range>(re)) return transformRange(llvm::cast<Range>(re));
86    else if (llvm::isa<Group>(re)) return transformGroup(llvm::cast<Group>(re));
87    else if (llvm::isa<Assertion>(re)) return transformAssertion(llvm::cast<Assertion>(re));
88    else {
89        llvm_unreachable("Unknown RE type");
90        return nullptr;
91    }
92}
93   
94RE * RE_Transformer::transformName(Name * nm) {
95    if (mNameTransform == NameTransformationMode::None) return nm;
96    RE * d = nm->getDefinition();
97    if (d) return transform(d);
98    UndefinedNameError(nm);
99    return nullptr;
100}
101 
102RE * RE_Transformer::transformCC(CC * cc) {
103    return cc;
104}
105
106RE * RE_Transformer::transformStart(Start * s) {
107    return s;
108}
109
110RE * RE_Transformer::transformEnd(End * e) {
111    return e;
112}
113
114RE * RE_Transformer::transformSeq(Seq * seq) {
115    std::vector<RE *> elems;
116    elems.reserve(seq->size());
117    bool any_changed = false;
118    for (RE * e : *seq) {
119        RE * e1 = transform(e);
120        if (e1 != e) any_changed = true;
121        elems.push_back(e1);
122    }
123    if (!any_changed) return seq;
124    return makeSeq(elems.begin(), elems.end());
125}
126
127RE * RE_Transformer::transformAlt(Alt * alt) {
128    std::vector<RE *> elems;
129    elems.reserve(alt->size());
130    bool any_changed = false;
131    for (RE * e : *alt) {
132        RE * e1 = transform(e);
133        if (e1 != e) any_changed = true;
134        elems.push_back(e1);
135    }
136    if (!any_changed) return alt;
137    return makeAlt(elems.begin(), elems.end());
138}
139   
140RE * RE_Transformer::transformRep(Rep * r) {
141    RE * x0 = r->getRE();
142    RE * x = transform(x0);
143    if (x == x0) {
144        return r;
145    } else {
146        return makeRep(x, r->getLB(), r->getUB());
147    }
148}
149
150RE * RE_Transformer::transformIntersect(Intersect * ix) {
151    RE * x0 = ix->getLH();
152    RE * y0 = ix->getRH();
153    RE * x = transform(x0);
154    RE * y = transform(y0);
155    if ((x == x0) && (y == y0)) {
156        return ix;
157    } else {
158        return makeIntersect(x, y);
159    }
160}
161
162RE * RE_Transformer::transformDiff(Diff * d) {
163    RE * x0 = d->getLH();
164    RE * y0 = d->getRH();
165    RE * x = transform(x0);
166    RE * y = transform(y0);
167    if ((x == x0) && (y == y0)) {
168        return d;
169    } else {
170        return makeDiff(x, y);
171    }
172}
173
174RE * RE_Transformer::transformRange(Range * rg) {
175    RE * x0 = rg->getLo();
176    RE * y0 = rg->getHi();
177    RE * x = transform(x0);
178    RE * y = transform(y0);
179    if ((x == x0) && (y == y0)) {
180        return rg;
181    } else {
182        return makeRange(x, y);
183    }
184}
185
186RE * RE_Transformer::transformGroup(Group * g) {
187    RE * x0 = g->getRE();
188    RE * x = transform(x0);
189    if (x == x0) {
190        return g;
191    } else {
192        return makeGroup(g->getMode(), x, g->getSense());
193    }
194}
195
196RE * RE_Transformer::transformAssertion(Assertion * a) {
197    RE * x0 = a->getAsserted();
198    RE * x = transform(x0);
199    if (x == x0) {
200        return a;
201    } else {
202        return makeAssertion(x, a->getKind(), a->getSense());
203    }
204}
205
206}
Note: See TracBrowser for help on using the repository browser.