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