xref: /third_party/skia/src/sksl/lex/RegexNode.cpp (revision cb93a386)
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#include "src/sksl/lex/RegexNode.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "src/sksl/lex/NFA.h"
11cb93a386Sopenharmony_ci
12cb93a386Sopenharmony_cistd::vector<int> RegexNode::createStates(NFA* nfa, const std::vector<int>& accept) const {
13cb93a386Sopenharmony_ci    std::vector<int> result;
14cb93a386Sopenharmony_ci    switch (fKind) {
15cb93a386Sopenharmony_ci        case kChar_Kind:
16cb93a386Sopenharmony_ci            result.push_back(nfa->addState(NFAState(fPayload.fChar, accept)));
17cb93a386Sopenharmony_ci            break;
18cb93a386Sopenharmony_ci        case kCharset_Kind: {
19cb93a386Sopenharmony_ci            std::vector<bool> chars;
20cb93a386Sopenharmony_ci            for (const RegexNode& child : fChildren) {
21cb93a386Sopenharmony_ci                if (child.fKind == kChar_Kind) {
22cb93a386Sopenharmony_ci                    while (chars.size() <= (size_t) child.fPayload.fChar) {
23cb93a386Sopenharmony_ci                        chars.push_back(false);
24cb93a386Sopenharmony_ci                    }
25cb93a386Sopenharmony_ci                    chars[child.fPayload.fChar] = true;
26cb93a386Sopenharmony_ci                } else {
27cb93a386Sopenharmony_ci                    SkASSERT(child.fKind == kRange_Kind);
28cb93a386Sopenharmony_ci                    while (chars.size() <= (size_t) child.fChildren[1].fPayload.fChar) {
29cb93a386Sopenharmony_ci                        chars.push_back(false);
30cb93a386Sopenharmony_ci                    }
31cb93a386Sopenharmony_ci                    for (char c = child.fChildren[0].fPayload.fChar;
32cb93a386Sopenharmony_ci                         c <= child.fChildren[1].fPayload.fChar;
33cb93a386Sopenharmony_ci                         ++c) {
34cb93a386Sopenharmony_ci                        chars[c] = true;
35cb93a386Sopenharmony_ci                    }
36cb93a386Sopenharmony_ci                }
37cb93a386Sopenharmony_ci            }
38cb93a386Sopenharmony_ci            result.push_back(nfa->addState(NFAState(fPayload.fBool, chars, accept)));
39cb93a386Sopenharmony_ci            break;
40cb93a386Sopenharmony_ci        }
41cb93a386Sopenharmony_ci        case kConcat_Kind: {
42cb93a386Sopenharmony_ci            std::vector<int> right = fChildren[1].createStates(nfa, accept);
43cb93a386Sopenharmony_ci            result = fChildren[0].createStates(nfa, right);
44cb93a386Sopenharmony_ci            break;
45cb93a386Sopenharmony_ci        }
46cb93a386Sopenharmony_ci        case kDot_Kind:
47cb93a386Sopenharmony_ci            result.push_back(nfa->addState(NFAState(NFAState::kDot_Kind, accept)));
48cb93a386Sopenharmony_ci            break;
49cb93a386Sopenharmony_ci        case kOr_Kind: {
50cb93a386Sopenharmony_ci            std::vector<int> states = fChildren[0].createStates(nfa, accept);
51cb93a386Sopenharmony_ci            result.insert(result.end(), states.begin(), states.end());
52cb93a386Sopenharmony_ci            states = fChildren[1].createStates(nfa, accept);
53cb93a386Sopenharmony_ci            result.insert(result.end(), states.begin(), states.end());
54cb93a386Sopenharmony_ci            break;
55cb93a386Sopenharmony_ci        }
56cb93a386Sopenharmony_ci        case kPlus_Kind: {
57cb93a386Sopenharmony_ci            std::vector<int> next = accept;
58cb93a386Sopenharmony_ci            std::vector<int> placeholder;
59cb93a386Sopenharmony_ci            int id = nfa->addState(NFAState(placeholder));
60cb93a386Sopenharmony_ci            next.push_back(id);
61cb93a386Sopenharmony_ci            result = fChildren[0].createStates(nfa, next);
62cb93a386Sopenharmony_ci            nfa->fStates[id] = NFAState(result);
63cb93a386Sopenharmony_ci            break;
64cb93a386Sopenharmony_ci        }
65cb93a386Sopenharmony_ci        case kQuestion_Kind:
66cb93a386Sopenharmony_ci            result = fChildren[0].createStates(nfa, accept);
67cb93a386Sopenharmony_ci            result.insert(result.end(), accept.begin(), accept.end());
68cb93a386Sopenharmony_ci            break;
69cb93a386Sopenharmony_ci        case kRange_Kind:
70cb93a386Sopenharmony_ci            SkUNREACHABLE;
71cb93a386Sopenharmony_ci        case kStar_Kind: {
72cb93a386Sopenharmony_ci            std::vector<int> next = accept;
73cb93a386Sopenharmony_ci            std::vector<int> placeholder;
74cb93a386Sopenharmony_ci            int id = nfa->addState(NFAState(placeholder));
75cb93a386Sopenharmony_ci            next.push_back(id);
76cb93a386Sopenharmony_ci            result = fChildren[0].createStates(nfa, next);
77cb93a386Sopenharmony_ci            result.insert(result.end(), accept.begin(), accept.end());
78cb93a386Sopenharmony_ci            nfa->fStates[id] = NFAState(result);
79cb93a386Sopenharmony_ci            break;
80cb93a386Sopenharmony_ci        }
81cb93a386Sopenharmony_ci    }
82cb93a386Sopenharmony_ci    return result;
83cb93a386Sopenharmony_ci}
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ci#ifdef SK_DEBUG
86cb93a386Sopenharmony_cistd::string RegexNode::description() const {
87cb93a386Sopenharmony_ci    switch (fKind) {
88cb93a386Sopenharmony_ci        case kChar_Kind:
89cb93a386Sopenharmony_ci            return std::string(1, fPayload.fChar);
90cb93a386Sopenharmony_ci        case kCharset_Kind: {
91cb93a386Sopenharmony_ci            std::string result("[");
92cb93a386Sopenharmony_ci            if (fPayload.fBool) {
93cb93a386Sopenharmony_ci                result += "^";
94cb93a386Sopenharmony_ci            }
95cb93a386Sopenharmony_ci            for (const RegexNode& c : fChildren) {
96cb93a386Sopenharmony_ci                result += c.description();
97cb93a386Sopenharmony_ci            }
98cb93a386Sopenharmony_ci            result += "]";
99cb93a386Sopenharmony_ci            return result;
100cb93a386Sopenharmony_ci        }
101cb93a386Sopenharmony_ci        case kConcat_Kind:
102cb93a386Sopenharmony_ci            return fChildren[0].description() + fChildren[1].description();
103cb93a386Sopenharmony_ci        case kDot_Kind:
104cb93a386Sopenharmony_ci            return ".";
105cb93a386Sopenharmony_ci        case kOr_Kind:
106cb93a386Sopenharmony_ci            return "(" + fChildren[0].description() + "|" + fChildren[1].description() + ")";
107cb93a386Sopenharmony_ci        case kPlus_Kind:
108cb93a386Sopenharmony_ci            return fChildren[0].description() + "+";
109cb93a386Sopenharmony_ci        case kQuestion_Kind:
110cb93a386Sopenharmony_ci            return fChildren[0].description() + "?";
111cb93a386Sopenharmony_ci        case kRange_Kind:
112cb93a386Sopenharmony_ci            return fChildren[0].description() + "-" + fChildren[1].description();
113cb93a386Sopenharmony_ci        case kStar_Kind:
114cb93a386Sopenharmony_ci            return fChildren[0].description() + "*";
115cb93a386Sopenharmony_ci        default:
116cb93a386Sopenharmony_ci            return "<" + std::to_string(fKind) + ">";
117cb93a386Sopenharmony_ci    }
118cb93a386Sopenharmony_ci}
119cb93a386Sopenharmony_ci#endif
120