1 /**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <string>
17
18 #include <gtest/gtest.h>
19
20 #include "util/parser/parser.h"
21
22 namespace panda::parser::test {
23 namespace {
24 struct Context {};
25 struct smth;
26
__anonddcd0bc60202(Action act, Context &, auto &it) 27 static const auto FOO = [](Action act, [[maybe_unused]] Context &, auto &it) {
28 switch (act) {
29 case Action::START:
30 if (*it != 'f') {
31 return false;
32 }
33 ++it;
34 if (*it != 'o') {
35 return false;
36 }
37 ++it;
38 if (*it != 'o') {
39 return false;
40 }
41 ++it;
42 return true;
43
44 case Action::CANCEL:
45 return true;
46
47 case Action::PARSED:
48 return true;
49 default:
50 UNREACHABLE();
51 return false;
52 }
53 };
54
__anonddcd0bc60302(Action act, Context &, auto &it) 55 static const auto BAR = [](Action act, [[maybe_unused]] Context &, auto &it) {
56 switch (act) {
57 case Action::START:
58 if (*it != 'b') {
59 return false;
60 }
61 ++it;
62 if (*it != 'a') {
63 return false;
64 }
65 ++it;
66 if (*it != 'r') {
67 return false;
68 }
69 ++it;
70 return true;
71
72 case Action::CANCEL:
73 return true;
74
75 case Action::PARSED:
76 return true;
77 default:
78 UNREACHABLE();
79 return false;
80 }
81 };
82
83 using P = typename Parser<Context, const char, const char *>::template Next<smth>;
84 using P1 = typename P::P;
85 using P2 = typename P1::P;
86 using P3 = typename P2::P;
87 using P4 = typename P3::P;
88 using P5 = typename P4::P;
89 using P6 = typename P5::P;
90
91 using It = const char *;
92 } // namespace
93
TEST(VerifierParserTest,Parser)94 TEST(VerifierParserTest, Parser)
95 {
96 Context cont;
97
98 static const auto ABCP = P::OfCharset(Charset {"abcABC"});
99 static const auto DEFP = P1::OfCharset(Charset {"defDEF"});
100 static const auto STRINGP = P2::OfString("string");
101 std::string aBc {"aBc"};
102 It start = &(aBc[0]);
103 It end = &(aBc[3]);
104 EXPECT_TRUE(ABCP(cont, start, end));
105 start = &(aBc[1]);
106 EXPECT_TRUE(ABCP(cont, start, end));
107 start = &(aBc[0]);
108 EXPECT_FALSE(DEFP(cont, start, end));
109 start = &(aBc[0]);
110 EXPECT_FALSE(STRINGP(cont, start, end));
111 std::string string {"string"};
112 start = &(string[0]);
113 end = &(string[6]);
114 EXPECT_FALSE(ABCP(cont, start, end));
115 start = &(string[0]);
116 EXPECT_FALSE(DEFP(cont, start, end));
117 start = &(string[0]);
118 EXPECT_TRUE(STRINGP(cont, start, end));
119 std::string d {"d"};
120 start = &(d[0]);
121 end = &(d[1]);
122 EXPECT_FALSE(ABCP(cont, start, end));
123 start = &(d[0]);
124 EXPECT_TRUE(DEFP(cont, start, end));
125 start = &(d[0]);
126 EXPECT_FALSE(STRINGP(cont, start, end));
127 start = &(string[0]);
128 end = &(string[3]);
129 EXPECT_FALSE(ABCP(cont, start, end));
130 start = &(string[0]);
131 EXPECT_FALSE(DEFP(cont, start, end));
132 start = &(string[0]);
133 EXPECT_FALSE(STRINGP(cont, start, end));
134
135 static const auto ENDP = P3::End();
136 start = &(string[0]);
137 end = &(string[0]);
138 EXPECT_TRUE(ENDP(cont, start, end));
139 end = &(string[2]);
140 EXPECT_FALSE(ENDP(cont, start, end));
141
142 static const auto ACSTRINGP = ~ABCP >> STRINGP;
143 start = &(string[0]);
144 end = &(string[6]);
145 EXPECT_TRUE(ACSTRINGP(cont, start, end));
146 std::string acstring {"ACstring"};
147 start = &(acstring[0]);
148 end = &(acstring[8]);
149 EXPECT_TRUE(ACSTRINGP(cont, start, end));
150 end = &(acstring[7]);
151 EXPECT_FALSE(ACSTRINGP(cont, start, end));
152
153 static const auto FOOABCP = ABCP |= FOO;
154 static const auto BARABCP = ABCP |= BAR;
155 start = &(string[0]);
156 end = &(string[6]);
157 EXPECT_FALSE(FOOABCP(cont, start, end));
158 std::string fooAcB {"fooAcB"};
159 start = &(fooAcB[0]);
160 end = &(fooAcB[6]);
161 EXPECT_TRUE(FOOABCP(cont, start, end));
162 start = &(fooAcB[0]);
163 EXPECT_FALSE(BARABCP(cont, start, end));
164
165 static const auto ABCDEFP = ABCP | DEFP;
166 start = &(aBc[0]);
167 end = &(aBc[3]);
168 EXPECT_TRUE(ABCDEFP(cont, start, end));
169 start = &(string[0]);
170 end = &(string[6]);
171 EXPECT_FALSE(ABCDEFP(cont, start, end));
172 start = &(d[0]);
173 end = &(d[1]);
174 EXPECT_TRUE(ABCDEFP(cont, start, end));
175
176 static const auto EMPTYP = ABCP & DEFP;
177 start = &(aBc[0]);
178 end = &(aBc[3]);
179 EXPECT_FALSE(EMPTYP(cont, start, end));
180 start = &(string[0]);
181 end = &(string[6]);
182 EXPECT_FALSE(EMPTYP(cont, start, end));
183 start = &(d[0]);
184 end = &(d[1]);
185 EXPECT_FALSE(EMPTYP(cont, start, end));
186
187 static const auto ABC2P = ABCP << STRINGP >> STRINGP;
188 start = &(acstring[0]);
189 end = &(acstring[8]);
190 EXPECT_TRUE(ABC2P(cont, start, end));
191 start = &(string[0]);
192 end = &(string[6]);
193 EXPECT_FALSE(ABC2P(cont, start, end));
194 start = &(d[0]);
195 end = &(d[1]);
196 EXPECT_FALSE(ABC2P(cont, start, end));
197
198 static const auto NOABCP = !ABCP;
199 start = &(aBc[0]);
200 end = &(aBc[3]);
201 EXPECT_FALSE(NOABCP(cont, start, end));
202 start = &(string[0]);
203 end = &(string[6]);
204 EXPECT_TRUE(NOABCP(cont, start, end));
205 start = &(d[0]);
206 end = &(d[1]);
207 EXPECT_TRUE(NOABCP(cont, start, end));
208
209 static const auto STRINGSTRINGENDP = *STRINGP >> ENDP;
210 static const auto STRINGENDP = STRINGP >> ENDP;
211 std::string stringstring {"stringstring"};
212 start = &(stringstring[0]);
213 end = &(stringstring[12]);
214 EXPECT_FALSE(STRINGENDP(cont, start, end));
215 start = &(stringstring[0]);
216 EXPECT_TRUE(STRINGSTRINGENDP(cont, start, end));
217 }
218 } // namespace panda::parser::test