9#include <framework/utilities/FormulaParser.h>
44 default:
throw std::runtime_error(std::string(
"Cannot apply operator ") +
operatorToChar(op));
106 throw std::runtime_error(
"could not parse, stack of operands empty. Please report, this is most likely a bug");
108 throw std::runtime_error(
"Missing operand");
129 if (tok == wrong)
throw std::runtime_error(
"wrong type of closing bracket");
130 if (tok == correct)
return;
134 throw std::runtime_error(
"unmatched bracket");
143 int op_precedence = (int)op >> 4;
148 int tok_precedence = (int)tok >> 4;
153 if (tok_precedence < op_precedence or (tok_precedence == op_precedence and tok_right))
break;
168 throw std::runtime_error(
"missing closing bracket");
194 if (next ==
'+' or next ==
'-') {
228 m_buffer = std::istringstream(formula);
239 for (
char next;
m_buffer.get(next);) {
245 if (next ==
'(') ++nestlevel;
246 if (next ==
')') --nestlevel;
274 if (next ==
' ' or next ==
'\n' or next ==
'\t' or next ==
'\r') {
288 if (nestlevel > 0)
throw std::runtime_error(
"unterminated variable arguments");
297 std::ostringstream message;
301 if (pos == -1) pos =
m_buffer.str().size() + 1;
303 message <<
"Error parsing formula at character " << pos <<
": " << e.what() << std::endl;
305 std::istringstream errbuff(
m_buffer.str());
307 bool arrowShown{
false};
308 for (std::string line; std::getline(errbuff, line);) {
310 message <<
" " << line << std::endl;
312 auto curpos = errbuff.tellg();
314 if (!arrowShown && (curpos == -1 || curpos >= pos)) {
316 for (
long i = lastpos - 1; i < pos; ++i) message <<
"-";
317 message <<
"^" << std::endl;
323 throw std::runtime_error(message.str());
EOperator checkForOperator(char next)
Check if the next character is a operator.
void flushPendingOperators()
Flush all pending operators at the end of processing.
void addOperator(EOperator op)
Add an operator to the internal state, convert them to reverse polish notation using the shunting yar...
void processString(const std::string &formula)
Process the given formula and store the final state.
static double applyOperator(EOperator op, double a, double b)
Apply operator on two values.
static void assertOperatorUsable(size_t stacksize)
Make sure we have enough operands to use an operator.
void raiseError(const std::runtime_error &e)
Format the given runtime_error with context information and rethrow a new one.
void flushCurrentVariable()
Flush the currently parsed variable name and add it to the state either as variable or number.
static char operatorToChar(EOperator op) noexcept
Convert operator code to character.
static ENumberStatus checkNumber(ENumberStatus current, char next)
Check if a string literal with a given number status continues to be a valid number if next is append...
Abstract base class for different kinds of events.