source: icGREP/icgrep-devel/icgrep/re/re_alt.h @ 5786

Last change on this file since 5786 was 5784, checked in by cameron, 18 months ago

Restructuring step/tidy-up for re_passes

File size: 2.2 KB
Line 
1/*
2 *  Copyright (c) 2014 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#ifndef ALT_H
8#define ALT_H
9
10#include "re_re.h"
11#include "re_cc.h"
12#include <llvm/Support/Casting.h>
13
14namespace re {
15
16class Alt : public Vector {
17public:
18    static inline bool classof(const RE * re) {
19        return re->getClassTypeId() == ClassTypeId::Alt;
20    }
21    static inline bool classof(const void *) {
22        return false;
23    }
24protected:
25    friend Alt * makeAlt();
26    template<typename iterator> friend RE * makeAlt(iterator, iterator);
27    Alt()
28    : Vector(ClassTypeId::Alt) {
29
30    }
31    Alt(iterator begin, iterator end)
32    : Vector(ClassTypeId::Alt, begin, end) {
33
34    }
35};
36
37/**
38 * @brief makeAlt
39 *
40 * Build an Alt, flattening alternative subgroups, and combining character classes and
41 * move character classes towards the end of the list to ensure that all combinations are found.
42 *
43 * @param list
44 * @return simplified RE representing the Alt
45 */
46
47inline Alt * makeAlt() {
48    return new Alt();
49}
50
51template<typename iterator>
52RE * makeAlt(iterator begin, iterator end) {
53    Alt * newAlt = makeAlt();
54    CC * unionCC = nullptr;
55    for (auto i = begin; i != end; ++i) {
56        if (CC * cc = llvm::dyn_cast<CC>(*i)) {
57            unionCC = unionCC ? makeCC(unionCC, cc) : cc;
58        } else if (const Alt * alt = llvm::dyn_cast<Alt>(*i)) {
59            // We have an Alt to embed within the alt.  We extract the individual
60            // elements to include within the new alt.   Note that recursive flattening
61            // is not required, if the elements themselves were created with makeAlt.
62            for (RE * a : *alt) {
63                if (CC * cc = llvm::dyn_cast<CC>(a)) {
64                    unionCC = unionCC ? makeCC(unionCC, cc) : cc;
65                } else {
66                    newAlt->push_back(a);
67                }
68            }
69        }
70        else {
71            newAlt->push_back(*i);
72        }
73    }
74    if (unionCC) {
75        newAlt->push_back(unionCC);
76    }
77    if (newAlt->size() == 1) return newAlt->front();
78    return newAlt;
79}
80
81inline RE * makeAlt(RE::InitializerList list) {
82    return makeAlt(list.begin(), list.end());
83}
84
85}
86
87#endif // ALT_H
88
Note: See TracBrowser for help on using the repository browser.