source: icGREP/icgrep-devel/icgrep/re/re_star_normal.cpp @ 5613

Last change on this file since 5613 was 5493, checked in by cameron, 2 years ago

Restore check-ins from the last several days

File size: 4.6 KB
Line 
1#include "re_star_normal.h"
2#include <re/re_name.h>
3#include <re/re_any.h>
4#include <re/re_start.h>
5#include <re/re_end.h>
6#include <re/re_alt.h>
7#include <re/re_cc.h>
8#include <re/re_seq.h>
9#include <re/re_rep.h>
10#include <re/re_diff.h>
11#include <re/re_intersect.h>
12#include <re/re_assertion.h>
13#include <re/re_analysis.h>
14
15using namespace llvm;
16
17namespace re {
18
19RE * RE_Star_Normal::star_normal(RE * re) {
20
21    if (Alt * alt = dyn_cast<Alt>(re)) {
22        std::vector<RE *> list;
23        list.reserve(alt->size());
24        for (RE * re : *alt) {
25            list.push_back(star_normal(re));
26        }
27        re = makeAlt(list.begin(), list.end());
28    } else if (Seq * seq = dyn_cast<Seq>(re)) {
29        std::vector<RE *> list;
30        list.reserve(seq->size());
31        for (RE * re : *seq) {
32            list.push_back(star_normal(re));
33        }
34        re = makeSeq(list.begin(), list.end());
35    } else if (Assertion * a = dyn_cast<Assertion>(re)) {
36        re = makeAssertion(star_normal(a->getAsserted()), a->getKind(), a->getSense());
37    } else if (Rep * rep = dyn_cast<Rep>(re)) {
38         if (rep->getLB() == 0 && rep->getUB() == Rep::UNBOUNDED_REP) {
39            RE * expr = helper(rep->getRE());
40            re = makeRep(expr, 0, rep->getUB());
41        } else {
42            RE * expr = star_normal(rep->getRE());
43            re = makeRep(expr, rep->getLB(), rep->getUB());
44        }
45    } else if (Diff * diff = dyn_cast<Diff>(re)) {
46        re = makeDiff(star_normal(diff->getLH()), star_normal(diff->getRH()));
47    } else if (Intersect * e = dyn_cast<Intersect>(re)) {
48        re = makeIntersect(star_normal(e->getLH()), star_normal(e->getRH()));
49    } else if (Name * name = dyn_cast<Name>(re)) {
50        if (name->getDefinition()) {
51            name->setDefinition(star_normal(name->getDefinition()));
52        }
53    }
54    return re;
55}
56
57RE * RE_Star_Normal::helper(RE * re) {
58
59    if (Alt * alt = dyn_cast<Alt>(re)) {
60        std::vector<RE *> list;
61        list.reserve(alt->size());
62        for (RE * re : *alt) {
63            list.push_back(helper(re));
64        }
65        re = makeAlt(list.begin(), list.end());
66    } else if (Seq * seq = dyn_cast<Seq>(re)) {
67        RE * re_first = *(seq->begin());
68        std::vector<RE *> list;
69        list.reserve(seq->size());
70        for (auto i = seq->begin() + 1; i != seq->end(); i++) {
71            list.push_back(*i);
72        }
73        RE * re_follow = makeSeq(list.begin(), list.end());
74        if (!isNullable(re_first) && !isNullable(re_follow)) {
75            re = makeSeq({star_normal(re_first), star_normal(re_follow)});
76        } else if (!isNullable(re_first) && isNullable(re_follow)) {
77            re = makeSeq({helper(re_first), star_normal(re_follow)});
78        } else if (isNullable(re_first) && !isNullable(re_follow)) {
79            re = makeSeq({star_normal(re_first), helper(re_follow)});
80        } else {
81            re = makeAlt({helper(re_first), helper(re_follow)});
82        }
83    } else if (Assertion * a = dyn_cast<Assertion>(re)) {
84        re = makeAssertion(helper(a->getAsserted()), a->getKind(), a->getSense());
85    } else if (Rep * rep = dyn_cast<Rep>(re)) {
86        if (rep->getLB() == 0 && rep->getUB() == Rep::UNBOUNDED_REP) {
87            re = helper(rep->getRE());
88        } else {
89            RE * expr = helper(rep->getRE());
90            re = makeRep(expr, rep->getLB(), rep->getUB());
91        }
92    } else if (Diff * diff = dyn_cast<Diff>(re)) {
93        re = makeDiff(helper(diff->getLH()), helper(diff->getRH()));
94    } else if (Intersect * e = dyn_cast<Intersect>(re)) {
95        re = makeIntersect(helper(e->getLH()), helper(e->getRH()));
96    } else if (Name * name = dyn_cast<Name>(re)) {
97        if (name->getDefinition()) {
98            name->setDefinition(helper(name->getDefinition()));
99        }
100    }
101    return re;
102}
103
104bool RE_Star_Normal::isNullable(const RE * re) {
105    if (const Seq * re_seq = dyn_cast<const Seq>(re)) {
106        for (const RE * re : *re_seq) {
107            if (!isNullable(re)) {
108                return false;
109            }
110        }
111        return true;
112    } else if (const Alt * re_alt = dyn_cast<const Alt>(re)) {
113        for (const RE * re : *re_alt) {
114            if (isNullable(re)) {
115                return true;
116            }
117        }
118    } else if (const Rep* re_rep = dyn_cast<const Rep>(re)) {
119        return re_rep->getLB() == 0 ? true : isNullable(re_rep->getRE());
120    } else if (const Diff * diff = dyn_cast<const Diff>(re)) {
121        return isNullable(diff->getLH()) && !isNullable(diff->getRH());
122    } else if (const Intersect * e = dyn_cast<const Intersect>(re)) {
123        return isNullable(e->getLH()) && isNullable(e->getRH());
124    } 
125    return false;
126}
127
128
129}
Note: See TracBrowser for help on using the repository browser.