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 };
26 struct smth;
27
__anon3578ab070202(action act, Context &, auto &it) 28 static const auto FOO = [](action act, [[maybe_unused]] Context &, auto &it) {
29 switch (act) {
30 case action::START:
31 if (*it != 'f') {
32 return false;
33 }
34 ++it;
35 if (*it != 'o') {
36 return false;
37 }
38 ++it;
39 if (*it != 'o') {
40 return false;
41 }
42 ++it;
43 return true;
44
45 case action::CANCEL:
46 return true;
47
48 case action::PARSED:
49 return true;
50 default:
51 UNREACHABLE();
52 return false;
53 }
54 };
55
__anon3578ab070302(action act, Context &, auto &it) 56 static const auto BAR = [](action act, [[maybe_unused]] Context &, auto &it) {
57 switch (act) {
58 case action::START:
59 if (*it != 'b') {
60 return false;
61 }
62 ++it;
63 if (*it != 'a') {
64 return false;
65 }
66 ++it;
67 if (*it != 'r') {
68 return false;
69 }
70 ++it;
71 return true;
72
73 case action::CANCEL:
74 return true;
75
76 case action::PARSED:
77 return true;
78 default:
79 UNREACHABLE();
80 return false;
81 }
82 };
83
84 using p = typename parser<Context, const char, const char *>::template next<smth>;
85 using p1 = typename p::p;
86 using p2 = typename p1::p;
87 using p3 = typename p2::p;
88 using p4 = typename p3::p;
89 using p5 = typename p4::p;
90 using p6 = typename p5::p;
91
92 using it = const char *;
93 } // namespace
94
TEST(VerifierParserTest,Parser)95 TEST(VerifierParserTest, Parser)
96 {
97 Context cont;
98
99 static const auto abcp = p::of_charset(charset {"abcABC"});
100 static const auto defp = p1::of_charset(charset {"defDEF"});
101 static const auto stringp = p2::of_string("string");
102 std::string aBc {"aBc"};
103 it start = &(aBc[0]);
104 it end = &(aBc[3]);
105 EXPECT_TRUE(abcp(cont, start, end));
106 start = &(aBc[1]);
107 EXPECT_TRUE(abcp(cont, start, end));
108 start = &(aBc[0]);
109 EXPECT_FALSE(defp(cont, start, end));
110 start = &(aBc[0]);
111 EXPECT_FALSE(stringp(cont, start, end));
112 std::string string {"string"};
113 start = &(string[0]);
114 end = &(string[6]);
115 EXPECT_FALSE(abcp(cont, start, end));
116 start = &(string[0]);
117 EXPECT_FALSE(defp(cont, start, end));
118 start = &(string[0]);
119 EXPECT_TRUE(stringp(cont, start, end));
120 std::string d {"d"};
121 start = &(d[0]);
122 end = &(d[1]);
123 EXPECT_FALSE(abcp(cont, start, end));
124 start = &(d[0]);
125 EXPECT_TRUE(defp(cont, start, end));
126 start = &(d[0]);
127 EXPECT_FALSE(stringp(cont, start, end));
128 start = &(string[0]);
129 end = &(string[3]);
130 EXPECT_FALSE(abcp(cont, start, end));
131 start = &(string[0]);
132 EXPECT_FALSE(defp(cont, start, end));
133 start = &(string[0]);
134 EXPECT_FALSE(stringp(cont, start, end));
135
136 static const auto endp = p3::end();
137 start = &(string[0]);
138 end = &(string[0]);
139 EXPECT_TRUE(endp(cont, start, end));
140 end = &(string[2]);
141 EXPECT_FALSE(endp(cont, start, end));
142
143 static const auto acstringp = ~abcp >> stringp;
144 start = &(string[0]);
145 end = &(string[6]);
146 EXPECT_TRUE(acstringp(cont, start, end));
147 std::string acstring {"ACstring"};
148 start = &(acstring[0]);
149 end = &(acstring[8]);
150 EXPECT_TRUE(acstringp(cont, start, end));
151 end = &(acstring[7]);
152 EXPECT_FALSE(acstringp(cont, start, end));
153
154 static const auto fooabcp = abcp |= FOO;
155 static const auto barabcp = abcp |= BAR;
156 start = &(string[0]);
157 end = &(string[6]);
158 EXPECT_FALSE(fooabcp(cont, start, end));
159 std::string fooAcB {"fooAcB"};
160 start = &(fooAcB[0]);
161 end = &(fooAcB[6]);
162 EXPECT_TRUE(fooabcp(cont, start, end));
163 start = &(fooAcB[0]);
164 EXPECT_FALSE(barabcp(cont, start, end));
165
166 static const auto abcdefp = abcp | defp;
167 start = &(aBc[0]);
168 end = &(aBc[3]);
169 EXPECT_TRUE(abcdefp(cont, start, end));
170 start = &(string[0]);
171 end = &(string[6]);
172 EXPECT_FALSE(abcdefp(cont, start, end));
173 start = &(d[0]);
174 end = &(d[1]);
175 EXPECT_TRUE(abcdefp(cont, start, end));
176
177 static const auto emptyp = abcp & defp;
178 start = &(aBc[0]);
179 end = &(aBc[3]);
180 EXPECT_FALSE(emptyp(cont, start, end));
181 start = &(string[0]);
182 end = &(string[6]);
183 EXPECT_FALSE(emptyp(cont, start, end));
184 start = &(d[0]);
185 end = &(d[1]);
186 EXPECT_FALSE(emptyp(cont, start, end));
187
188 static const auto abc2p = abcp << stringp >> stringp;
189 start = &(acstring[0]);
190 end = &(acstring[8]);
191 EXPECT_TRUE(abc2p(cont, start, end));
192 start = &(string[0]);
193 end = &(string[6]);
194 EXPECT_FALSE(abc2p(cont, start, end));
195 start = &(d[0]);
196 end = &(d[1]);
197 EXPECT_FALSE(abc2p(cont, start, end));
198
199 static const auto noabcp = !abcp;
200 start = &(aBc[0]);
201 end = &(aBc[3]);
202 EXPECT_FALSE(noabcp(cont, start, end));
203 start = &(string[0]);
204 end = &(string[6]);
205 EXPECT_TRUE(noabcp(cont, start, end));
206 start = &(d[0]);
207 end = &(d[1]);
208 EXPECT_TRUE(noabcp(cont, start, end));
209
210 static const auto stringstringendp = *stringp >> endp;
211 static const auto stringendp = stringp >> endp;
212 std::string stringstring {"stringstring"};
213 start = &(stringstring[0]);
214 end = &(stringstring[12]);
215 EXPECT_FALSE(stringendp(cont, start, end));
216 start = &(stringstring[0]);
217 EXPECT_TRUE(stringstringendp(cont, start, end));
218 }
219 } // namespace panda::parser::test