HAL
parser_liberty.cpp
Go to the documentation of this file.
4 
5 #include <boost/fusion/include/at_c.hpp>
6 #include <boost/fusion/sequence/intrinsic/at_c.hpp>
7 #include <boost/spirit/home/x3.hpp>
8 
9 namespace hal
10 {
11  namespace BooleanFunctionParser
12  {
13  Result<std::vector<Token>> parse_with_liberty_grammar(const std::string& expression)
14  {
15  // stores the list of tokens that are generated and filled during the
16  // parsing process adn the different semantic actions
17  std::vector<Token> tokens;
18 
20  // (1) Semantic actions to generate tokens
22 
23  const auto AndAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::And()); };
24  const auto NotAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::Not()); };
25  const auto OrAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::Or()); };
26  const auto XorAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::Xor()); };
27 
28  const auto NotSuffixAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::NotSuffix()); };
29 
30  const auto BracketOpenAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::BracketOpen()); };
31  const auto BracketCloseAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::BracketClose()); };
32 
33  const auto VariableAction = [&tokens](auto& ctx) {
34  // combines the first matched character with the remaining string
35  std::stringstream name;
36  name << std::string(1, boost::fusion::at_c<0>(_attr(ctx))) << boost::fusion::at_c<1>(_attr(ctx));
37 
38  tokens.emplace_back(BooleanFunctionParser::Token::Variable(name.str(), 1));
39  };
40  const auto VariableIndexAction = [&tokens](auto& ctx) {
41  // combines the first matched character with the remaining string
42  std::stringstream name;
43  name << std::string(1, boost::fusion::at_c<0>(_attr(ctx))) << boost::fusion::at_c<1>(_attr(ctx)) << boost::fusion::at_c<2>(_attr(ctx)) << boost::fusion::at_c<3>(_attr(ctx))
44  << boost::fusion::at_c<4>(_attr(ctx));
45  tokens.emplace_back(BooleanFunctionParser::Token::Variable(name.str(), 1));
46  };
47  const auto ConstantAction = [&tokens](auto& ctx) {
48  auto value = (_attr(ctx) == '0') ? BooleanFunction::Value::ZERO : BooleanFunction::Value::ONE;
49  tokens.emplace_back(BooleanFunctionParser::Token::Constant({value}));
50  };
51 
53  // (2) Rules
55 
56  namespace x3 = boost::spirit::x3;
57 
58  const auto AndRule = x3::char_("& *")[AndAction];
59  const auto NotRule = x3::lit("!")[NotAction];
60  const auto NotSuffixRule = x3::lit("'")[NotSuffixAction];
61  const auto OrRule = x3::char_("|+")[OrAction];
62  const auto XorRule = x3::lit("^")[XorAction];
63 
64  const auto BracketOpenRule = x3::lit("(")[BracketOpenAction];
65  const auto BracketCloseRule = x3::lit(")")[BracketCloseAction];
66 
67  const auto VariableRule = x3::lexeme[(x3::char_("a-zA-Z") >> *x3::char_("a-zA-Z0-9_"))][VariableAction];
68  const auto VariableIndexRule = x3::lexeme[(x3::char_("a-zA-Z") >> *x3::char_("a-zA-Z0-9_") >> x3::char_("(") >> x3::int_ >> x3::char_(")"))][VariableIndexAction];
69  const auto ConstantRule = x3::lexeme[x3::char_("0-1")][ConstantAction];
70 
71  auto iter = expression.begin();
72  const auto ok = x3::phrase_parse(iter,
73  expression.end(),
75  // (3) Parsing Expression Grammar
77  +(AndRule | NotRule | NotSuffixRule | OrRule | XorRule | VariableIndexRule | VariableRule | ConstantRule | BracketOpenRule | BracketCloseRule),
78  // we use an invalid a.k.a. non-printable ASCII character in order
79  // to prevent the skipping of space characters as they are defined
80  // as an and operation
81  x3::char_(0x00));
82 
83  if (!ok || (iter != expression.end()))
84  {
85  return ERR("could not to parse Boolean function '" + expression + "': " + std::string(iter, expression.end()));
86  }
87 
88  return OK(tokens);
89  }
90  } // namespace BooleanFunctionParser
91 } // namespace hal
#define ERR(message)
Definition: result.h:53
#define OK(...)
Definition: result.h:49
Result< std::vector< Token > > parse_with_liberty_grammar(const std::string &expression)
std::string name
static Token Constant(std::vector< BooleanFunction::Value > value)
static Token Variable(std::string name, u16 size)