1 /*
2 * Copyright (c) 2021 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 #ifndef PANDA_VERIFICATION_DEBUG_OPTIONS_MSG_SET_PARSER_H_
17 #define PANDA_VERIFICATION_DEBUG_OPTIONS_MSG_SET_PARSER_H_
18
19 #include "verification/debug/parser/parser.h"
20 #include "verifier_messages.h"
21
22 namespace panda::verifier::debug {
23
24 template <typename Context, typename String>
NameHandler()25 const auto &NameHandler()
26 {
27 using panda::parser::action;
28
29 static const auto NAME_HANDLER = [](action a, Context &c, auto from, auto to) {
30 if (a == action::PARSED) {
31 auto name = String {from, to};
32 size_t num = static_cast<size_t>(panda::verifier::StringToVerifierMessage(name));
33 c.stack.push_back(std::make_pair(num, num));
34 }
35 return true;
36 };
37
38 return NAME_HANDLER;
39 }
40
41 template <typename Context>
NumHandler()42 const auto &NumHandler()
43 {
44 using panda::parser::action;
45
46 static const auto NUM_HANDLER = [](action a, Context &c, auto from) {
47 if (a == action::PARSED) {
48 size_t num = std::strtol(from, nullptr, 0);
49 c.stack.push_back(std::make_pair(num, num));
50 }
51 return true;
52 };
53
54 return NUM_HANDLER;
55 }
56
57 template <typename Context>
RangeHandler()58 const auto &RangeHandler()
59 {
60 using panda::parser::action;
61
62 static const auto RANGE_HANDLER = [](action a, Context &c) {
63 if (a == action::PARSED) {
64 auto num_end = c.stack.back();
65 c.stack.pop_back();
66 auto num_start = c.stack.back();
67 c.stack.pop_back();
68
69 c.stack.push_back(std::make_pair(num_start.first, num_end.first));
70 }
71 return true;
72 };
73
74 return RANGE_HANDLER;
75 }
76
77 template <typename Context>
ItemHandler()78 const auto &ItemHandler()
79 {
80 using panda::parser::action;
81
82 static const auto ITEM_HANDLER = [](action a, Context &c) {
83 if (a == action::START) {
84 c.stack.clear();
85 }
86 if (a == action::PARSED) {
87 auto range = c.stack.back();
88 c.stack.pop_back();
89
90 for (auto i = range.first; i <= range.second; ++i) {
91 c.nums.insert(i);
92 }
93 }
94 return true;
95 };
96
97 return ITEM_HANDLER;
98 }
99
100 template <typename Context, typename String>
MessageSetParser()101 const auto &MessageSetParser()
102 {
103 using panda::parser::action;
104 using panda::parser::charset;
105 using panda::parser::parser;
106
107 using p = parser<Context, const char, const char *>;
108 using p1 = typename p::p;
109 using p2 = typename p1::p;
110 using p3 = typename p2::p;
111 using p4 = typename p3::p;
112
113 static const auto WS = p::of_charset(" \t\r\n");
114 static const auto COMMA = p1::of_charset(",");
115 static const auto DEC = p2::of_charset("0123456789");
116
117 static const auto NAME = p3::of_charset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789") |=
118 NameHandler<Context, String>();
119
120 static const auto NUM = DEC |= NumHandler<Context>();
121
122 static const auto MSG = NUM | NAME;
123
124 static const auto RANGE_DELIM = ~WS >> p4::of_string("-") >> ~WS;
125
126 static const auto MSG_RANGE = MSG >> RANGE_DELIM >> MSG |= RangeHandler<Context>();
127
128 static const auto ITEM = (~WS >> MSG_RANGE >> ~WS | ~WS >> MSG >> ~WS |= ItemHandler<Context>()) >> ~COMMA;
129
130 // here should be ITEMS = *ITEM, but due to clang-tidy bug, used lambda instead
131 static const auto ITEMS = [](Context &c, const char *&start, const char *end) {
132 while (true) {
133 auto saved = start;
134 if (!ITEM(c, start, end)) {
135 start = saved;
136 break;
137 }
138 }
139 return true;
140 };
141
142 return ITEMS;
143 }
144
145 } // namespace panda::verifier::debug
146
147 #endif // PANDA_VERIFICATION_DEBUG_OPTIONS_MSG_SET_PARSER_H_
148