HAL  v4.5.0-257-ge24279b4e
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
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, const std::map<std::string, u16>& var_sizes)
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 
19  // Looks up a variable's bit-width from the caller-supplied map; defaults to 1 when absent.
20  const auto var_size = [&var_sizes](const std::string& name) -> u16 {
21  if (auto it = var_sizes.find(name); it != var_sizes.end())
22  {
23  return it->second;
24  }
25  return 1;
26  };
27 
29  // (1) Semantic actions to generate tokens
31 
32  const auto AndAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::And()); };
33  const auto NotAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::Not()); };
34  const auto OrAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::Or()); };
35  const auto XorAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::Xor()); };
36 
37  const auto NotSuffixAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::NotSuffix()); };
38 
39  const auto BracketOpenAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::BracketOpen()); };
40  const auto BracketCloseAction = [&tokens](auto& /* ctx */) { tokens.emplace_back(BooleanFunctionParser::Token::BracketClose()); };
41 
42  const auto VariableAction = [&tokens, &var_size](auto& ctx) {
43  // combines the first matched character with the remaining string
44  std::stringstream name;
45  name << std::string(1, boost::fusion::at_c<0>(_attr(ctx))) << boost::fusion::at_c<1>(_attr(ctx));
46 
47  tokens.emplace_back(BooleanFunctionParser::Token::Variable(name.str(), var_size(name.str())));
48  };
49  const auto VariableIndexAction = [&tokens, &var_size](auto& ctx) {
50  // combines the first matched character with the remaining string
51  std::stringstream name;
52  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))
53  << boost::fusion::at_c<4>(_attr(ctx));
54  tokens.emplace_back(BooleanFunctionParser::Token::Variable(name.str(), var_size(name.str())));
55  };
56  const auto ConstantAction = [&tokens](auto& ctx) {
57  auto value = (_attr(ctx) == '0') ? BooleanFunction::Value::ZERO : BooleanFunction::Value::ONE;
58  tokens.emplace_back(BooleanFunctionParser::Token::Constant({value}));
59  };
60 
62  // (2) Rules
64 
65  namespace x3 = boost::spirit::x3;
66 
67  const auto AndRule = x3::char_("& *")[AndAction];
68  const auto NotRule = x3::lit("!")[NotAction];
69  const auto NotSuffixRule = x3::lit("'")[NotSuffixAction];
70  const auto OrRule = x3::char_("|+")[OrAction];
71  const auto XorRule = x3::lit("^")[XorAction];
72 
73  const auto BracketOpenRule = x3::lit("(")[BracketOpenAction];
74  const auto BracketCloseRule = x3::lit(")")[BracketCloseAction];
75 
76  const auto VariableRule = x3::lexeme[(x3::char_("a-zA-Z") >> *x3::char_("a-zA-Z0-9_"))][VariableAction];
77  const auto VariableIndexRule = x3::lexeme[(x3::char_("a-zA-Z") >> *x3::char_("a-zA-Z0-9_") >> x3::char_("(") >> x3::int_ >> x3::char_(")"))][VariableIndexAction];
78  const auto ConstantRule = x3::lexeme[x3::char_("0-1")][ConstantAction];
79 
80  auto iter = expression.begin();
81  const auto ok = x3::phrase_parse(iter,
82  expression.end(),
84  // (3) Parsing Expression Grammar
86  +(AndRule | NotRule | NotSuffixRule | OrRule | XorRule | VariableIndexRule | VariableRule | ConstantRule | BracketOpenRule | BracketCloseRule),
87  // we use an invalid a.k.a. non-printable ASCII character in order
88  // to prevent the skipping of space characters as they are defined
89  // as an and operation
90  x3::char_(0x00));
91 
92  if (!ok || (iter != expression.end()))
93  {
94  return ERR("could not to parse Boolean function '" + expression + "': " + std::string(iter, expression.end()));
95  }
96 
97  return OK(tokens);
98  }
99  } // namespace BooleanFunctionParser
100 } // namespace hal
uint16_t u16
Definition: defines.h:40
#define ERR(message)
Definition: result.h:60
#define OK(...)
Definition: result.h:56
Result< std::vector< Token > > parse_with_liberty_grammar(const std::string &expression, const std::map< std::string, u16 > &var_sizes={})
Definition: defines.h:45
std::string name
static Token Constant(std::vector< BooleanFunction::Value > value)
static Token Variable(std::string name, u16 size)