Zigbee Protocol Controller 1.6.0
attribute_mapper_grammar.hpp
Go to the documentation of this file.
1/******************************************************************************
2 * # License
3 * <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
4 ******************************************************************************
5 * The licensor of this software is Silicon Laboratories Inc. Your use of this
6 * software is governed by the terms of Silicon Labs Master Software License
7 * Agreement (MSLA) available at
8 * www.silabs.com/about-us/legal/master-software-license-agreement. This
9 * software is distributed to you in Source Code format and is governed by the
10 * sections of the MSLA applicable to Source Code.
11 *
12 *****************************************************************************/
13
29#ifndef ATTRIBUTE_MAPPER_GRAMMAR_H
30#define ATTRIBUTE_MAPPER_GRAMMAR_H
31
32#include <boost/any.hpp>
33#include <boost/spirit/include/qi.hpp>
34#include <boost/spirit/include/qi_grammar.hpp>
35#include <boost/phoenix/operator.hpp>
36#include <boost/phoenix/object.hpp>
37#include <boost/phoenix/bind.hpp>
39
40namespace qi = boost::spirit::qi;
42
43// Operators in the term rule have higher precedence than
44// those in expression rule.
45struct term_rule_operators_ : qi::symbols<char, ast::operator_ids> {
47 {
48 // clang-format off
57 // clang-format on
58 }
60
61// Operators in the expression rule have lower precedence than
62// those in the term rule.
63struct expr_rule_operators_ : qi::symbols<char, ast::operator_ids> {
65 {
66 // clang-format off
75 // clang-format on
76 }
78
87template<typename IteratorType> class SkipperGrammar :
88 public qi::grammar<IteratorType>
89{
90 public:
92 {
93 lineCommentRule = qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol;
95 = qi::lit("/*") >> *(qi::char_ - qi::lit("*/")) >> qi::lit("*/");
96 spaceRule = qi::space;
98 }
99
100 private:
101 qi::rule<IteratorType> lineCommentRule;
102 qi::rule<IteratorType> blockCommentRule;
103 qi::rule<IteratorType> spaceRule;
104 qi::rule<IteratorType> rule;
105};
106
122template<typename T> struct strict_real_policies :
124 static bool const expect_dot = true;
125};
126
127template<typename IteratorType, typename Skipper> class UAMGrammar :
128 public qi::grammar<IteratorType, ast::ast_tree(), Skipper>
129{
130 public:
131 UAMGrammar() : UAMGrammar::base_type(start_rule, "Rules")
132 {
133 using qi::alnum;
134 using qi::alpha;
135 using qi::attr;
136 using qi::char_;
137 using qi::eol;
138 using qi::hex;
139 using qi::lit;
140 using qi::string;
141 using qi::uint_;
142
143 using qi::fail;
144 using qi::on_error;
145 using namespace qi::labels;
146 using boost::phoenix::construct;
147 using boost::phoenix::val;
148 using boost::spirit::qi::real_parser;
149 using boost::spirit::qi::strict_ureal_policies;
150 //This parser parses real numbers, real numbers must contain a dot
151 real_parser<float, strict_ureal_policies<float>> ureal;
152
153 // Parser operators: https://www.boost.org/doc/libs/1_80_0/libs/spirit/doc/html/spirit/qi/reference/operator.html
154
155 // definitions, example: def my_var 1234
156 // note that here we use a schematic action to build the defs parser.
157 // in this way when the parse later passes an identifier the defs parser
158 // will output the expression from the def_rule.
160 = "def" > (identifier_rule
161 > expression_rule)[boost::phoenix::bind(defs.add, _1, _2)];
162
163 // identifier, name of something
164 identifier_rule = (alpha | char_("_")) >> *(alnum | char_("_"));
165
166 // elements of an attribute path
168 = '^' | (operand_rule >> '[' >> operand_rule >> ']') | operand_rule;
169
170 // the whole attribute path, example d'1245.6666[3].9999
171 attribute_rule = char_("dre") >> '\'' >> attribute_path_element_rule % '.';
172
173 // Instance assigments i: / Clearance assignment c:
175 = (lit("c:") >> attr(2)) | (lit("i:") >> attr(1)) | attr(0);
176
177 // if condition, example if (r'1244 == 0) 2 4
179
180 // any operand type, numbers, attributes conditions etc.
181 operand_rule = "undefined" | ("0x" > hex) | (ureal >> 'f') | uint_
183 | ('(' > expression_rule > ')') | (char_('-') > operand_rule)
184 | (char_('+') > operand_rule) | built_in_function_rule;
185
186 // a term is made of 1 or more operators combined by a strong binding operator like * / | &
188
189 // an experssion is made of 1 or more operators combined by a weak binding operator like + and -
191
192 // Functions can be put in assignments, and they contain an expression themselves
193 // fn_at_least_one_value_defined(r'2,r'3,r'5)
194 // fn_min_value(r'2,d'3 or r'3,r'5)
196 >> (expression_rule > *("," >> expression_rule))
197 >> ")";
198
199 // an assignment, example r'1234 = r'6666
202
203 // Scope configuration is used assign configurations for a scope
204 scope_setting_name = string("chain_reaction") | string("clear_desired")
205 | string("create_attributes")
206 | string("common_parent_type");
207 scope_setting_value = ("0x" > hex) | uint_;
210
211 // the scope rule is used to group assignments and assign them a priority.
212 scope_rule = "scope" > uint_ > *scope_configuration_rule > "{"
213 >> +assignment_rule >> "}";
214
215 // This is the entry rule for the grammer, definitions must come first, then scopes
217
218 expression_rule.name("expression");
219 term_rule.name("term");
220 operand_rule.name("operand");
221 condition_rule.name("condition");
222 attribute_rule.name("attribute");
223 assignment_type_rule.name("assignment_type");
224 assignment_rule.name("assignment");
225 built_in_function_rule.name("function");
226 scope_setting_name.name("scope_setting_name");
227 scope_setting_value.name("scope_setting_value");
228 scope_configuration_rule.name("scope_configuration_rule");
229 scope_rule.name("scope");
230 def_rule.name("def");
231 identifier_rule.name("identifier");
232 attribute_path_element_rule.name("path element");
233
234 // Error handler for the parser
235 // See https://www.boost.org/doc/libs/1_76_0/libs/spirit/doc/html/spirit/qi/tutorials/mini_xml___error_handling.html
236 on_error<fail>(
238 std::cout << val("Error! Expecting ") << _4 // what failed?
239 << val(" here: \"")
240 << construct<std::string>(_3,
241 _2) // iterators to error-pos, end
242 << val("\"") << std::endl);
243 }
244
245 private:
247
248 // Rules ( small parsers ) used by the main parser.
249 // note that the second template argument is the data type of the output of the
250 // rule. The tokens produced by the parser must be compatible destination struct
251 // Ie if a rule parses and integer followed by a string then the struct in the
252 // second argument must have a integer as first argument and a string as second argument.
253 // See documentation for details:
254 // https://www.boost.org/doc/libs/1_76_0/libs/spirit/doc/html/spirit/qi/tutorials/employee___parsing_into_structs.html
255 qi::rule<IteratorType, ast::expression(), Skipper> expression_rule;
256 qi::rule<IteratorType, ast::expression(), Skipper> term_rule;
257 qi::rule<IteratorType, ast::operand(), Skipper> operand_rule;
258 qi::rule<IteratorType, ast::condition(), Skipper> condition_rule;
259 qi::rule<IteratorType, int, Skipper> assignment_type_rule;
260 qi::rule<IteratorType, ast::attribute(), Skipper> attribute_rule;
261 qi::rule<IteratorType, ast::attribute_path_element(), Skipper>
263 qi::rule<IteratorType, std::string()> identifier_rule;
264 qi::rule<IteratorType, ast::function_invokation(), Skipper>
266 qi::rule<IteratorType, ast::assignment(), Skipper> assignment_rule;
267 qi::rule<IteratorType, std::string()> scope_setting_name;
268 qi::rule<IteratorType, boost::optional<unsigned int>, Skipper>
270 qi::rule<IteratorType, ast::scope_setting(), Skipper>
272 qi::rule<IteratorType, ast::scope(), Skipper> scope_rule;
273 qi::rule<IteratorType, Skipper> def_rule;
274 qi::rule<IteratorType, ast::ast_tree(), Skipper> start_rule;
275};
276
277#endif //ATTRIBUTE_MAPPER_GRAMMAR_H
278
Skipper grammer.
Definition: attribute_mapper_grammar.hpp:89
SkipperGrammar()
Definition: attribute_mapper_grammar.hpp:91
qi::rule< IteratorType > blockCommentRule
Definition: attribute_mapper_grammar.hpp:102
qi::rule< IteratorType > spaceRule
Definition: attribute_mapper_grammar.hpp:103
qi::rule< IteratorType > lineCommentRule
Definition: attribute_mapper_grammar.hpp:101
qi::rule< IteratorType > rule
Definition: attribute_mapper_grammar.hpp:104
Definition: attribute_mapper_grammar.hpp:129
qi::rule< IteratorType, ast::expression(), Skipper > term_rule
Definition: attribute_mapper_grammar.hpp:256
UAMGrammar()
Definition: attribute_mapper_grammar.hpp:131
qi::rule< IteratorType, int, Skipper > assignment_type_rule
Definition: attribute_mapper_grammar.hpp:259
qi::rule< IteratorType, boost::optional< unsigned int >, Skipper > scope_setting_value
Definition: attribute_mapper_grammar.hpp:269
qi::rule< IteratorType, ast::attribute(), Skipper > attribute_rule
Definition: attribute_mapper_grammar.hpp:260
qi::rule< IteratorType, ast::scope(), Skipper > scope_rule
Definition: attribute_mapper_grammar.hpp:272
qi::rule< IteratorType, ast::operand(), Skipper > operand_rule
Definition: attribute_mapper_grammar.hpp:257
qi::rule< IteratorType, std::string()> identifier_rule
Definition: attribute_mapper_grammar.hpp:263
qi::rule< IteratorType, Skipper > def_rule
Definition: attribute_mapper_grammar.hpp:273
qi::rule< IteratorType, ast::expression(), Skipper > expression_rule
Definition: attribute_mapper_grammar.hpp:255
defines_t defs
Definition: attribute_mapper_grammar.hpp:246
qi::rule< IteratorType, std::string()> scope_setting_name
Definition: attribute_mapper_grammar.hpp:267
qi::rule< IteratorType, ast::condition(), Skipper > condition_rule
Definition: attribute_mapper_grammar.hpp:258
qi::rule< IteratorType, ast::ast_tree(), Skipper > start_rule
Definition: attribute_mapper_grammar.hpp:274
qi::rule< IteratorType, ast::attribute_path_element(), Skipper > attribute_path_element_rule
Definition: attribute_mapper_grammar.hpp:262
qi::rule< IteratorType, ast::scope_setting(), Skipper > scope_configuration_rule
Definition: attribute_mapper_grammar.hpp:271
qi::rule< IteratorType, ast::function_invokation(), Skipper > built_in_function_rule
Definition: attribute_mapper_grammar.hpp:265
qi::rule< IteratorType, ast::assignment(), Skipper > assignment_rule
Definition: attribute_mapper_grammar.hpp:266
expr_rule_operators_ expr_rule_operators
term_rule_operators_ term_rule_operators
boost::variant< ast::nil, ast::operand, uint32_t, attribute_path_subscript > attribute_path_element
Attribute path element.
Definition: attribute_mapper_ast.hpp:104
@ operator_modulo
Definition: attribute_mapper_ast.hpp:72
@ operator_div
Definition: attribute_mapper_ast.hpp:65
@ operator_bitand
Definition: attribute_mapper_ast.hpp:66
@ operator_bitxor
Definition: attribute_mapper_ast.hpp:68
@ operator_minus
Definition: attribute_mapper_ast.hpp:62
@ operator_bitor
Definition: attribute_mapper_ast.hpp:67
@ operator_mult
Definition: attribute_mapper_ast.hpp:64
@ operator_or
Definition: attribute_mapper_ast.hpp:71
@ operator_less_than_or_eq
Definition: attribute_mapper_ast.hpp:75
@ operator_exponent
Definition: attribute_mapper_ast.hpp:73
@ operator_greater_than_or_eq
Definition: attribute_mapper_ast.hpp:76
@ operator_greater_than
Definition: attribute_mapper_ast.hpp:70
@ operator_plus
Definition: attribute_mapper_ast.hpp:61
@ operator_less_than
Definition: attribute_mapper_ast.hpp:69
@ operator_equals
Definition: attribute_mapper_ast.hpp:63
@ operator_neq
Definition: attribute_mapper_ast.hpp:74
x3::variant< ast::nil, uint32_t, float, x3::forward_ast< attribute >, x3::forward_ast< signed_ >, x3::forward_ast< expression >, x3::forward_ast< condition >, x3::forward_ast< function_invokation > > operand
Operands.
Definition: attribute_mapper_ast.hpp:95
sl_status_t add(zigbee_eui64_uint_t eui64, const zigpc_discovery_status_callback_t callback)
Add a callback to be invoked for a specific EUI64 (or WILDCARD_EUI64 for all devices).
Assignment.
Definition: attribute_mapper_ast.hpp:193
Definition: attribute_mapper_ast.hpp:53
Attribute.
Definition: attribute_mapper_ast.hpp:177
Condition.
Definition: attribute_mapper_ast.hpp:147
Expression.
Definition: attribute_mapper_ast.hpp:134
Built-in function invokation Example : fn_min_value(r'3, 5, d'5 or 20)
Definition: attribute_mapper_ast.hpp:209
Scope setting A scope setting consists of a setting name and an associated value.
Definition: attribute_mapper_ast.hpp:218
Scope.
Definition: attribute_mapper_ast.hpp:234
Definition: attribute_mapper_grammar.hpp:63
expr_rule_operators_()
Definition: attribute_mapper_grammar.hpp:64
Main UAM grammer.
Definition: attribute_mapper_grammar.hpp:123
static bool const expect_dot
Definition: attribute_mapper_grammar.hpp:124
Definition: attribute_mapper_grammar.hpp:45
term_rule_operators_()
Definition: attribute_mapper_grammar.hpp:46