1 #pragma once
2 #include <boost/fusion/include/adapt_struct.hpp>
3 #include <boost/spirit/home/x3/support/ast/variant.hpp>
4 
5 #include <iostream>
6 #include <list>
7 #include <numeric>
8 #include <optional>
9 #include <string>
10 
11 namespace redfish
12 {
13 namespace filter_ast
14 {
15 
16 namespace x3 = boost::spirit::x3;
17 
18 // Represents a string literal
19 // (ie 'Enabled')
20 struct QuotedString : std::string
21 {};
22 
23 // Represents a string that matches an identifier
24 // Looks similar to a json pointer
25 struct UnquotedString : std::string
26 {};
27 
28 // Because some program elements can reference BooleanOp recursively,
29 // they need to be forward declared so that x3::forward_ast can be used
30 struct LogicalAnd;
31 struct Comparison;
32 using BooleanOp =
33     x3::variant<x3::forward_ast<Comparison>, x3::forward_ast<LogicalAnd>>;
34 
35 enum class ComparisonOpEnum
36 {
37     Invalid,
38     Equals,
39     NotEquals,
40     GreaterThan,
41     GreaterThanOrEqual,
42     LessThan,
43     LessThanOrEqual
44 };
45 
46 // An expression that has been negated with not
47 struct LogicalNot
48 {
49     std::optional<char> isLogicalNot;
50     BooleanOp operand;
51 };
52 
53 using Argument = x3::variant<int64_t, double, UnquotedString, QuotedString>;
54 
55 struct Comparison
56 {
57     Argument left;
58     ComparisonOpEnum token = ComparisonOpEnum::Invalid;
59     Argument right;
60 };
61 
62 struct LogicalOr
63 {
64     LogicalNot first;
65     std::list<LogicalNot> rest;
66 };
67 struct LogicalAnd
68 {
69     LogicalOr first;
70     std::list<LogicalOr> rest;
71 };
72 } // namespace filter_ast
73 } // namespace redfish
74 
75 BOOST_FUSION_ADAPT_STRUCT(redfish::filter_ast::Comparison, left, token, right);
76 BOOST_FUSION_ADAPT_STRUCT(redfish::filter_ast::LogicalNot, isLogicalNot,
77                           operand);
78 BOOST_FUSION_ADAPT_STRUCT(redfish::filter_ast::LogicalOr, first, rest);
79 BOOST_FUSION_ADAPT_STRUCT(redfish::filter_ast::LogicalAnd, first, rest);
80