CGII/framework/include/libs/ppp_lib/expression_processor.h
2018-05-17 15:50:03 +02:00

84 lines
2.5 KiB
C++

#pragma once
#include <utility>
#include <vector>
#include <stack>
#include "variant.h"
#include "operators.h"
#include <cgv/utils/token.h>
using cgv::utils::token;
#include "lib_begin.h"
namespace cgv {
namespace media {
namespace text {
namespace ppp {
class ph_processor;
enum ExpressionPart { EP_VALUE, EP_OPERATOR, EP_OPEN, EP_FUNC, EP_CLOSE, EP_LIST_OPEN, EP_LIST_CLOSE, EP_LIST_ACCESS, EP_COMMA };
struct expression_token : public token
{
variant value;
OperatorType ot;
ExpressionPart ep;
expression_token(const token& tok, const variant& v) : token(tok), value(v), ep(EP_VALUE) {}
expression_token(const token& tok, OperatorType _ot) : token(tok), ot(_ot), ep(EP_OPERATOR) {}
expression_token(const token& tok, ExpressionPart _ep) : token(tok), ep(_ep) {}
};
class CGV_API expression_processor
{
protected:
bool debug_parse;
bool debug_evaluate;
typedef std::pair<unsigned int,unsigned int> expr_stack_entry;
void prepare();
bool compress_stack_validate(int priority, std::vector<expr_stack_entry>& expression_stack,
std::vector<ExpressionPart>& parenthesis_stack,
std::stack<variant>& value_stack, std::stack<OperatorType>& operator_stack);
bool compress_stack_evaluate(int priority, std::vector<expr_stack_entry>& expression_stack,
std::vector<ExpressionPart>& parenthesis_stack,
std::stack<variant>& value_stack, std::stack<OperatorType>& operator_stack);
std::vector<expression_token> expression_tokens;
unsigned int get_nr_comma_separated_expressions(std::vector<expr_stack_entry>& expression_stack,
std::vector<ExpressionPart>& parenthesis_stack,
std::stack<variant>& value_stack) const;
ExpressionPart find_last_parenthesis(std::vector<expr_stack_entry>& expression_stack,
std::vector<ExpressionPart>& parenthesis_stack) const;
mutable std::string last_error;
mutable token last_error_token;
public:
bool found_error;
bool issued_error;
expression_processor();
bool parse(const token& input_token);
void extract_begins(std::vector<unsigned>& begins, unsigned i0=0, unsigned ie=-1) const;
bool assign_func_decl(const std::vector<variant>& values) const;
bool is_func_decl() const;
int classify_call(unsigned i) const;
bool validate(bool allow_several_values = false);
bool evaluate(variant& result, ph_processor* ph_proc);
const std::string& get_last_error() const;
const token& get_last_error_token() const;
};
}
}
}
}
#include <cgv/config/lib_end.h>