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