aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sksl/lex/RegexNode.h
blob: e3aa65b3d125a9417985d5466863be60827f523a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SKSL_REGEXNODE
#define SKSL_REGEXNODE

#include <string>
#include <vector>

struct NFA;

/**
 * Represents a node in the parse tree of a regular expression.
 */
struct RegexNode {
    enum Kind {
        kChar_Kind,
        kCharset_Kind,
        kConcat_Kind,
        kDot_Kind,
        kOr_Kind,
        kPlus_Kind,
        kRange_Kind,
        kQuestion_Kind,
        kStar_Kind
    };

    RegexNode(Kind kind)
    : fKind(kind) {}

    RegexNode(Kind kind, char payload)
    : fKind(kind) {
        fPayload.fChar = payload;
    }

    RegexNode(Kind kind, const char* children)
    : fKind(kind) {
        fPayload.fBool = false;
        while (*children != '\0') {
            fChildren.emplace_back(kChar_Kind, *children);
            ++children;
        }
    }

    RegexNode(Kind kind, RegexNode child)
    : fKind(kind) {
        fChildren.push_back(std::move(child));
    }

    RegexNode(Kind kind, RegexNode child1, RegexNode child2)
    : fKind(kind) {
        fChildren.push_back(std::move(child1));
        fChildren.push_back(std::move(child2));
    }

    /**
     * Creates NFA states for this node, with a successful match against this node resulting in a
     * transition to all of the states in the accept vector.
     */
    std::vector<int> createStates(NFA* nfa, const std::vector<int>& accept) const;

    std::string description() const;

    Kind fKind;

    union Payload {
        char fChar;
        bool fBool;
    } fPayload;

    std::vector<RegexNode> fChildren;
};

#endif