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

Last change on this file since 5775 was 5775, checked in by cameron, 19 months ago

makeAlt should combine CCs as advertised, but should not recursively flatten

File size: 2.1 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();
54    CC * unionCC = makeCC();
55    for (auto i = begin; i != end; ++i) {
56        if (const CC * cc = llvm::dyn_cast<CC>(*i)) {
57            unionCC = makeCC(unionCC, 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 = makeCC(unionCC, cc);
65                }
66                else newAlt->push_back(a);
67            }
[4203]68        }
[5775]69        else {
70            newAlt->push_back(*i);
71        }
[4203]72    }
[5775]73    if (!unionCC->empty()) newAlt->push_back(unionCC);
74    return newAlt;
[4194]75}
76
[4203]77inline RE * makeAlt(RE::InitializerList list) {
78    return makeAlt(list.begin(), list.end());
[4194]79}
80
[4203]81}
82
[3850]83#endif // ALT_H
84
Note: See TracBrowser for help on using the repository browser.