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_NFASTATE 9cb93a386Sopenharmony_ci#define SKSL_NFASTATE 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include <string> 12cb93a386Sopenharmony_ci#include <vector> 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_ci#include "src/sksl/lex/LexUtil.h" 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_cistruct NFAState { 17cb93a386Sopenharmony_ci enum Kind { 18cb93a386Sopenharmony_ci // represents an accept state - if the NFA ends up in this state, we have successfully 19cb93a386Sopenharmony_ci // matched the token indicated by fData[0] 20cb93a386Sopenharmony_ci kAccept_Kind, 21cb93a386Sopenharmony_ci // matches the single character fChar 22cb93a386Sopenharmony_ci kChar_Kind, 23cb93a386Sopenharmony_ci // the regex '.'; matches any char but '\n' 24cb93a386Sopenharmony_ci kDot_Kind, 25cb93a386Sopenharmony_ci // a state which serves as a placeholder for the states indicated in fData. When we 26cb93a386Sopenharmony_ci // transition to this state, we instead transition to all of the fData states. 27cb93a386Sopenharmony_ci kRemapped_Kind, 28cb93a386Sopenharmony_ci // contains a list of true/false values in fData. fData[c] tells us whether we accept the 29cb93a386Sopenharmony_ci // character c. 30cb93a386Sopenharmony_ci kTable_Kind 31cb93a386Sopenharmony_ci }; 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci NFAState(Kind kind, std::vector<int> next) 34cb93a386Sopenharmony_ci : fKind(kind) 35cb93a386Sopenharmony_ci , fNext(std::move(next)) {} 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci NFAState(char c, std::vector<int> next) 38cb93a386Sopenharmony_ci : fKind(kChar_Kind) 39cb93a386Sopenharmony_ci , fChar(c) 40cb93a386Sopenharmony_ci , fNext(std::move(next)) {} 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci NFAState(std::vector<int> states) 43cb93a386Sopenharmony_ci : fKind(kRemapped_Kind) 44cb93a386Sopenharmony_ci , fData(std::move(states)) {} 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ci NFAState(bool inverse, std::vector<bool> accepts, std::vector<int> next) 47cb93a386Sopenharmony_ci : fKind(kTable_Kind) 48cb93a386Sopenharmony_ci , fInverse(inverse) 49cb93a386Sopenharmony_ci , fNext(std::move(next)) { 50cb93a386Sopenharmony_ci for (bool b : accepts) { 51cb93a386Sopenharmony_ci fData.push_back(b); 52cb93a386Sopenharmony_ci } 53cb93a386Sopenharmony_ci } 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ci NFAState(int token) 56cb93a386Sopenharmony_ci : fKind(kAccept_Kind) { 57cb93a386Sopenharmony_ci fData.push_back(token); 58cb93a386Sopenharmony_ci } 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci bool accept(char c) const { 61cb93a386Sopenharmony_ci switch (fKind) { 62cb93a386Sopenharmony_ci case kAccept_Kind: 63cb93a386Sopenharmony_ci return false; 64cb93a386Sopenharmony_ci case kChar_Kind: 65cb93a386Sopenharmony_ci return c == fChar; 66cb93a386Sopenharmony_ci case kDot_Kind: 67cb93a386Sopenharmony_ci return c != '\n'; 68cb93a386Sopenharmony_ci case kTable_Kind: { 69cb93a386Sopenharmony_ci bool value; 70cb93a386Sopenharmony_ci if ((size_t) c < fData.size()) { 71cb93a386Sopenharmony_ci value = fData[c]; 72cb93a386Sopenharmony_ci } else { 73cb93a386Sopenharmony_ci value = false; 74cb93a386Sopenharmony_ci } 75cb93a386Sopenharmony_ci return value != fInverse; 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci default: 78cb93a386Sopenharmony_ci SkUNREACHABLE; 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci } 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci#ifdef SK_DEBUG 83cb93a386Sopenharmony_ci std::string description() const { 84cb93a386Sopenharmony_ci switch (fKind) { 85cb93a386Sopenharmony_ci case kAccept_Kind: 86cb93a386Sopenharmony_ci return "Accept(" + std::to_string(fData[0]) + ")"; 87cb93a386Sopenharmony_ci case kChar_Kind: { 88cb93a386Sopenharmony_ci std::string result = "Char('" + std::string(1, fChar) + "'"; 89cb93a386Sopenharmony_ci for (int v : fNext) { 90cb93a386Sopenharmony_ci result += ", "; 91cb93a386Sopenharmony_ci result += std::to_string(v); 92cb93a386Sopenharmony_ci } 93cb93a386Sopenharmony_ci result += ")"; 94cb93a386Sopenharmony_ci return result; 95cb93a386Sopenharmony_ci } 96cb93a386Sopenharmony_ci case kDot_Kind: { 97cb93a386Sopenharmony_ci std::string result = "Dot("; 98cb93a386Sopenharmony_ci const char* separator = ""; 99cb93a386Sopenharmony_ci for (int v : fNext) { 100cb93a386Sopenharmony_ci result += separator; 101cb93a386Sopenharmony_ci result += std::to_string(v); 102cb93a386Sopenharmony_ci separator = ", "; 103cb93a386Sopenharmony_ci } 104cb93a386Sopenharmony_ci result += ")"; 105cb93a386Sopenharmony_ci return result; 106cb93a386Sopenharmony_ci } 107cb93a386Sopenharmony_ci case kRemapped_Kind: { 108cb93a386Sopenharmony_ci std::string result = "Remapped("; 109cb93a386Sopenharmony_ci const char* separator = ""; 110cb93a386Sopenharmony_ci for (int v : fData) { 111cb93a386Sopenharmony_ci result += separator; 112cb93a386Sopenharmony_ci result += std::to_string(v); 113cb93a386Sopenharmony_ci separator = ", "; 114cb93a386Sopenharmony_ci } 115cb93a386Sopenharmony_ci result += ")"; 116cb93a386Sopenharmony_ci return result; 117cb93a386Sopenharmony_ci } 118cb93a386Sopenharmony_ci case kTable_Kind: { 119cb93a386Sopenharmony_ci std::string result = std::string("Table(") + (fInverse ? "true" : "false") + ", ["; 120cb93a386Sopenharmony_ci const char* separator = ""; 121cb93a386Sopenharmony_ci for (int v : fData) { 122cb93a386Sopenharmony_ci result += separator; 123cb93a386Sopenharmony_ci result += v ? "true" : "false"; 124cb93a386Sopenharmony_ci separator = ", "; 125cb93a386Sopenharmony_ci } 126cb93a386Sopenharmony_ci result += "]"; 127cb93a386Sopenharmony_ci for (int n : fNext) { 128cb93a386Sopenharmony_ci result += ", "; 129cb93a386Sopenharmony_ci result += std::to_string(n); 130cb93a386Sopenharmony_ci } 131cb93a386Sopenharmony_ci result += ")"; 132cb93a386Sopenharmony_ci return result; 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci default: 135cb93a386Sopenharmony_ci SkUNREACHABLE; 136cb93a386Sopenharmony_ci } 137cb93a386Sopenharmony_ci } 138cb93a386Sopenharmony_ci#endif 139cb93a386Sopenharmony_ci 140cb93a386Sopenharmony_ci Kind fKind; 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ci char fChar = 0; 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ci bool fInverse = false; 145cb93a386Sopenharmony_ci 146cb93a386Sopenharmony_ci std::vector<int> fData; 147cb93a386Sopenharmony_ci 148cb93a386Sopenharmony_ci // states we transition to upon a succesful match from this state 149cb93a386Sopenharmony_ci std::vector<int> fNext; 150cb93a386Sopenharmony_ci}; 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_ci#endif 153