9 namespace BooleanFunctionParser
88 static const std::map<ParserType, std::map<TokenType, unsigned>> parser2precedence = {
90 std::map<TokenType, unsigned>({
98 std::map<TokenType, unsigned>({
112 const auto&
precedence = parser2precedence.at(parser);
130 return this->
type == _type;
135 static const std::map<TokenType, std::string> type2str = {
155 os <<
"Token { " << type2str.at(token.
type);
159 os <<
", " << std::get<0>(token.
variable) <<
" (" << std::get<1>(token.
variable) <<
")";
165 for (
auto i = token.
constant.size(); i-- != 0;)
177 std::stringstream ss;
182 Token::Token(
TokenType _type, std::tuple<std::string, u16> _variable, std::vector<BooleanFunction::Value> _constant) :
type(_type), variable(_variable), constant(_constant)
192 int ternary_depth = 0;
193 for (
const auto& tok : tokens)
201 if (ternary_depth == 0)
203 return ERR(
"could not translate '" + expression +
"' to reverse polish notation: unmatched ':' in ternary expression");
208 if (ternary_depth != 0)
210 return ERR(
"could not translate '" + expression +
"' to reverse polish notation: unmatched '?' in ternary expression");
213 std::stack<Token> operator_stack;
214 std::vector<Token>
output;
216 for (
auto&& token : tokens)
223 output.emplace_back(token);
239 const bool left_assoc = token.is_left_associative();
241 && (operator_stack.top().precedence(parser) > token.precedence(parser)
242 || (left_assoc && operator_stack.top().precedence(parser) == token.precedence(parser))))
244 output.emplace_back(operator_stack.top());
245 operator_stack.pop();
247 operator_stack.push(token);
264 operator_stack.push(token);
273 output.emplace_back(operator_stack.top());
274 operator_stack.pop();
277 operator_stack.pop();
284 while (!operator_stack.empty())
288 return ERR(
"could not translate '" + expression +
"' to reverse polish notation: bracket level is invalid");
291 output.emplace_back(operator_stack.top());
292 operator_stack.pop();
299 auto nodes = std::vector<BooleanFunction::Node>();
300 nodes.reserve(tokens.size());
302 for (
auto&& token : tokens)
309 return ERR(
"could not translate tokens: tokens are imbalanced, i.e., the operation comes before the operand nodes");
345 if (nodes.size() < 3)
347 return ERR(
"could not translate tokens: ternary `:` requires three preceding operands");
349 const u16 ite_size = nodes.back().size;
362 return ERR(
"could not translate tokens: unable to handle '" + token.to_string() +
"' in '" + expression +
"'");
368 return ERR_APPEND(res.get_error(),
"could not translate tokens: unable to build Boolean function from vector of nodes");
static Result< BooleanFunction > build(std::vector< Node > &&nodes)
#define ERR_APPEND(prev_error, message)
ParserType
ParserType refers to the parser identifier.
@ Liberty
refers to the 'Liberty' Boolean function parser
@ Standard
refers to the 'Standard' Boolean function parser
std::ostream & operator<<(std::ostream &os, const Token &token)
Result< BooleanFunction > translate(std::vector< Token > &&tokens, const std::string &expression)
TokenType
TokenType refers to a token identifier for a Boolean function string.
Result< std::vector< Token > > reverse_polish_notation(std::vector< Token > &&tokens, const std::string &expression, const ParserType &parser)
static Node Constant(const std::vector< BooleanFunction::Value > value)
static Node Operation(u16 type, u16 size)
static Node Variable(const std::string variable, u16 size)
Token refers to a token identifier and accompanied data.
static Token BracketOpen()
std::tuple< std::string, u16 > variable
optional value and bit-size in case token is a variable
static Token BracketClose()
std::string to_string() const
bool is_left_associative() const
TokenType type
refers to the underlying token type identifier
static Token Constant(std::vector< BooleanFunction::Value > value)
Token(TokenType _type, std::tuple< std::string, u16 > variable, std::vector< BooleanFunction::Value > constant)
Construct a new initialized Token.
bool is(TokenType type) const
static Token Variable(std::string name, u16 size)
std::vector< BooleanFunction::Value > constant
optional value in case token is a constant
unsigned precedence(const ParserType &type) const