4 #include <boost/fusion/include/at_c.hpp>
5 #include <boost/fusion/sequence/intrinsic/at_c.hpp>
6 #include <boost/spirit/home/x3.hpp>
11 namespace BooleanFunctionParser
17 std::vector<Token> tokens;
20 const auto var_size = [&var_sizes](
const std::string&
name) ->
u16 {
21 if (
auto it = var_sizes.find(
name); it != var_sizes.end())
46 const auto MultiBitBinAction = [&tokens](
auto& ctx) {
48 const auto& bits = _attr(ctx);
49 std::vector<BooleanFunction::Value> values;
50 values.reserve(bits.size());
52 for (
auto it = bits.rbegin(); it != bits.rend(); ++it)
54 values.push_back((*it ==
'0') ? BooleanFunction::Value::ZERO : BooleanFunction::Value::ONE);
59 const auto MultiBitHexAction = [&tokens](
auto& ctx) {
61 const auto& digits = _attr(ctx);
62 std::vector<BooleanFunction::Value> values;
63 values.reserve(digits.size() * 4);
64 for (
auto it = digits.rbegin(); it != digits.rend(); ++it)
68 if (c >=
'0' && c <=
'9')
70 else if (c >=
'a' && c <=
'f')
71 nibble = c -
'a' + 10;
73 nibble = c -
'A' + 10;
74 for (
int i = 0; i < 4; ++i)
76 values.push_back((nibble & (1 << i)) ? BooleanFunction::Value::ONE : BooleanFunction::Value::ZERO);
82 const auto MultiBitOctAction = [&tokens](
auto& ctx) {
84 const auto& digits = _attr(ctx);
85 std::vector<BooleanFunction::Value> values;
86 values.reserve(digits.size() * 3);
87 for (
auto it = digits.rbegin(); it != digits.rend(); ++it)
89 const u8 oct = *it -
'0';
90 for (
int i = 0; i < 3; ++i)
92 values.push_back((oct & (1 << i)) ? BooleanFunction::Value::ONE : BooleanFunction::Value::ZERO);
98 const auto VariableAction = [&tokens, &var_size](
auto& ctx) {
102 std::stringstream
name;
103 name << std::string(1, boost::fusion::at_c<0>(_attr(ctx)));
104 name << boost::fusion::at_c<1>(_attr(ctx));
108 const auto VariableIndexAction = [&tokens, &var_size](
auto& ctx) {
113 std::stringstream
name;
114 name << std::string(1, boost::fusion::at_c<1>(_attr(ctx)));
115 name << boost::fusion::at_c<2>(_attr(ctx));
116 name << boost::fusion::at_c<3>(_attr(ctx));
117 name << boost::fusion::at_c<4>(_attr(ctx));
118 name << boost::fusion::at_c<5>(_attr(ctx));
121 const auto ConstantAction = [&tokens](
auto& ctx) {
122 const auto value = (_attr(ctx) ==
'0') ? BooleanFunction::Value::ZERO : BooleanFunction::Value::ONE;
130 namespace x3 = boost::spirit::x3;
132 const auto AndRule = x3::lit(
"&")[AndAction];
133 const auto NotRule = x3::char_(
"!~")[NotAction];
134 const auto OrRule = x3::lit(
"|")[OrAction];
135 const auto XorRule = x3::lit(
"^")[XorAction];
136 const auto EqRule = x3::lit(
"==")[EqAction];
137 const auto QuestionRule = x3::lit(
"?")[QuestionAction];
138 const auto ColonRule = x3::lit(
":")[ColonAction];
139 const auto AddRule = x3::lit(
"+")[AddAction];
140 const auto SubRule = x3::lit(
"-")[SubAction];
141 const auto MulRule = x3::lit(
"*")[MulAction];
143 const auto BracketOpenRule = x3::lit(
"(")[BracketOpenAction];
144 const auto BracketCloseRule = x3::lit(
")")[BracketCloseAction];
146 const auto VariableRule = x3::lexeme[(x3::char_(
"a-zA-Z") >> *x3::char_(
"a-zA-Z0-9_"))][VariableAction];
147 const auto VariableIndexRoundBracketRule =
148 x3::lexeme[(-(x3::char_(
"\\")) >> x3::char_(
"a-zA-Z") >> *x3::char_(
"a-zA-Z0-9_") >> x3::char_(
"(") >> x3::int_ >> x3::char_(
")"))][VariableIndexAction];
149 const auto VariableIndexSquareBracketRule =
150 x3::lexeme[(-(x3::char_(
"\\")) >> x3::char_(
"a-zA-Z") >> *x3::char_(
"a-zA-Z0-9_") >> x3::char_(
"[") >> x3::int_ >> x3::char_(
"]"))][VariableIndexAction];
151 const auto VariableIndexRule = VariableIndexRoundBracketRule | VariableIndexSquareBracketRule;
153 const auto ConstantRule = x3::lexeme[x3::char_(
"0-1")][ConstantAction];
154 const auto ConstantBinRule = x3::lit(
"0b") >> x3::lexeme[+x3::char_(
"0-1")][MultiBitBinAction];
155 const auto ConstantHexRule = x3::lit(
"0x") >> x3::lexeme[+x3::char_(
"0-9a-fA-F")][MultiBitHexAction];
156 const auto ConstantOctRule = x3::lit(
"0o") >> x3::lexeme[+x3::char_(
"0-7")][MultiBitOctAction];
157 const auto ConstantSuffixRule = x3::lexeme[x3::char_(
"0-1") >> x3::lit(
"'b1")][ConstantAction];
159 auto iter = expression.begin();
160 const auto ok = x3::phrase_parse(
166 +(AndRule | NotRule | OrRule | XorRule | EqRule | QuestionRule | ColonRule | AddRule | SubRule | MulRule | VariableIndexRule | VariableRule | ConstantSuffixRule | ConstantHexRule
167 | ConstantOctRule | ConstantBinRule | ConstantRule | BracketOpenRule | BracketCloseRule),
171 if (!ok || (iter != expression.end()))
173 return ERR(
"could not parse Boolean function '" + expression +
"': " + std::string(iter, expression.end()));
Result< std::vector< Token > > parse_with_standard_grammar(const std::string &expression, const std::map< std::string, u16 > &var_sizes={})
static Token BracketOpen()
static Token BracketClose()
static Token Constant(std::vector< BooleanFunction::Value > value)
static Token Variable(std::string name, u16 size)