ExpressionContainer.hh 6.94 KB
#ifndef EXPRESSIONCONTAINER_HH_
#define EXPRESSIONCONTAINER_HH_

#include <cstdio>
#include <vector>
#include <boost/lexical_cast.hpp>

namespace AMDA {
namespace parser {

struct Operator {
	explicit Operator(std::string ihmSymbol, std::string kernelSymbol) : ihmSymbol(ihmSymbol), kernelSymbol(kernelSymbol) {};

	std::string ihmSymbol = "";
	std::string kernelSymbol = "";
};

namespace Expression{

typedef std::string var;

struct BinaryOperation;
struct UnaryOperation;
struct FunctionOperation;
struct PowerOperation;
struct ParameterDef;

typedef boost::variant<
	var,
	boost::recursive_wrapper<UnaryOperation>,
	boost::recursive_wrapper<BinaryOperation>,
	boost::recursive_wrapper<PowerOperation>,
	boost::recursive_wrapper<FunctionOperation>,
	boost::recursive_wrapper<ParameterDef>
> ExpressionContainer;

struct FunctionOperation
{
	explicit FunctionOperation(std::string func, const ExpressionContainer& arg1) : func(func) {
		args.push_back(arg1);
	}

	explicit FunctionOperation(std::string func, const ExpressionContainer& arg1, const ExpressionContainer& arg2) : func(func) {
		args.push_back(arg1);
		args.push_back(arg2);
	}

	explicit FunctionOperation(std::string func, const ExpressionContainer& arg1, const ExpressionContainer& arg2, const ExpressionContainer& arg3) : func(func) {
		args.push_back(arg1);
		args.push_back(arg2);
		args.push_back(arg3);
	}

	explicit FunctionOperation(std::string func, const ExpressionContainer& arg1, const ExpressionContainer& arg2, const ExpressionContainer& arg3, const ExpressionContainer& arg4) : func(func) {
		args.push_back(arg1);
		args.push_back(arg2);
		args.push_back(arg3);
		args.push_back(arg4);
	}

	std::string func;
	std::vector<ExpressionContainer> args;
};

struct ParameterDef
{
	enum ComponentType {
		CT_INDEX,
		CT_ALL,
		CT_RANGE_VALUES,
		CT_RANGE_INDEXES
	};

	struct Component {
		ComponentType type = ComponentType::CT_ALL;
		int    index = 0;
		float min   = 0.;
		float max   = 0.;
	};

	explicit ParameterDef(std::string param, const std::string& comp1, const std::string& comp2) : param(param) {
		components.push_back(parseComponent(comp1));
		components.push_back(parseComponent(comp2));
	}

	explicit ParameterDef(std::string param, const std::string& comp1) : param(param) {
		components.push_back(parseComponent(comp1));
	}

	explicit ParameterDef(std::string param) : param(param) {}

	Component parseComponent(const std::string& comp) {
		Component res;
		if (comp.compare("*") == 0) {
			res.type = ComponentType::CT_ALL;
		}
		else if (comp.find("range[") == 0) {
			if (std::sscanf((char*)comp.c_str(), "range[%f,%f]", &res.min, &res.max) == 2) {
				res.type = ComponentType::CT_RANGE_VALUES;
			}
			else {
				res.type = ComponentType::CT_ALL;
			}
		}
		else if (comp.find("indexes[") == 0) {
			int min = 0, max = 0;
			if (std::sscanf((char*)comp.c_str(), "indexes[%d,%d]", &min, &max) == 2) {
				res.type = ComponentType::CT_RANGE_INDEXES;
				res.min = min;
				res.max = max;
			}
			else {
				res.type = ComponentType::CT_ALL;
			}
		}
		else {
			try {
				res.index = boost::lexical_cast<int>(comp.c_str());
				res.type = ComponentType::CT_INDEX;
			} catch( boost::bad_lexical_cast const& ) {
				res.type = ComponentType::CT_ALL;
			}
		}

		return res;
	}

	std::string param;
	std::vector<Component> components;
};

struct UnaryOperation
{
	explicit UnaryOperation(Operator op, const ExpressionContainer& e) : op(op), e(e) {}
	Operator op;
	ExpressionContainer e;
};

struct BinaryOperation
{
	explicit BinaryOperation(const ExpressionContainer& l, Operator op, const ExpressionContainer& r) : l(l), op(op), r(r) { }
	ExpressionContainer l;
	Operator op;
	ExpressionContainer r;
};

struct PowerOperation
{
	explicit PowerOperation(const ExpressionContainer& l, const ExpressionContainer& r) : l(l), r(r) {}
	ExpressionContainer l;
	ExpressionContainer r;
};

struct NotOperation : UnaryOperation
{
	explicit NotOperation(const ExpressionContainer& e) : UnaryOperation(Operator("!","!"), e) {}
};

struct MinusSignOperation : UnaryOperation
{
	explicit MinusSignOperation(const ExpressionContainer& e) : UnaryOperation(Operator("-","-"), e) {}
};

struct PlusSignOperation : UnaryOperation
{
	explicit PlusSignOperation(const ExpressionContainer& e) : UnaryOperation(Operator("+","+"), e) {}
};

struct ConstantOperation : UnaryOperation
{
	explicit ConstantOperation(const ExpressionContainer& e) : UnaryOperation(Operator("@",""), e) {}
};

struct PowerTenOperation : BinaryOperation
{
	explicit PowerTenOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator("e","e"), r) { }
};

struct PowerTenDOperation : BinaryOperation
{
	explicit PowerTenDOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator("d","e"), r) { }
};

struct SumOperation : BinaryOperation
{
	explicit SumOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator("+","+"), r) { }
};

struct DifferenceOperation : BinaryOperation
{
	explicit DifferenceOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator("-","-"), r) { }
};

struct FactorOperation : BinaryOperation
{
	explicit FactorOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator("*","*"), r) { }
};

struct DivisionOperation : BinaryOperation
{
	explicit DivisionOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator("/","/"), r) { }
};

struct EqualOperation : BinaryOperation
{
	explicit EqualOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator("=","=="), r) { }
};

struct UnequalOperation : BinaryOperation
{
	explicit UnequalOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator("!=","!="), r) { }
};

struct GreaterOperation : BinaryOperation
{
	explicit GreaterOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator(">",">"), r) { }
};

struct GreaterOrEqualOperation : BinaryOperation
{
	explicit GreaterOrEqualOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator(">=",">="), r) { }
};

struct LowerOperation : BinaryOperation
{
	explicit LowerOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator("<","<"), r) { }
};

struct LowerOrEqualOperation : BinaryOperation
{
	explicit LowerOrEqualOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator("<=","<="), r) { }
};

struct AndOperation : BinaryOperation
{
	explicit AndOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator("&","&&"), r) { }
};

struct OrOperation : BinaryOperation
{
	explicit OrOperation(const ExpressionContainer& l, const ExpressionContainer& r) : BinaryOperation(l, Operator("|","||"), r) { }
};

} /* namespace Expression */

} /* namespace parser */
} /* namespace AMDA */

#endif