|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzBase includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tgrammar.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tparser.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tunit.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "texpression.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace TSyntax;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// TExpression::Imp definition
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class TExpression::Imp
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
const Grammar *m_grammar; //!< (not owned) The expression's grammar
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParam *m_param; //!< (not owned) The expression's owner
|
|
Toshihiro Shimizu |
890ddd |
Calculator *m_calculator; //!< (owned) Expression calculator object
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::string m_text; //!< Text content
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::string m_error; //!< Description of an error in the expression's text
|
|
Toshihiro Shimizu |
890ddd |
std::pair<int, int=""> m_errorPos; //!< Position of the error in the expression's text</int,>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool m_isValid, //!< Whether the expression is valid
|
|
Toshihiro Shimizu |
890ddd |
m_hasBeenParsed; //!< Whether the expression has already been parsed
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
Imp() : m_grammar(0), m_param(0), m_calculator(0), m_errorPos(0, -1), m_isValid(false), m_hasBeenParsed(true) {}
|
|
Toshihiro Shimizu |
890ddd |
~Imp() { delete m_calculator; }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// TExpression implementation
|
|
Toshihiro Shimizu |
890ddd |
//**********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TExpression::TExpression()
|
|
Toshihiro Shimizu |
890ddd |
: m_imp(new Imp())
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TExpression::~TExpression()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TExpression::TExpression(const TExpression &src)
|
|
Toshihiro Shimizu |
890ddd |
: m_imp(new Imp())
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_grammar = src.m_imp->m_grammar;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_param = src.m_imp->m_param;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_text = src.m_imp->m_text;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_calculator = 0;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isValid = src.m_imp->m_isValid;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_error = src.m_imp->m_error;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_errorPos = src.m_imp->m_errorPos;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_hasBeenParsed = false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TExpression &TExpression::operator=(TExpression copy)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
std::swap(copy.m_imp, m_imp);
|
|
Toshihiro Shimizu |
890ddd |
return *this;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TExpression::setGrammar(const TSyntax::Grammar *grammar)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_grammar = grammar;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_hasBeenParsed = false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const TSyntax::Grammar *TExpression::getGrammar() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_grammar;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TExpression::setText(string text)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_text != text) {
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_text = text;
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp->m_calculator;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_calculator = 0;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isValid = false;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_hasBeenParsed = false;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_error = "";
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_errorPos = std::make_pair(0, -1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
string TExpression::getText() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_text;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// note: unit is used by the CycleNode node only
|
|
Toshihiro Shimizu |
890ddd |
TSyntax::Calculator *TExpression::getCalculator()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->m_hasBeenParsed)
|
|
Toshihiro Shimizu |
890ddd |
parse();
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_isValid && m_imp->m_calculator)
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_calculator;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TExpression::isValid()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->m_hasBeenParsed)
|
|
Toshihiro Shimizu |
890ddd |
parse();
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_isValid;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
string TExpression::getError() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_error;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
std::pair<int, int=""> TExpression::getErrorPos() const</int,>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_errorPos;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TExpression::accept(TSyntax::CalculatorNodeVisitor &visitor)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->m_hasBeenParsed)
|
|
Toshihiro Shimizu |
890ddd |
parse();
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_isValid && m_imp->m_calculator)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_calculator->accept(visitor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TExpression::parse()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
delete m_imp->m_calculator;
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_calculator = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_errorPos = std::make_pair(0, -1);
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_error = std::string();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->m_grammar) {
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_error = "No grammar defined";
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isValid = false;
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
Parser parser(m_imp->m_grammar);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_calculator = parser.parse(m_imp->m_text);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_calculator)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_calculator->setOwnerParameter(m_imp->m_param);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_isValid = parser.isValid();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_imp->m_isValid) {
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_error = parser.getError();
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_errorPos = parser.getErrorPos();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_hasBeenParsed = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TExpression::setOwnerParameter(TDoubleParam *param)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_param = param;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_imp->m_calculator)
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_calculator->setOwnerParameter(param);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParam *TExpression::getOwnerParameter() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return m_imp->m_param;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool TExpression::isCycling() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// TODO: this is a quick&dirty implementation to be replaced with a more "semantic" one
|
|
Toshihiro Shimizu |
890ddd |
return getText().find("cycle") != string::npos;
|
|
Toshihiro Shimizu |
890ddd |
}
|