• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef PANDA_VERIFIER_DEBUG_MSG_SET_PARSER_H_
17 #define PANDA_VERIFIER_DEBUG_MSG_SET_PARSER_H_
18 
19 #include "runtime/include/mem/panda_containers.h"
20 #include "verification/util/parser/parser.h"
21 #include "verifier_messages.h"
22 
23 namespace panda::verifier::debug {
24 
25 struct MessageSetContext {
26     panda::PandaVector<std::pair<size_t, size_t>> stack;
27     panda::PandaUnorderedSet<size_t> nums;
28 };
29 
30 namespace {
31 using panda::parser::action;
32 
33 static const auto NAME_HANDLER = [](action a, MessageSetContext &c, auto from, auto to) {
34     if (a == action::PARSED) {
35         std::string_view name {from, static_cast<size_t>(to - from)};
36         size_t num = static_cast<size_t>(panda::verifier::StringToVerifierMessage(name));
37         c.stack.push_back(std::make_pair(num, num));
38     }
39     return true;
40 };
41 
42 static const auto NUM_HANDLER = [](action a, MessageSetContext &c, auto from) {
43     if (a == action::PARSED) {
44         size_t num = std::strtol(from, nullptr, 0);
45         c.stack.push_back(std::make_pair(num, num));
46     }
47     return true;
48 };
49 
50 static const auto RANGE_HANDLER = [](action a, MessageSetContext &c) {
51     if (a == action::PARSED) {
52         auto num_end = c.stack.back();
53         c.stack.pop_back();
54         auto num_start = c.stack.back();
55         c.stack.pop_back();
56 
57         c.stack.push_back(std::make_pair(num_start.first, num_end.first));
58     }
59     return true;
60 };
61 
62 static const auto ITEM_HANDLER = [](action a, MessageSetContext &c) {
63     if (a == action::START) {
64         c.stack.clear();
65     }
66     if (a == action::PARSED) {
67         auto range = c.stack.back();
68         c.stack.pop_back();
69 
70         for (auto i = range.first; i <= range.second; ++i) {
71             c.nums.insert(i);
72         }
73     }
74     return true;
75 };
76 }  // namespace
77 
MessageSetParser()78 const auto &MessageSetParser()
79 {
80     using panda::parser::action;
81     using panda::parser::charset;
82     using panda::parser::parser;
83 
84     using p = parser<MessageSetContext, const char, const char *>;
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 
90     static const auto WS = p::of_charset(" \t\r\n");
91     static const auto COMMA = p1::of_charset(",");
92     static const auto DEC = p2::of_charset("0123456789");
93 
94     static const auto NAME = p3::of_charset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789") |=
95         NAME_HANDLER;
96 
97     static const auto NUM = DEC |= NUM_HANDLER;
98 
99     static const auto MSG = NUM | NAME;
100 
101     static const auto MSG_RANGE = MSG >> ~WS >> p4::of_string("-") >> ~WS >> MSG |= RANGE_HANDLER;
102 
103     static const auto ITEM = ~WS >> ((MSG_RANGE | MSG) |= ITEM_HANDLER) >> ~WS >> ~COMMA;
104 
105     // clang-tidy bug, use lambda instead of ITEMS = *ITEM
106     static const auto ITEMS = [](MessageSetContext &c, const char *&start, const char *end) {
107         while (true) {
108             auto saved = start;
109             if (!ITEM(c, start, end)) {
110                 start = saved;
111                 break;
112             }
113         }
114         return true;
115     };
116 
117     return ITEMS;
118 }
119 
120 }  // namespace panda::verifier::debug
121 
122 #endif  //! PANDA_VERIFIER_DEBUG_MSG_SET_PARSER_H_
123