X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbooleanevaluator.cpp;h=ecb38fb0d07657e4ed9a1a3e574289e08bccee5b;hb=HEAD;hp=6891abceff9a8088db506c6ea1388664830fb4f1;hpb=44c71b05ff282b3ce5a2d71c0f14eed97bfefea6;p=builder.git diff --git a/source/booleanevaluator.cpp b/source/booleanevaluator.cpp deleted file mode 100644 index 6891abc..0000000 --- a/source/booleanevaluator.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include -#include "booleanevaluator.h" - -using namespace std; - -BooleanEvaluator::BooleanEvaluator(const ValueFunction &f): - func([&f](const string &value, const string *){ return f(value); }), - ops("&|!") -{ } - -BooleanEvaluator::BooleanEvaluator(const CompareFunction &f): - func(f), - ops("&|!=^") -{ } - -bool BooleanEvaluator::evaluate(const string &str) -{ - string buf; - last_was_op = true; - for(auto i=str.begin();; ++i) - { - if(i!=str.end() && (isalnum(*i) || (!buf.empty() && (*i=='_' || *i=='-')))) - buf += *i; - else - { - if(!buf.empty()) - { - if(!last_was_op) - throw runtime_error("syntax error at "+buf); - - char op = (op_stack.empty() ? 0 : op_stack.back()); - if(op=='=' || op=='^') - { - op_stack.pop_back(); - string var = var_stack.back(); - var_stack.pop_back(); - bool value = (func(var, &buf) == (op=='=')); - value_stack.push_back(value); - } - else - var_stack.push_back(buf); - - buf.clear(); - last_was_op = false; - } - - if(i==str.end()) - break; - else if(isspace(*i)) - ; - else if(ops.find(*i)!=string::npos) - push_op(*i); - else - throw runtime_error("syntax error at "+string(1, *i)); - } - } - - collapse(0); - - bool value = pop_value(); - if(!value_stack.empty()) - throw runtime_error("too many values"); - - return value; -} - -void BooleanEvaluator::push_op(char op) -{ - if(last_was_op!=is_unary(op)) - throw runtime_error("syntax error at "+string(1, op)); - // TODO Disallow mixing of ! and =/^ - if(is_logic(op) && !var_stack.empty()) - value_stack.push_back(pop_value()); - - if(!is_unary(op)) - collapse(precedence(op)); - op_stack.push_back(op); - last_was_op = true; -} - -bool BooleanEvaluator::pop_value() -{ - if(!var_stack.empty()) - { - string var = var_stack.back(); - var_stack.pop_back(); - return func(var, 0); - } - else if(!value_stack.empty()) - { - bool value = value_stack.back(); - value_stack.pop_back(); - return value; - } - - throw runtime_error("value stack underflow"); -} - -void BooleanEvaluator::collapse(unsigned until) -{ - while(!op_stack.empty()) - { - char op = op_stack.back(); - if(precedence(op)