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

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

Restructuring step/tidy-up for re_passes

File size: 2.2 KB
RevLine 
[3850]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"
[5775]11#include "re_cc.h"
[5267]12#include <llvm/Support/Casting.h>
[3850]13
[4194]14namespace re {
[3914]15
[4194]16class Alt : public Vector {
[3850]17public:
[4194]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();
[4203]26    template<typename iterator> friend RE * makeAlt(iterator, iterator);
[4194]27    Alt()
28    : Vector(ClassTypeId::Alt) {
29
30    }
31    Alt(iterator begin, iterator end)
32    : Vector(ClassTypeId::Alt, begin, end) {
33
[4272]34    }
[3850]35};
36
[4203]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
[4194]47inline Alt * makeAlt() {
48    return new Alt();
49}
50
[4203]51template<typename iterator>
52RE * makeAlt(iterator begin, iterator end) {
[5775]53    Alt * newAlt = makeAlt();
[5782]54    CC * unionCC = nullptr;
[5775]55    for (auto i = begin; i != end; ++i) {
[5782]56        if (CC * cc = llvm::dyn_cast<CC>(*i)) {
57            unionCC = unionCC ? makeCC(unionCC, cc) : cc;
[5775]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)) {
[5782]64                    unionCC = unionCC ? makeCC(unionCC, cc) : cc;
65                } else {
66                    newAlt->push_back(a);
[5775]67                }
68            }
[4203]69        }
[5775]70        else {
71            newAlt->push_back(*i);
72        }
[4203]73    }
[5782]74    if (unionCC) {
75        newAlt->push_back(unionCC);
76    }
[5784]77    if (newAlt->size() == 1) return newAlt->front();
[5775]78    return newAlt;
[4194]79}
80
[4203]81inline RE * makeAlt(RE::InitializerList list) {
82    return makeAlt(list.begin(), list.end());
[4194]83}
84
[4203]85}
86
[3850]87#endif // ALT_H
88
Note: See TracBrowser for help on using the repository browser.