1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2017 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#ifndef SKSL_REGEXNODE
9cb93a386Sopenharmony_ci#define SKSL_REGEXNODE
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ci#include <string>
12cb93a386Sopenharmony_ci#include <vector>
13cb93a386Sopenharmony_ci
14cb93a386Sopenharmony_cistruct NFA;
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ci/**
17cb93a386Sopenharmony_ci * Represents a node in the parse tree of a regular expression.
18cb93a386Sopenharmony_ci */
19cb93a386Sopenharmony_cistruct RegexNode {
20cb93a386Sopenharmony_ci    enum Kind {
21cb93a386Sopenharmony_ci        kChar_Kind,
22cb93a386Sopenharmony_ci        kCharset_Kind,
23cb93a386Sopenharmony_ci        kConcat_Kind,
24cb93a386Sopenharmony_ci        kDot_Kind,
25cb93a386Sopenharmony_ci        kOr_Kind,
26cb93a386Sopenharmony_ci        kPlus_Kind,
27cb93a386Sopenharmony_ci        kRange_Kind,
28cb93a386Sopenharmony_ci        kQuestion_Kind,
29cb93a386Sopenharmony_ci        kStar_Kind
30cb93a386Sopenharmony_ci    };
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ci    RegexNode(Kind kind)
33cb93a386Sopenharmony_ci    : fKind(kind) {}
34cb93a386Sopenharmony_ci
35cb93a386Sopenharmony_ci    RegexNode(Kind kind, char payload)
36cb93a386Sopenharmony_ci    : fKind(kind) {
37cb93a386Sopenharmony_ci        fPayload.fChar = payload;
38cb93a386Sopenharmony_ci    }
39cb93a386Sopenharmony_ci
40cb93a386Sopenharmony_ci    RegexNode(Kind kind, const char* children)
41cb93a386Sopenharmony_ci    : fKind(kind) {
42cb93a386Sopenharmony_ci        fPayload.fBool = false;
43cb93a386Sopenharmony_ci        while (*children != '\0') {
44cb93a386Sopenharmony_ci            fChildren.emplace_back(kChar_Kind, *children);
45cb93a386Sopenharmony_ci            ++children;
46cb93a386Sopenharmony_ci        }
47cb93a386Sopenharmony_ci    }
48cb93a386Sopenharmony_ci
49cb93a386Sopenharmony_ci    RegexNode(Kind kind, RegexNode child)
50cb93a386Sopenharmony_ci    : fKind(kind) {
51cb93a386Sopenharmony_ci        fChildren.push_back(std::move(child));
52cb93a386Sopenharmony_ci    }
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_ci    RegexNode(Kind kind, RegexNode child1, RegexNode child2)
55cb93a386Sopenharmony_ci    : fKind(kind) {
56cb93a386Sopenharmony_ci        fChildren.push_back(std::move(child1));
57cb93a386Sopenharmony_ci        fChildren.push_back(std::move(child2));
58cb93a386Sopenharmony_ci    }
59cb93a386Sopenharmony_ci
60cb93a386Sopenharmony_ci    /**
61cb93a386Sopenharmony_ci     * Creates NFA states for this node, with a successful match against this node resulting in a
62cb93a386Sopenharmony_ci     * transition to all of the states in the accept vector.
63cb93a386Sopenharmony_ci     */
64cb93a386Sopenharmony_ci    std::vector<int> createStates(NFA* nfa, const std::vector<int>& accept) const;
65cb93a386Sopenharmony_ci
66cb93a386Sopenharmony_ci    std::string description() const;
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ci    Kind fKind;
69cb93a386Sopenharmony_ci
70cb93a386Sopenharmony_ci    union Payload {
71cb93a386Sopenharmony_ci        char fChar;
72cb93a386Sopenharmony_ci        bool fBool;
73cb93a386Sopenharmony_ci    } fPayload;
74cb93a386Sopenharmony_ci
75cb93a386Sopenharmony_ci    std::vector<RegexNode> fChildren;
76cb93a386Sopenharmony_ci};
77cb93a386Sopenharmony_ci
78cb93a386Sopenharmony_ci#endif
79