source: icGREP/icgrep-devel/icgrep/re/exclude_CC.cpp @ 6104

Last change on this file since 6104 was 5929, checked in by cameron, 18 months ago

mayMatchCC

File size: 4.1 KB
Line 
1/*
2 *  Copyright (c) 2017 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/exclude_CC.h>
8#include <re/re_cc.h>
9#include <re/re_name.h>
10#include <re/re_start.h>
11#include <re/re_end.h>
12#include <re/re_any.h>
13#include <re/re_seq.h>
14#include <re/re_alt.h>
15#include <re/re_rep.h>
16#include <re/re_group.h>
17#include <re/re_range.h>
18#include <re/re_diff.h>
19#include <re/re_intersect.h>
20#include <re/re_assertion.h>
21#include <llvm/Support/Casting.h>
22#include <llvm/Support/ErrorHandling.h>
23
24using namespace llvm;
25
26namespace re {
27
28bool mayMatchCC(RE * re, CC * cc) {
29    if (CC * cc0 = dyn_cast<CC>(re)) {
30        return intersects(cc0, cc);
31    } else if (Seq * seq = dyn_cast<Seq>(re)) {
32        for (auto s : * seq) {
33            if (mayMatchCC(s, cc)) return true;
34        }
35        return false;
36    } else if (Alt * alt = dyn_cast<Alt>(re)) {
37        for (auto a : * alt) {
38            if (mayMatchCC(a, cc)) return true;
39        }
40        return false;
41    } else if (Rep * rep = dyn_cast<Rep>(re)) {
42        return mayMatchCC(rep->getRE(), cc);
43    } else if (Group * g = dyn_cast<Group>(re)) {
44        return mayMatchCC(g->getRE(), cc);
45    } else if (Diff * diff = dyn_cast<Diff>(re)) {
46        // We only need exclude from the LH operand.
47        return mayMatchCC(diff->getLH(), cc);
48    } else if (Intersect * e = dyn_cast<Intersect>(re)) {
49        // We only need check  one of the operands.
50        return mayMatchCC(e->getLH(), cc);
51    } else if (isa<Start>(re) || isa<End>(re) || isa<Assertion>(re)) {
52        return false;
53    } else if (Name * n = dyn_cast<Name>(re)) {
54        if (n->getType() ==  Name::Type::ZeroWidth) {
55            return false;
56        }
57        RE * defn = n->getDefinition();
58        return mayMatchCC(defn, cc);
59    } else {
60        report_fatal_error("exclude_CC: unhandled regexp type");
61    }
62}
63 
64   
65RE * exclude_CC(RE * re, CC * cc) {
66    if (!mayMatchCC(re, cc)) return re;
67    if (CC * cc0 = dyn_cast<CC>(re)) {
68        if (intersects(cc0, cc)) return subtractCC(cc0, cc);
69        else return cc0;
70    } else if (Seq * seq = dyn_cast<Seq>(re)) {
71        std::vector<RE*> list;
72        for (auto s : * seq) {
73            list.push_back(exclude_CC(s, cc));
74        }
75        return makeSeq(list.begin(), list.end());
76    } else if (Alt * alt = dyn_cast<Alt>(re)) {
77        std::vector<RE*> list;
78        for (auto a : * alt) {
79            list.push_back(exclude_CC(a, cc));
80        }
81        return makeAlt(list.begin(), list.end());
82    } else if (Rep * rep = dyn_cast<Rep>(re)) {
83        return makeRep(exclude_CC(rep->getRE(), cc), rep->getLB(), rep->getUB());
84    } else if (Group * g = dyn_cast<Group>(re)) {
85        return makeGroup(g->getMode(), exclude_CC(g->getRE(), cc), g->getSense());
86    } else if (Diff * diff = dyn_cast<Diff>(re)) {
87        // We only need exclude from the LH operand.
88        return makeDiff(exclude_CC(diff->getLH(), cc), diff->getRH());
89    } else if (Intersect * e = dyn_cast<Intersect>(re)) {
90        // We only need exclude from the one of the operands.
91        return makeIntersect(exclude_CC(e->getLH(), cc), e->getRH());
92    } else if (isa<Start>(re) || isa<End>(re) || isa<Assertion>(re)) {
93        return re;
94    } else if (Name * n = dyn_cast<Name>(re)) {
95        switch (n->getType()) {
96            case Name::Type::Reference:
97            case Name::Type::ZeroWidth:
98                return re;
99            case Name::Type::Capture:
100                return makeCapture(n->getName(), exclude_CC(n->getDefinition(), cc));
101            default:
102                RE * defn = n->getDefinition();
103                if (const CC * cc0 = dyn_cast<CC>(defn)) {
104                    if (!intersects(cc0, cc)) return re;
105                }
106                std::string cc_name = n->getName() + "--" + cc->canonicalName();
107                return makeName(cc_name, Name::Type::Unicode, exclude_CC(defn, cc));
108                /*
109                return exclude_CC(defn, cc);
110                */
111        }
112    } else {
113        report_fatal_error("exclude_CC: unhandled regexp type");
114    }
115}
116}
117
Note: See TracBrowser for help on using the repository browser.