18 #ifndef CONFIG_GRAMMAR_HPP_ 19 #define CONFIG_GRAMMAR_HPP_ 26 #include <type_traits> 40 using namespace tao::pegtl;
41 using namespace tao::pegtl::ascii;
48 static const std::string error_message;
54 struct yes : std::true_type, error<T> {};
58 struct no : std::false_type, error<T> {};
62 struct yes_without_content : std::true_type, error<T>
64 static void transform(std::unique_ptr<config::parse_tree::node> &node)
66 node->remove_content();
73 struct replace_with_first_child : std::true_type, error<T>
75 static void transform(std::unique_ptr<config::parse_tree::node> &node)
77 auto children = std::move(node->children);
78 node = std::move(children.front());
79 children.erase(children.begin());
80 node->children = std::move(children);
85 template<
typename T>
struct store : no<T> {};
89 struct comment : seq<one<'#'>, star<not_at<eol>, not_at<eof>, any>> {};
90 struct ignored : sor<space, comment> {};
94 struct p : pad<N, ignored> {};
97 struct eos : one<';'> {};
100 template <
typename K>
101 struct a0_statement : seq<K, p<must<eos>>> {};
102 template <
typename K,
typename V = success>
103 struct a1_statement : seq<K, p<must<V>>, p<must<eos>>> {};
106 struct opening_brace : one<'{'> {};
107 struct closing_brace : one<'}'> {};
108 template <
typename K,
typename... Statements>
109 struct t_block : seq<K,
110 p<must<opening_brace>>,
111 star<p<sor<Statements...>>>,
112 p<must<closing_brace>>> {};
115 template <
typename K,
typename N,
typename... Statements>
117 : seq<K, p<must<N>>, p<must<opening_brace>>,
118 star<p<sor<Statements...>>>, p<must<closing_brace>>> {};
122 : sor<TAO_PEGTL_STRING("yes"), TAO_PEGTL_STRING("no")> {};
125 struct integer : plus<digit> {};
128 struct signed_integer : seq<opt<one<'+', '-'>>, integer> {};
131 struct mavaddr : seq<integer, one<'.'>, integer> {};
132 struct full_mask : if_must<one<':'>, mavaddr> {};
133 struct forward_mask : if_must<one<'/'>, integer> {};
134 struct backward_mask : if_must<one<'\\'>, integer> {};
136 : seq<mavaddr, opt<sor<full_mask, forward_mask, backward_mask>>> {};
139 struct port : integer {};
140 template<>
struct store<port> : yes<port> {};
143 struct address : seq<integer, rep<3, seq<one<'.'>, integer>>> {};
144 template<>
struct store<address> : yes<address> {};
147 struct max_bitrate : integer {};
148 template<>
struct store<max_bitrate> : yes<max_bitrate> {};
151 struct device : plus<sor<alnum, one<'.', '_', '/'>>> {};
152 template<>
struct store<device> : yes<device> {};
155 struct baudrate : integer {};
156 template<>
struct store<baudrate> : yes<baudrate> {};
159 struct flow_control : yesno {};
160 template<>
struct store<flow_control> : yes<flow_control> {};
163 struct preload : mavaddr {};
164 template<>
struct store<preload> : yes<preload> {};
167 struct chain_name : identifier {};
168 template<>
struct store<chain_name> : yes<chain_name> {};
172 struct accept : TAO_PEGTL_STRING("accept") {};
173 template<>
struct store<accept> : yes_without_content<accept> {};
175 struct reject : TAO_PEGTL_STRING("reject") {};
176 template<>
struct store<
reject> : yes_without_content<reject> {};
178 struct call : chain_name {};
179 template<>
struct store<
call> : yes<call> {};
180 struct call_container : seq<TAO_PEGTL_STRING("call"), p<must<call>>> {};
181 template<>
struct store<call_container>
182 : replace_with_first_child<call_container> {};
184 struct goto_ : chain_name {};
185 template<>
struct store<
goto_> : yes<goto_> {};
186 struct goto_container : seq<TAO_PEGTL_STRING("goto"), p<must<goto_>>> {};
187 template<>
struct store<goto_container>
188 : replace_with_first_child<goto_container> {};
190 struct action : sor<accept, reject, call_container, goto_container> {};
193 struct packet_type : plus<sor<upper, digit, one<'_'>>> {};
194 template<>
struct store<packet_type> : yes<packet_type> {};
195 struct source : mavmask {};
196 template<>
struct store<source> : yes<source> {};
197 struct source_command
198 : seq<TAO_PEGTL_STRING("from"), p<must<source>>> {};
199 struct dest : mavmask {};
200 template<>
struct store<dest> : yes<dest> {};
202 : seq<TAO_PEGTL_STRING("to"), p<must<dest>>> {};
203 struct start_with_packet_type
204 : seq<packet_type, opt<p<source_command>>, opt<p<dest_command>>> {};
205 struct start_with_source : seq<source_command, opt<p<dest_command>>> {};
206 struct start_with_dest : dest_command {};
207 struct condition_value
208 : p<sor<start_with_packet_type, start_with_source, start_with_dest>> {};
209 struct condition : if_must<TAO_PEGTL_STRING("if"), condition_value> {};
210 template<>
struct store<condition> : yes_without_content<condition> {};
213 struct priority : signed_integer {};
214 template<>
struct store<priority> : yes<priority> {};
215 struct priority_keyword : TAO_PEGTL_STRING("priority") {};
216 struct priority_command
217 : seq<TAO_PEGTL_STRING("with"), p<must<priority_keyword>>,
218 p<must<priority>>> {};
221 struct unsupported_statement : failure {};
223 : if_must<a0_statement<identifier>, unsupported_statement> {};
225 : if_must<a1_statement<identifier,
226 star<not_one<';'>>>, unsupported_statement> {};
227 struct s_catch : sor<sa0_catch, sa1_catch> {};
230 struct invalid_rule : failure {};
231 struct sa0_rule_catch : if_must<a0_statement<identifier>, invalid_rule> {};
232 struct sa1_rule_catch
233 : if_must<a1_statement<identifier,
234 star<not_one<';'>>>, invalid_rule> {};
235 struct rule_catch : sor<sa0_rule_catch, sa1_rule_catch> {};
239 : if_must<sor<action, rule_catch>, opt<p<priority_command>>,
240 opt<p<condition>>, eos> {};
241 template<>
struct store<
rule> : replace_with_first_child<rule> {};
242 struct chain : chain_name {};
243 template<>
struct store<chain> : yes<chain> {};
244 struct chain_container
245 : t_named_block<TAO_PEGTL_STRING("chain"), chain, rule> {};
246 template<>
struct store<chain_container>
247 : replace_with_first_child<chain_container> {};
250 struct default_action_option : sor<accept, reject> {};
251 struct default_action
252 : a1_statement<TAO_PEGTL_STRING("default_action"),
253 default_action_option> {};
254 template<>
struct store<default_action>
255 : yes_without_content<default_action> {};
258 struct s_port : a1_statement<TAO_PEGTL_STRING("port"), port> {};
259 struct s_address : a1_statement<TAO_PEGTL_STRING("address"), address> {};
261 : a1_statement<TAO_PEGTL_STRING("max_bitrate"), max_bitrate> {};
263 : t_block<TAO_PEGTL_STRING("udp"),
264 s_port, s_address, s_max_bitrate, s_catch> {};
265 template<>
struct store<udp> : yes_without_content<udp> {};
268 struct s_device : a1_statement<TAO_PEGTL_STRING("device"), device> {};
269 struct s_baudrate : a1_statement<TAO_PEGTL_STRING("baudrate"), baudrate> {};
270 struct s_flow_control
271 : a1_statement<TAO_PEGTL_STRING("flow_control"), flow_control> {};
272 struct s_preload : a1_statement<TAO_PEGTL_STRING("preload"), preload> {};
274 : t_block<TAO_PEGTL_STRING("serial"),
275 s_device, s_baudrate, s_flow_control, s_preload, s_catch> {};
276 template<>
struct store<serial> : yes_without_content<serial> {};
279 struct block : sor<udp, serial, chain_container> {};
280 struct statement : sor<default_action, s_catch> {};
281 struct element : sor<comment, block, statement> {};
282 struct elements : plus<pad<element, ignored>> {};
283 struct grammar : seq<must<elements>, eof> {};
286 #pragma clang diagnostic push 287 #pragma clang diagnostic ignored "-Wglobal-constructors" 288 #pragma clang diagnostic ignored "-Wexit-time-destructors" 294 const std::string error<eos>::error_message;
297 const std::string error<opening_brace>::error_message;
300 const std::string error<closing_brace>::error_message;
303 const std::string error<unsupported_statement>::error_message;
306 const std::string error<default_action_option>::error_message;
309 const std::string error<port>::error_message;
312 const std::string error<address>::error_message;
315 const std::string error<max_bitrate>::error_message;
318 const std::string error<device>::error_message;
321 const std::string error<baudrate>::error_message;
324 const std::string error<flow_control>::error_message;
327 const std::string error<preload>::error_message;
330 const std::string error<chain_name>::error_message;
333 const std::string error<chain>::error_message;
336 const std::string error<call>::error_message;
339 const std::string error<goto_>::error_message;
342 const std::string error<invalid_rule>::error_message;
345 const std::string error<condition_value>::error_message;
348 const std::string error<dest>::error_message;
351 const std::string error<source>::error_message;
354 const std::string error<mavaddr>::error_message;
357 const std::string error<integer>::error_message;
360 const std::string error<priority>::error_message;
363 const std::string error<priority_keyword>::error_message;
366 const std::string error<elements>::error_message;
370 const std::string error<T>::error_message =
371 "parse error matching " + internal::demangle<T>();
374 #pragma clang diagnostic pop 390 template <
typename Input>
391 std::unique_ptr<config::parse_tree::node>
parse(Input &in)
393 return parse_tree::parse<grammar, config::store>(in);
397 std::ostream &os,
const config::parse_tree::node &n,
398 bool print_location,
const std::string &s =
"");
403 std::ostream &os,
const config::parse_tree::node &node);
406 #endif // CONFIG_GRAMMAR_HPP_ std::ostream & print_node(std::ostream &os, const config::parse_tree::node &node, bool print_location, const std::string &prefix)
std::unique_ptr< config::parse_tree::node > parse(Input &in)
std::ostream & operator<<(std::ostream &os, const config::parse_tree::node &node)